1
votes

I am trying to implement MVP Matrices into my engine. My Model matrix is working fine but my View and Projection Matrices do not work. Here is the creation for both:

    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);
    }

The vertices i'm trying to render are: -0.5f, 0.5f, -1.0f, -0.5f, -0.5f, -1.0f, 0.5f, -0.5f, -1.0f, 0.5f, 0.5f, -1.0f

I Tested the view matrix before the upload to shader and it is correct.

This is how I render:

    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();

Vertex Shader:

#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;
}
3
I can't see any obvious issue in the code. You have to be more specific. What exactly "do not work"? How do you use the matrices in the shader code?Rabbid76
IS the geometry clipped by the near plane of the viewing frustum?Rabbid76
Matrices are multiplied in the shader code. The geometry just does not render.PixelRifts
In which order do you multiply the matrices?Rabbid76
Do you set the matrix uniforms after the program was installed by glUseProgram?Rabbid76

3 Answers

3
votes

While the answer of @Rabbid76 of course it totally right in general, the actual issue in this case is a combination of bad API design (in the case of JOML) and not reading the JavaDocs of the used methods.

In particular the Matrix4f._mNN() methods only set the respective matrix field but omit reevaluating the matrix properties stored internally in order to accelerate/route further matrix operations (most notably multiplication) to more optimized methods when knowing about the properties of a matrix, such as "is it identity", "does it only represent translation", "is it a perspective projection", "is it affine", "is it orthonormal" etc... This is an optimization that JOML applies to in most cases very significantly improve performance of matrix multiplications.

As for bad API design: Those methods are only public in order for the class org.joml.internal.MemUtil to access them to set matrix elements read from NIO buffers. Since Java does not (yet) have friend classes, those _mNN() methods must have been public for this reason. They are however not meant for public/client usage.

I've changed this now and the next JOML version 1.9.21 will not expose them anymore. In order to set matrix fields still explicitly (not necessary in most cases like these here) one can still use the mNN() methods, which do reevaluate/weaken the matrix properties to make all further operations still correct, albeit likely non-optimal.

So the issue in this cases is actually: JOML still thinks that the manually created perspective projection matrix is the identity matrix and will short-cut further matrix multiplications assuming so.

1
votes

The geometry has to be place in the Viewing frustum. All the geometry which is out of the viewing frustum, is clipped an not "visible".
The geometry has to be positioned between the NEAR_PLANE and FAR_PLANE. Note, at perspective projection NEAR_PLANE and FAR_PLANE have to be greater 0:

0 < NEAR_PLANE < FAR_PLANE 

Note, in view space the z axis points out of the viewport. An initial view matrix that looks at the object can be defined by:

pos = new Vector3f(0, 0, (NEAR_PLANE + FAR_PLANE)/2f );
rot = new Vector3f(0, 0, 0);

Note, if the distance to the FAR_PLANE is very far, then the object is possibly very small and almost invisible. In this case change the inital values:

pos = new Vector3f(0, 0, NEAR_PLANE * 0.99f + FAR_PLANE * 0.01f );
rot = new Vector3f(0, 0, 0);
-1
votes

So I tried everything and found out that you should not initialise the uniform locations to 0. In the class that extends the ShaderProgram class, I had:

    private int l_TextureSampler = 0;
    private int l_ProjectionMatrix = 0;
    private int l_ViewMatrix = 0;
    private int l_ModelMatrix = 0;

Changing it to this:

    private int l_TextureSampler;
    private int l_ProjectionMatrix;
    private int l_ViewMatrix;
    private int l_ModelMatrix;

Worked for me.