我尝试使用LWJGL3在Java中使用OpenGL渲染一个简单的三角形。
一切都很好,但投影矩阵(透视)不起作用。在C ++中,我刚刚使用了glm::perspective()
方法,该方法效果很好。但是在Java中,我自己实现了它,因为没有像GLM这样的库来处理它。
所以这里是Java中透视的代码:
public mat4 perspective(float fov, float aspect, float zNear, float zFar){
mat4 projection = new mat4();
float halfTanFov = (float) Math.tan(Math.toRadians(fov / 2));
float frustum = zNear - zFar;
projection.m[0][0] = 1f / halfTanFov * aspect;
projection.m[1][1] = 1f / halfTanFov;
projection.m[2][2] = - ((zNear + zFar) / frustum);
projection.m[2][3] = 2 * zFar * zNear / frustum;
projection.m[3][2] = 1;
return projection;
}
我创建了mat4
类,这就是我应用乘法的方法:
for(int i=0; i<4; i++)
for(int j=0; j<4; j++){
result.m[i][j] = matrix.m[i][0] * m[0][j] +
matrix.m[i][1] * m[1][j] +
matrix.m[i][2] * m[2][j] +
matrix.m[i][3] * m[3][j];
}
当然,我测试了这个乘法,并将结果与我的TI输出进行了比较,并且效果很好。
其他信息,constructor
类的默认mat4
将所有值都设置为0。
这是代码:
public void setZero(){
m[0][0] = 0; m[0][1] = 0; m[0][2] = 0; m[0][3] = 0;
m[1][0] = 0; m[1][1] = 0; m[1][2] = 0; m[1][3] = 0;
m[2][0] = 0; m[2][1] = 0; m[2][2] = 0; m[2][3] = 0;
m[3][0] = 0; m[3][1] = 0; m[3][2] = 0; m[3][3] = 0;
}
另一方面,viewMatrix()
工作得很好。它是lookAt()
方法的简单实现。
因此,当lookAtMatrix * modelMatrix * position
vec4 position
结果良好时。perspective * lookatMatrix * model * position
但是当我尝试为MVP添加投影矩阵时:public mat4 getViewProjection() {
mViewProjection = Transform.getInstance().lookAt(mPosition, mPosition.add(mDirection), mUp);
return mViewProjection;
}
public mat4 getMVP(mat4 model){
return mPerspective.mult(getViewProjection()).mult(model);
}
结果是什么都没有。
在这里,我在代码中执行此操作:
#version 430
layout(location=0) in vec3 position;
uniform mat4 MVP;
void main(void){
gl_Position = MVP * vec4(position, 1);
}
这是我的简单GLSL着色器(用于顶点着色器):
{{1}}
我尝试了透视的其他实现没有成功,所以我猜我的错误是在其他地方,但遗憾的是,我无法弄清楚在哪里。如果有人可以提供帮助,那就太棒了!谢谢。 如果你有其他信息,请问我,我会发布它。
答案 0 :(得分:0)
可能有其他方法来定义投影矩阵。但至少与我通常与OpenGL一起使用的投影矩阵相比,你有几个反转的符号。在这:
projection.m[0][0] = 1f / halfTanFov * aspect;
projection.m[1][1] = 1f / halfTanFov;
projection.m[2][2] = - ((zNear + zFar) / frustum);
projection.m[2][3] = 2 * zFar * zNear / frustum;
projection.m[3][2] = 1;
如果您希望相机在眼睛坐标空间中查看正 z轴的方向,则这些符号实际上可能正常。让相机向下看负 z轴会更常见。
更重要的是,看起来你的矩阵是转置的。至少只要您按列主顺序指定矩阵,这是它通常使用OpenGL完成的方式,并且看起来与您发布的代码一致。
通过这两个更正,代码应为:
projection.m[0][0] = 1f / halfTanFov * aspect;
projection.m[1][1] = 1f / halfTanFov;
projection.m[2][2] = (zNear + zFar) / frustum;
projection.m[3][2] = 2 * zFar * zNear / frustum;
projection.m[2][3] = -1f;