我正在尝试在OpenGL SuperBible中给出的描述之后在Delphi / 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),我期望从getCameraOrientation方法获得一个单位矩阵,但我得到< / p>
(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 SuperBible的原始代码:
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]);
}
答案 0 :(得分:2)
鉴于你的getcameraOrientation代码,得到的矩阵非常明显:forward =(0,0,1)产生z =(0,0,-1),它对应于矩阵的第3行。 z =(0,0,-1)和FUp =(0,1,0)的叉积导致x =(1,0,0),其对应于矩阵的第一行。第二行只是FUp的副本,第四行刚刚修复。
我实际上并不明白你想要达到的目标,但是当你旋转相机时,你会清楚地看到你的物体。在现实世界中,如果你看一点并转过头 - 这是同样的事情。您是否试图颠倒翻译和轮换的顺序?
答案 1 :(得分:1)
身份矩阵
我不确定为什么SuperBible建议使用(-FForward.X,-FForward.y,-FForward.z)创建你的Z向量。如果你取出减号,那么当前向量为(0,0,1)时,你将得到你期望的单位矩阵。
如果你想保留减号,并且你想要一个(0,0,-1)的前向矢量来产生一个单位矩阵,那么你需要将十字产品从Cross(z,FUp)改为Cross (FUp,z),因为OpenGL使用右手坐标系。请参阅Cross product。
15在错误的地方
我同意你的意见,我希望翻译矩阵看起来像这样:
(1, 0, 0, x)
(0, 1, 0, y)
(0, 0, 1, z)
(0, 0, 0, 1)
请注意,OpenGL将其矩阵存储在列顺序而非行顺序中,因此当您获取模型视图矩阵时,它将按以下顺序出现:
(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])
如果您认为它按行顺序排列,则可能是导致混淆的原因。