我正在尝试将MVP矩阵实施到我的引擎中。 我的模型矩阵工作正常,但我的视图和投影矩阵不起作用。 这是两者的创建:
public void calculateProjectionMatrix() {
final float aspect = Display.getDisplayWidth() / Display.getDisplayHeight();
final float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspect);
final float x_scale = y_scale / aspect;
final float frustum_length = FAR_PLANE - NEAR_PLANE;
proj.identity();
proj._m00(x_scale);
proj._m11(y_scale);
proj._m22(-((FAR_PLANE + NEAR_PLANE) / frustum_length));
proj._m23(-1);
proj._m32(-((2 * NEAR_PLANE * FAR_PLANE) / frustum_length));
proj._m33(0);
}
public void calculateViewMatrix() {
view.identity();
view.rotate((float) Math.toRadians(rot.x), Mathf.xRot);
view.rotate((float) Math.toRadians(rot.y), Mathf.yRot);
view.rotate((float) Math.toRadians(rot.z), Mathf.zRot);
view.translate(new Vector3f(pos).mul(-1));
System.out.println(view);
}
我要渲染的顶点是: -0.5f,0.5f,-1.0f, -0.5f,-0.5f,-1.0f, 0.5f,-0.5f,-1.0f, 0.5f,0.5f,-1.0f
我在上传到着色器之前测试了视图矩阵,它是正确的。
这就是我的渲染方式:
ss.bind();
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
ss.loadViewProjection(cam);
ss.loadModelMatrix(Mathf.transformation(new Vector3f(0, 0, 0), new Vector3f(), new Vector3f(1)));
ss.connectTextureUnits();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
ss.unbind();
顶点着色器:
#version 330 core
layout(location = 0) in vec3 i_position;
layout(location = 1) in vec2 i_texCoord;
layout(location = 2) in vec3 i_normal;
out vec2 p_texCoord;
uniform mat4 u_proj;
uniform mat4 u_view;
uniform mat4 u_model;
void main() {
gl_Position = u_proj * u_view * u_model * vec4(i_position, 1.0);
p_texCoord = i_texCoord;
}
答案 0 :(得分:3)
虽然@ Rabbid76的答案通常总的来说是完全正确的,但这种情况下的实际问题是不良的API设计(在JOML的情况下)和未阅读所用方法的JavaDoc的结合。
特别是Matrix4f._mNN()方法仅设置相应的矩阵字段,但是省略了重新评估内部存储的矩阵属性,以便在知道以下属性时将更多的矩阵运算(最著名的是乘法)加速/路由到更优化的方法。矩阵,例如“是同一性”,“是否仅代表翻译”,“是否是透视投影”,“是否仿射”,“是否正交”等。 这是JOML在大多数情况下适用的一种优化,可以极大地提高矩阵乘法的性能。
关于不良的API设计:这些方法仅是公共的,以便类{{1}}访问它们以设置从NIO缓冲区读取的矩阵元素。由于Java还没有朋友类,因此_mNN()方法必须是公共的。但是,它们并非供公众/客户使用。
I've changed this now和下一个JOML版本1.9.21将不再公开它们。 为了仍然明确地设置矩阵字段(在大多数情况下不是必需的),仍然可以使用mNN()方法,该方法会重新评估/削弱矩阵属性以使所有进一步的操作仍然正确,尽管可能不是最佳。
因此,在这种情况下的问题实际上是:JOML仍然认为手动创建的透视投影矩阵是单位矩阵,并假设这样将简化进一步的矩阵乘法。
答案 1 :(得分:-1)
因此,我尝试了所有操作,发现不应将统一位置初始化为0。 在扩展ShaderProgram类的类中,我有:
private int l_TextureSampler = 0;
private int l_ProjectionMatrix = 0;
private int l_ViewMatrix = 0;
private int l_ModelMatrix = 0;
将其更改为此:
private int l_TextureSampler;
private int l_ProjectionMatrix;
private int l_ViewMatrix;
private int l_ModelMatrix;
为我工作。