Win32 API渲染器线程和OpenGL

时间:2010-12-18 22:10:01

标签: c++ opengl

我正在尝试在我的OpenGL程序中运行线程。现在我正在制作一个原型来呈现给我的小组。基本上,我必须使用Win32 API中的:: PeekMessage()函数渲染大片地形,从而产生不稳定的结果。因此,我试图让一个渲染线程运行,将持续渲染,而主线程处理所有输入。我正确地启动了线程,但不知怎的,它过早地消失了。我无法弄清楚我的代码中是什么导致它。我的代码库很小,所以对于那些有很多使用这些东西的经验的人来说,我认为不应该很难诊断。整个代码由3个源文件组成,长度不超过100行,可在以下位置找到。

http://99.116.251.16/code/WIN32/Vers2/

具体来说,我的问题出现在ContrllerGL.cpp第21-76行。该代码如下:

void ControllerGL::runThread(){



/*
  * BEFORE RESIZE EVEN MAKE SURE TO GET DEMINSIONS OF WINDOW
  */

 RECT clientArea;
 ::GetClientRect(this->hwnd, &clientArea);
 this->wndWidth = clientArea.right - clientArea.left;
 this->wndHeight = clientArea.bottom - clientArea.top;
 char out[256];
 sprintf(out, "1) %d X %d --> %d", this->wndWidth, this->wndHeight, this->loopFlag);
 MessageBox (NULL, TEXT(out), TEXT("Message Box"), 0);



 /* 
  * BEFORE WE ENTER MAIN RENDERING LOOP SET OPENGL
  * FLAGS AND CLEAR ALL BUFFERS
  */
 glEnable(GL_DEPTH_TEST);
 glClearDepth(1.0);
 glClearColor(0.0, 0.0, 0.0, 1.0);                      
 /*
  * END OF SET OPENGL FLAGS AND CLEAR ALL BUFFERS 
  */

 /* 
  * Main Rendering Loop
  */

 //*/
 while(this->loopFlag){
  //*/
  ::Sleep(50);
  if(this->resizeFlag > 0){
   this->resizeFlag = 0;
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();  
   float aspectRatio = (float)((this->wndWidth)/(this->wndHeight));
   gluPerspective(45.0f, aspectRatio, 1.0f, 100000.0);
   glViewport(0, 0, this->wndWidth, this->wndHeight);
  }
  char out[256];
  sprintf(out, "2) %d X %d --> %d", this->wndWidth, this->wndHeight, this->loopFlag);
  MessageBox (NULL, TEXT(out), TEXT("Message Box"), 0);
  glEnable(GL_DEPTH_TEST);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity(); 
  gluLookAt(0.0f, 0.0f, 10.0f, 0.0f, 0.0f, -10.0f, 0.0f, 1.0f, 0.0f);         
  glBegin(GL_TRIANGLES);      
   glColor3f(1.0, 0.0, 0.0);
   glVertex3f( 0.0f, 5.0f, 0.0f);
   glColor3f(0.0, 1.0, 0.0);     
   glVertex3f(-5.0f,-5.0f, 0.0f);
   glColor3f(0.0, 0.0, 1.0);     
   glVertex3f( 5.0f,-5.0f, 0.0f);     
  glEnd();
  ::SwapBuffers(this->hdc);                     
  //*/
 }
 //*/
 /* 
  * END OF MAIN RENDERING LOOP
  */
 ::wglMakeCurrent(NULL, NULL);
 ::CloseHandle(this->threadHandle);
}

不知何故,在函数的顶部,我的循环标志为真,但不知何故,当它到达循环时,它的计算结果为false。它应该中断的唯一原因是因为产生它的主线程终止了。但是,如果编译程序,您将看到主窗口仍然存在。

对此的任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:0)

ControllerGL函数返回后,initializeApp的实例超出范围,这使得对其成员数据的任何访问都无效。如果没有崩溃,这是纯粹的运气。让ControllerGL成为WinMaker类的成员,使其保持活力。

答案 1 :(得分:0)

我不认为这是它,但是

(this->wndHeight)

如果您调整窗口大小,则可能为0。一个常见的safegaurd是添加1,如果0

你也有

glEnable(GL_DEPTH_TEST);

在你的运行循环中已经在上面的行中初始化了。

也许您无意中调用了复制构造函数并且有一个浅表副本?

答案 2 :(得分:0)

这是整个互联网的碎片。无论如何,我会把我的代码留在我的网站上,供其他遇到这些问题的人使用。

我的代码有两个问题。在将其传递给WinMaker之前,我必须实际创建一个新的ControllGL。一旦我这样做,它解决了我的所有问题。在解决了我的问题后,我必须知道每个线程只能有一个渲染上下文。因此,我需要将这两行添加到我的线程函数中,因为它是从另一个线程调用的。

this->hglrc = ::wglCreateContext(this->hdc);

::wglMakeCurrent(this->hdc, this->hglrc);

一旦我这样做,一切都奏效了。一旦我将注释代码添加到上面的URL中,这将会产生更多。