2010-12-18 88 views
-1

我想讓線程在我的OpenGL程序中運行。現在我正在製作一個原型以呈現給我的小組。從本質上講,我必須使用Win32 API中的:: PeekMessage()函數渲染大片地形,產生波濤洶涌的結果。因此,我試圖獲得一個渲染線程來運行,將不斷呈現,而主線程處理所有的輸入。我有線程正確啓動,但不知何故它過早死亡。我無法弄清楚我的代碼在造成什麼。我的代碼基數很小,所以對於有這方面工作經驗的人來說,我認爲它不應該很難診斷。整個代碼由3個源文件組成,不超過100行,可以在這裏找到。Win32 API渲染線程和OpenGL

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

這是遍佈互聯網的碎片。無論如何,我會將我的代碼留在我的網站上,以解決遇到這些問題的其他人。

我的代碼有兩個錯誤。在我將它傳遞給WinMaker之前,我必須實際創建一個新的ControllGL。一旦我這樣做,它解決了我所有的問題。在我的問題解決之後,我必須瞭解每個線程只能有一個渲染上下文。因此,我需要將這兩行添加到我的線程函數中,因爲它是從另一個線程調用的。

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

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

一旦我做到了它的所有工作。這將使更多,因爲一旦我得到我的評論代碼到上面的網址。

0

ControllerGL的實例在從功能initializeApp返回後超出了範圍,這使得對其成員數據的任何訪問都無效。如果它不會崩潰,那是純粹的運氣。使ControllerGL成爲您的WinMaker類的成員,並保持它的活力。

+0

WinMaker.h的第23行包含一個ControllerGL * graphixGL,它在CreateWindowEx()中用作USERDATA。我也嘗試將main.cpp中的ControllerGL cntrl移動到全局範圍。每當我嘗試在我的線程函數中使用成員變量時,我仍然崩潰。不過,我同意你的看法,它必須超出範圍,這是完美的,因爲它爲什麼崩潰,或爲什麼循環停止。我提出了你的建議改變,但它仍然是一個不行。讓我發佈我的更新代碼到http://99.116.251.16/code/WIN32/Vers2/。給我1分鐘左右就能搞定。 – 2010-12-18 23:36:09

0

我不認爲這是它,但

(this->wndHeight) 

可能是0,如果你調整窗口的大小。一個常見的safegaurd是添加1,如果0

你也有

glEnable(GL_DEPTH_TEST); 
在已經initialzed在上面的線是那麼您的運行循環

也許你無意中調用了一個拷貝構造函數並且有一個淺拷貝?

+0

你好Enabren, 所以我修改了我的代碼,現在循環已經崩潰了,我需要在將main.cpp傳遞給WinMaker.cpp之前實例化ctrl。更新後的版本可以在http://99.116.251.16/code/WIN32/Vers2/找到。現在我被卡住了,因爲某些原因,我無法讓OpenGL函數畫到窗口。我有一個以前的工作版本,可以在http://99.116.251.16/code/WIN32/Vers1/找到。在這裏,我有最終結果,只是當我將頂點的數量擴展到256X256以上時,它纔會變慢。無論如何,如果有人可以幫助我理解... – 2010-12-19 01:15:32

+0

你是如何結婚的Windows GDI? GLUT是平臺獨立的,給我更少的困擾。但是在GLUT中重新實現可能工作太多。 偏離主題,標籤是不好的。作爲個人喜好,我建議將軟標籤設置爲4個空格以防止「標籤損壞」 – EnabrenTane 2010-12-19 01:22:35