我正在尝试在我的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。它应该中断的唯一原因是因为产生它的主线程终止了。但是,如果编译程序,您将看到主窗口仍然存在。
对此的任何帮助将不胜感激。
答案 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中,这将会产生更多。