2009-07-24 126 views
2

我試圖在OpenGL SuperBible中給出的描述後,在Delphi/OpenGL中實現相機模型。相機有一個位置,一個向前的向量和一個向上的向量。翻譯相機似乎可以正常工作,但是當我嘗試根據正向矢量旋轉相機時,我看不到我的物體。OpenGL:相機轉換幫助

function TCamera.GetCameraOrientation: TMatrix4f; 
var 
    x, z: T3DVector; 
begin 
    z := T3DVector.Create(-FForward.X, -FForward.y, -FForward.z); 
    x := T3DVector.Cross(z, FUp); 

    result[0, 0] := x.X; 
    result[1, 0] := x.Y; 
    result[2, 0] := x.Z; 
    result[3, 0] := 0; 

    result[0, 1] := FUp.X; 
    result[1, 1] := FUp.Y; 
    result[2, 1] := FUp.Z; 
    result[3, 1] := 0; 

    result[0, 2] := z.x; 
    result[1, 2] := z.y; 
    result[2, 2] := z.z; 
    result[3, 2] := 0; 

    result[0, 3] := 0; 
    result[1, 3] := 0; 
    result[2, 3] := 0; 
    result[3, 3] := 1; 
end; 

procedure TCamera.ApplyTransformation; 
var 
    cameraOrient: TMatrix4f; 
    a, b, c: TMatrix4f; 
begin 
    cameraOrient := getcameraOrientation; 
    glMultMatrixf(@cameraOrient); 
    glTranslatef(-FPosition.x, -FPosition.y, -FPosition.z); 
end; 

鑑於位置(0,0,-15),前向向量(0 0 1)和向上矢量(0 1 0),I有望獲得從getCameraOrientation-方法的同一性矩陣,但相反,我得到

(1, 0, 0, 0) 
(0, 1, 0, 0) 
(0, 0, -1, 0) 
(0, 0, 0, 1) 

如果我改變正向矢量(0 0 -1)我得到以下矩陣:

(-1, 0, 0, 0) 
(0, 1, 0, 0) 
(0, 0, 1, 0) 
(0, 0, 0, 1) 

調用glMultMatrix()和glTranslate(),glGet(後)給了我下面的GL_MODELVIEW_MATRIX:

(1, 0, 0, 0) 
(0, 1, 0, 0) 
(0, 0, -1, 0) 
(0, 0, 15, 1) 

我本來期望的15是在第4列,第3行,不列3,第4行

任何人都可以看到我得到這個錯了嗎?

編輯:從OpenGL的OpenGL超級原始代碼:

inline void GetCameraOrientation(M3DMatrix44f m) 
     { 
     M3DVector3f x, z; 

     // Make rotation matrix 
     // Z vector is reversed 
     z[0] = -vForward[0]; 
     z[1] = -vForward[1]; 
     z[2] = -vForward[2]; 

     // X vector = Y cross Z 
     m3dCrossProduct(x, vUp, z); 

     // Matrix has no translation information and is 
     // transposed.... (rows instead of columns) 
     #define M(row,col) m[col*4+row] 
      M(0, 0) = x[0]; 
      M(0, 1) = x[1]; 
      M(0, 2) = x[2]; 
      M(0, 3) = 0.0; 
      M(1, 0) = vUp[0]; 
      M(1, 1) = vUp[1]; 
      M(1, 2) = vUp[2]; 
      M(1, 3) = 0.0; 
      M(2, 0) = z[0]; 
      M(2, 1) = z[1]; 
      M(2, 2) = z[2]; 
      M(2, 3) = 0.0; 
      M(3, 0) = 0.0; 
      M(3, 1) = 0.0; 
      M(3, 2) = 0.0; 
      M(3, 3) = 1.0; 
     #undef M 
     } 

    inline void ApplyCameraTransform(bool bRotOnly = false)  
     { 
     M3DMatrix44f m; 

     GetCameraOrientation(m); 

     // Camera Transform 
     glMultMatrixf(m); 

     // If Rotation only, then do not do the translation 
     if(!bRotOnly) 
      glTranslatef(-vOrigin[0], -vOrigin[1], -vOrigin[2]); 
     } 

回答

2

鑑於你getcameraOrientation的代碼所產生的矩陣是很明顯的:轉發=(0,0,1)得到Z =(0,0, - 1),它對應於矩陣的第3行。 z =(0,0,-1)和FUp =(0,1,0)的叉積導致x =(1,0,0),這對應於矩陣的第一行。第二行只是FUp的一個副本,第四行只是固定的。

我其實不明白你想達到什麼,但是當你旋轉攝像頭時,你清楚地看不到你的物體。在現實世界中,如果你看到一個點並轉過頭來 - 這是一回事。你是否試圖扭轉翻譯和旋轉的順序?

+0

他應該能夠圍繞向前的矢量旋轉而不會忽視他的對象。 – Nosredna 2009-07-24 16:02:07

1

單位矩陣

我不知道爲什麼OpenGL超級建議使用(-FForward.X,-FForward.y,-FForward.z)來創建ž載體。如果你拿出減號,那麼當你的向量爲(0,0,1)時,你將得到你期望的單位矩陣。如果你想保留減號,並且你想要一個正向向量(0,0,-1)產生一個單位矩陣,那麼你需要將交叉乘積從十字(z,FUp)改變爲交叉(FUp,z),因爲OpenGL使用右手座標系。請參閱Cross product

(1, 0, 0, x) 
(0, 1, 0, y) 
(0, 0, 1, z) 
(0, 0, 0, 1) 

不過,請注意OpenGL的存儲其矩陣順序:

在錯誤的地方

我同意你的看法,我會期待一個平移矩陣看起來像這樣15不是順序,所以當你glGet模型視圖矩陣它會按此順序出來:

(m[0], m[4], m[8], m[12]) 
(m[1], m[5], m[9], m[13]) 
(m[2], m[6], m[10], m[14]) 
(m[3], m[7], m[11], m[15]) 

如果您認爲它是按行排序的,那麼這可能是導致混淆的原因。