Win32 API Renderer Thread и OpenGL - PullRequest
       1

Win32 API Renderer Thread и OpenGL

0 голосов
/ 19 декабря 2010

Я пытаюсь запустить потоки в моей программе OpenGL. Сейчас я просто работаю над прототипом, чтобы представить его моей группе. По сути, мне нужно визуализировать большой участок местности, используя функцию :: PeekMessage () из Win32 API, которая дает нестабильные результаты. Таким образом, я пытаюсь запустить поток рендеринга, который будет непрерывно рендериться, в то время как основной поток обрабатывает весь ввод. У меня поток запускается правильно, но как-то преждевременно отмирает. Я не могу понять, что в моем коде вызывает это. У меня небольшая база кода, поэтому для тех, кто имеет большой опыт работы с этим материалом, я не думаю, что его будет сложно диагностировать. Весь код состоит из 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);
}

Каким-то образом в верхней части функции мой флаг цикла равен true, но каким-то образом к тому времени, когда он попадает в цикл, он оценивается как false. Единственная причина, по которой он должен сломаться, заключается в том, что основной поток, который его породил, завершился. Однако, если вы скомпилируете программу, вы увидите, что главное окно все еще живо.

Любая помощь по этому вопросу будет принята с благодарностью.

Ответы [ 3 ]

0 голосов
/ 19 декабря 2010

Не думаю, что это так, но

(this->wndHeight)

Может быть 0, если вы измените размер окна. Обычное безопасное выражение - добавить 1, если 0

у вас также есть

glEnable(GL_DEPTH_TEST);

в вашем рабочем цикле, который уже инициализирован, как указано выше в строках.

Возможно, вы случайно вызвали конструктор копирования и получили мелкую копию?

0 голосов
/ 19 декабря 2010

Это по всему интернету по частям. В любом случае, я оставлю свой код на своем сайте для всех, кто столкнется с этими проблемами.

Были две вещи не так с моим кодом. Я должен был создать новый ControllGL, прежде чем передать его WinMaker. Как только я это сделал, это решило все мои проблемы. После того, как мои проблемы были решены, я должен был узнать, что у вас может быть только один контекст рендеринга на поток. Поэтому мне нужно было добавить эти две строки в мою функцию потока, так как она была вызвана из другого потока.

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

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

Как только я это сделал, все заработало. Это сделает больше, так как, как только я получу свой закомментированный код в URL выше.

0 голосов
/ 19 декабря 2010

Ваш экземпляр ControllerGL выходит из области видимости после возврата из функции initializeApp, которая делает любой доступ к его данным члена недействительным.Это чистая удача, если она не рухнет.Сделайте ControllerGL членом вашего WinMaker класса, который должен поддерживать его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...