2010-12-06 51 views
1

我在OpenGL燈光方面遇到了問題。我的問題是這樣的:當物體旋轉0度時,照明效果很好 - 否則照明會起作用,但會隨物體一起旋轉,而不是固定在場景中。每個型號的本地自動更新openGL燈光

聽起來很簡單吧? OpenGL FAQ對此有一些簡單的建議:傳遞給glLightfv的座標(GL_LIGHT0,GL_POSITION ...)乘以當前的MODELVIEW矩陣。所以我必須在錯誤的地方調用它......除非我不是。我已經將MODELVIEW矩陣複製到一個變量中進行調試,並且不管我的對象如何旋轉,它都保持不變。所以它必須是別的東西,但是我對此感到不知所措。

我使用glDrawArrays繪製模型,並使用glMatrixMult在由旋轉四元數和平移構建的矩陣中定位我的模型。所有這些都發生在glPushMatrix/glPopMatrix中,所以不應該對燈光有任何副作用。

一個砍下我的渲染過程中的版本是這樣的:

//Setup our camera 
glMatrixMode(GL_MODELVIEW);    
glLoadIdentity(); 
cameraMatrix = translate(Vector3D(Pos.mX,Pos.mY,Pos.mZ)) * camRot.QuatToMatrix(); 
glMultMatrixf((GLfloat*)&cameraMatrix); 

//Position the light now 
glEnable(GL_LIGHTING); 
glEnable(GL_LIGHT0); 
GLfloat lp[4] = {lightPos.mX, lightPos.mY, lightPos.mZ, 1.0f}; 
glLightfv(GL_LIGHT0, GL_POSITION,(GLfloat*) lp); 

//Loop, doing this for each model: (mRot, mPos, and mi are model member variables) 
matrix = translate(Vector3D(mPos.mX,mPos.mY,mPos.mZ)) * mRot.QuatToMatrix(); 
glPushMatrix(); 
glMultMatrixf((GLfloat*)&matrix); 
glBindBuffer(GL_ARRAY_BUFFER, mi->mVertexBufHandle); //Bind the model VBO. 
glDrawArrays(GL_TRIANGLES, 0, mi->verts); //Draw the object 
glPopMatrix(); 

我以爲法線可能會搞砸了,但是當我使出來,他們看起來很好。還有什麼可能會影響OpenGL照明?常見問題解答中提到:

如果你的光源是 燈具的一部分,你可能還需要 指定造型變換,所以 光位置是在同一位置 的周圍固定幾何形狀。

我認爲這意味着你需要將光線轉換成場景,這是一種不費吹灰之力......但這是否意味着別的什麼?

+0

這真的很奇怪。使用glPushMatrix();當我將燈光位置設置爲0,0,0時,燈光甚至旋轉。 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glLightfv(GL_LIGHT0,GL_POSITION,Vector4D(0,0,0,1)); glPopMatrix(); – 2010-12-06 19:04:58

+0

我很確定我在渲染對象時做錯了什麼,最後一步是給對象一個局部旋轉,但看起來這個旋轉也適用於光源。我的第一個想法是乘以新的旋轉燈的位置,但我要麼做錯了或它沒有幫助... – 2010-12-07 02:35:35

+0

你怎麼知道燈光在旋轉?嘗試在其位置繪製GL_POINT,並嘗試對glDrawArrays進行註釋(以避免混淆);即使cameraMatrix被固定,點是否移動? – UncleZeiv 2010-12-07 12:16:13

回答

1

這是一段時間後,但我終於弄清楚了這個問題。問題我認爲我曾經是光的位置翻譯錯了。想象一下:光線位於0,0,0,但是我翻譯並旋轉了網格。如果情況確實如此,我必須按照其他答案中的建議做,並確保我將我的glLightfv電話放在正確的位置。

實際問題原來是更簡單,但更陰險。事實證明,我沒有正確設置glNormalPointer,所以它被送入垃圾數據。在調試時,我會渲染法線來檢查它們是否正確,但是當我這樣做時,我會根據我計算的位置手動繪製它們。對未來調試器的建議:在繪製調試信息的正常射線時,確保您提供調試功能/相同的數據/ openGL獲取。在我的情況下,這意味着將我的正常光線繪製函數的glVertexPointer指向與模型的glNormalPointer相同的位置。

0

基本上,OpenGL燈的行爲就像一個頂點。所以在你的代碼中,它被cameraMatrix轉換,而你的網格被轉換爲cameraMatrix * matrix。現在,它看起來像cameraMatrixmatrix都包含mrot.QuatToMatrix(),即:有一個單一的旋轉矩陣,並且光線被旋轉一次,而對象旋轉兩次。它看起來並不正確,除非你的實際代碼不同;您爲每個網格使用的mRot矩陣應該是它自己的,例如, mRot[meshIndex]

1

這可能是次要的,但在這一行:

glLightfv(GL_LIGHT0, GL_POSITION,(GLfloat*) &lp); 

刪除&(地址運算符)。 lp將已經給你數組地址。