开发者

Win32 API Renderer Thread and OpenGL

I am trying to get threads running in my OpenGL program. Right now I am just working on a prototype to present to my group. Essentially, I have to render a large piece of terrain, using the ::PeekMessage() function from the Win32 API, is producing choppy results. Thus I am trying to get a render thread to run that will continuously render, while the main thread handles all the input. I have the thread launch correctly, but somehow it is dieing off prematurely. I can't figure out what in my code is causing it. My code base is small, so for anyone that has a lot of experience working with this stuff, I don't think it should be to hard to diagnose. The entire code consists of 3 source files, no more than 100 lines long, and can be found at.

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

Specifically, my issues arises in ContrllerGL.cpp line numbers 21 - 76. That code is as follows:

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);
}

Somehow at the top of the function my loop flag is true, but somehow by the time it gets to the loop it evaluates to false. The only reason why it should break is because the main thread that spawned it terminated. However, if you compile the program, you wi开发者_JAVA技巧ll see the main window is still alive.

Any help on this would be greatly appreciated.


Your instance of ControllerGL goes out of scope after returning from the function initializeApp, which makes any access to it's member data invalid. It's pure luck if it doesn't crash. Make the ControllerGL a member of your WinMaker class, that should keep it alive.


I dont think this is it, but

(this->wndHeight)

May be 0 if you resize the window. A common safegaurd is to add 1 if 0

you also have

glEnable(GL_DEPTH_TEST);

in your running loop which is already initialzed to be so in the above lines.

Perhaps you inadvertently called a copy constructor and have a shallow copy?


This is all over the internet in pieces. Anyways, I will leave my code up at my site for anyone else who runs into these problems.

There were were two things wrong with my code. One I had to actually create a new ControllGL before I passed it to WinMaker. Once I did that it resolved all my issues. After my issues were resolved with that I had to learn that you can only have one rendering context per thread. Thus I needed to add these two lines to my thread function since it was called from the other thread.

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

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

Once i did that it all worked. This will make more since once I get my commented code to the url above.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜