2013-06-03 2 views
1

"C# Game Programming For Serious Game Creation"의 예제를 통해 이상한 동작을보고 있습니다. 뷰포트와 직교 투영을 설정 한 다음 폭이 50 픽셀 인 삼각형을 그려 봅니다. 처음에는 삼각형의 작은 부분 만 보았지만 창이 크기를 조정하면 (예 : 최대화 후 복원) 삼각형이 갑자기 올바른 크기로 표시됩니다. 여기 크기가 조정될 때까지 OpenGL 뷰포트 설정이 인식되지 않습니다.

문제를 재현하는 간단한 예입니다

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 
using Tao.OpenGl; 

namespace SimpleExample 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
      _openGLControl.InitializeContexts(); 
     } 

     protected override void OnClientSizeChanged(EventArgs e) 
     { 
      base.OnClientSizeChanged(e); 

      int width = ClientSize.Width; 
      int height = ClientSize.Height; 
      double halfWidth = (double)width/2; 
      double halfHeight = (double)height/2; 

      Gl.glViewport(0, 0, width, height); 
      Gl.glMatrixMode(Gl.GL_PROJECTION); 
      Gl.glLoadIdentity(); 
      Gl.glOrtho(-halfWidth, halfWidth, -halfHeight, halfHeight, -100, 100); 
      Gl.glMatrixMode(Gl.GL_MODELVIEW); 
      Gl.glLoadIdentity(); 
     } 

     private void _openGLControl_Paint(object sender, PaintEventArgs e) 
     { 
      Gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
      Gl.glClear(Gl.GL_COLOR_BUFFER_BIT); 

      Gl.glBegin(Gl.GL_TRIANGLE_STRIP); 
      { 
       Gl.glColor4d(1.0, 0.0, 0.0, 0.5); 
       Gl.glVertex3d(-50, 0, 0); 
       Gl.glColor3d(0.0, 1.0, 0.0); 
       Gl.glVertex3d(50, 0, 0); 
       Gl.glColor3d(0.0, 0.0, 1.0); 
       Gl.glVertex3d(0, 50, 0); 

      } 
      Gl.glEnd(); 
      Gl.glFinish(); 
     } 
    } 
} 

OnClientSizeChanged 이벤트가 삼각형이 그려지기 전에 프로그램이 시작되지만 뷰포트/오르 때까지 아무것도 변경하지 않는 것 때 트리거가 나올까요 창 크기를 조정합니다.

OpenTk 라이브러리를 사용하고 Tao.OpenGL을 (를) 볼 수 있습니다. Dock을 Fill으로 설정 한 폼에 SimpleOpenGlControl을 사용하고 있습니다. Windows 7에서 VS2012를 실행합니다. 가능한 한 책 예제에 집중하고 glut 또는 추가 라이브러리를 사용하지 않습니다. 아무도 내가 잘못하고있는 것을 지적 할 수 있습니까?

+0

'glBegin'과'glEnd'는 2008 년 이후로 사용이 중단되었습니다. 'loadIdentity'와 동일합니다. 당신이 그 책의 제목까지 살기를 원한다면, 더 좋은 책을 찾아야합니다. – GraphicsMuncher

+0

더 좋은 책에 대한 제안이 있으십니까? 내 목표는 C#에서 2 차원 및 3 차원 그래픽을 프로그래밍 할 수있게하는 것입니다. –

답변

2

OpenGL보기의 측면을 변경하려면 장면을 완전히 다시 그려야합니다. 일반적인 OpenGL 렌더링에는 오버레이 (HUD, 주석 등)가 포함되므로 뷰포트 및 프로젝션 매트릭스를 도면과 별도로 설정하는 것은 의미가 없습니다. 따라서 그리기 루틴에서 glViewport 및 프로젝션 행렬 설정을 수행해야합니다.

윈도우 크기 또는 다른보기 측면의 변경 사항은 어쨌든 전체 다시 그리기를 트리거해야하고 그리기 루틴의 뷰포트 및 프로젝션 설정이 추가 고려하지 않고 처리해야합니다.

+0

OnClientSizeChanged 함수에서 뷰포트 항목을 페인트 기능의 시작 부분으로 이동하면 트릭이 수행됩니다. 감사! –

2

내 생각에 InitializeComponent(); 중에 OnClientSizeChanged이 호출되어 _openGLControl.InitializeContexts();이 아직 호출되지 않았으며 뷰포트에 대한 변경 사항이 사용자 컨트롤에 적용되지 않습니다. 그래서 그것을 고치기 위해 컨트롤의 컨텍스트를 초기화 한 후에 뷰포트를 설정합니다.

+0

당신은 정확하게 맞습니다. 나는 그걸 확인하려고 생각하지 않았지만, 그 일이 일어나고 있습니다. –

관련 문제