2011-05-06 231 views

回答

24

首先,一些背景。在3D圖形,你需要擔心的幾個向量空間:

  • 模型空間 - 這是通常的座標你指定的OpenGL
  • 世界空間 - 座標相對於世界上一些中心點指定。
  • 視圖空間 - 相對於相機指定座標
  • 投影空間 - 屏幕上的所有內容適用於每個維度的間隔[-1, +1]

座標被指定爲均勻,所以每個矢量都有組件(x, y, z, w),其中w是比例因子。您可以使用(x/w, y/w, z/w)獲得三維座標。縮放因子對於某些轉換(比如透視投影)來說是必需的,而這對於非均勻座標是不可能的。

需要4x4矩陣來將座標從一個向量空間轉換到另一個向量空間。你可以有三種不同的矩陣:

  • 模型矩陣(模型世界)
  • 查看矩陣(世界查看)
  • 投影矩陣(視圖投影空間)

你會項目座標C在屏幕上使用公式:

C' = P * V * M * C 

OpenGL實習生盟友維護兩個矩陣:modelview(模型和視圖相乘在一起)和投影。還有一個我們不擔心的紋理矩陣。當您撥打glMatrixMode時,您正在切換這些矩陣。用glLoadIdentity替換當前矩陣與單位矩陣。使用glTranslatefglRotatefgluProjection等函數對當前矩陣應用變換。這些函數中的每一個都創建了一個4x4矩陣,實現了特定的變換,然後將當前矩陣乘以它。您可以看到OpenGL 2.1 reference pages中的轉換矩陣。


現在爲實際的答案。您需要爲場景中的每個對象維護一個4x4模型矩陣。模型矩陣將包含將模型座標轉換爲世界座標所需的所有轉換。舉例來說,每次調用glTranslate時候,你會更新你的模型矩陣:

T = [ 1 0 0 x ] 
    [ 0 1 0 y ] 
    [ 0 0 1 z ] 
    [ 0 0 0 1 ] 
M' = M * T 

然後你可以用你的模型矩陣得到座標轉換成世界空間(確保它們是齊次座標第一;剛剛成立w = 1,如果他們不是):

V' = V * M 

由於要維持這些並行轉換,你實際上並不需要再維持了OpenGL模型視圖矩陣。您可以將您的模型矩陣作爲統一傳遞給着色器。您可以用類似的方式維護自己的視圖和投影矩陣。這在最新版本的OpenGL中是必需的;所有的矩陣處理函數都被棄用。

+1

我該如何維護我自己的模型矩陣? – 2011-05-06 17:15:55

+0

@Shazad,增加了一些背景信息和更詳細的解釋。希望有所幫助。 – 2011-05-06 17:48:11

+0

@Jay:首先你說'C'= P * V * M * C',然而,在你說'V'= M * V'的結尾。我有點困惑,因爲一旦它是'V * M'並且一次'M * V'。矩陣乘法不可交換,所以'A * B!= B * A'。難道你的答案中的任何一個順序都是錯誤的?也許這也是我的數學錯誤,但在這種情況下,請隨時糾正我。 – Mecki 2012-05-21 18:11:30

4

您可以使用虛擬攝像機視圖矩陣(V-1)倍的對象模型視圖矩陣(V * M)來獲得世界座標的倒數的產品。

你只是gluLookAt()函數使用後獲得五:

glGetFloatv(GL_MODELVIEW_MATRIX,camViewMatrix)

然後反矩陣和存儲,(用於乘後面的代碼中)。

你在哪裏,你要繪製對象點獲得V *男,剛過所有的glTranslatef(),glRotatef()和glScale()使用相同的GL功能命令:

glGetFloatv(GL_MODELVIEW_MATRIX,objectsModelVie wMatrix);

V-1 *(V * 中號)== 中號

然後倍數的兩個矩陣,生成的基質中包含的位置,M12 = X,M13 = y和M14 = Z

更多細節在與C語言代碼: https://sourceforge.net/p/openantz/wiki/Local_to_World_Coordinates/

相關問題