我正在使用LWJGL学习OpenGL 3。我已经尝试实现一个等同于gluLookAt()
的函数,虽然它能够工作,但是我有些困惑。
我承认我只是从网上各种来源中复制了这段代码,但经过多次研究,我认为我理解了它背后的数学原理,并且我也明白了LWJGL的工作原理。
然而,在我的应用程序中,“正确”的gluLookAt
代码行为不正确,因为相机似乎转向了错误的方向。我只能通过转置正交向量forward
,side
和up
(希望我使用了正确的术语!)来使我的代码工作,但我很确定这样是错误的...
private static final Vector3f forward = new Vector3f();
private static final Vector3f side = new Vector3f();
private static final Vector3f up = new Vector3f();
private static final Vector3f eye = new Vector3f();
public static Matrix4f lookAt(float eyeX, float eyeY, float eyeZ,
float centerX, float centerY, float centerZ,
float upX, float upY, float upZ) {
forward.set(centerX - eyeX, centerY - eyeY, centerZ - eyeZ);
forward.normalise();
up.set(upX, upY, upZ);
Vector3f.cross(forward, up, side);
side.normalise();
Vector3f.cross(side, forward, up);
up.normalise();
Matrix4f matrix = new Matrix4f();
matrix.m00 = side.x;
matrix.m01 = side.y;
matrix.m02 = side.z;
matrix.m10 = up.x;
matrix.m11 = up.y;
matrix.m12 = up.z;
matrix.m20 = -forward.x;
matrix.m21 = -forward.y;
matrix.m22 = -forward.z;
matrix.transpose(); // <------ My dumb hack
eye.set(-eyeX, -eyeY, -eyeZ);
matrix.translate(eye);
return matrix;
}
我认为我不应该进行转置,但是如果没有转置,它就不起作用。我使用transpose()
,因为我懒得重新输入所有矩阵单元格的位置!
我的理解是lookAt矩阵的形式应该如下:
[ side.x up.x fwd.x 0 ] [ 1 0 0 -eye.x ]
[ side.y up.y fwd.y 0 ] [ 0 1 0 -eye.y ]
[ side.z up.z fwd.z 0 ] [ 0 0 1 -eye.z ]
[ 0 0 0 1 ] [ 0 0 0 1 ]
我认为LWJGL的Matrix4f
类将矩阵单元表示为m<col><row>
。 translate(Vector3f)
方法执行以下操作:
public static Matrix4f translate(Vector3f vec, Matrix4f src, Matrix4f dest) {
...
dest.m30 += src.m00 * vec.x + src.m10 * vec.y + src.m20 * vec.z;
dest.m31 += src.m01 * vec.x + src.m11 * vec.y + src.m21 * vec.z;
dest.m32 += src.m02 * vec.x + src.m12 * vec.y + src.m22 * vec.z;
dest.m33 += src.m03 * vec.x + src.m13 * vec.y + src.m23 * vec.z;
...
}
我非常困惑,不知道哪个部分出了问题。是我的lookAt矩阵的理解有误,还是Matrix4f
的列/行优先(这是一个单词吗?!)有问题,还是其他原因?我的代码剩下的部分是否正确呢?它其实是正确的,只是我过于担心了吗?我是个笨蛋吗?
谢谢。