Matrices issue with JGLM

Started by Neoptolemus, February 06, 2015, 10:30:24

Previous topic - Next topic

Neoptolemus

Hi everyone,

With the retirement of the old LWJGL 2.x math library in version 3.0, I've decided to switch over to JGLM, which is a Java port of the famous GLM library.

I seem to be having some real issues using it however, in that I cannot get anything to render on screen when using a projection perspective. I have the following simple coloured square defined:

float[] vertices = 
             {   -0.5f, 0.5f, 0.0f, // Left top front        ID: 0
                 -0.5f, -0.5f, 0.0f, // Left bottom  front    ID: 1
                 0.5f, -0.5f, 0.0f, // Right bottom  front   ID: 2
                 0.5f, 0.5f, 0.0f//, // Right top front      ID: 3
              };

float[] colours =
              {   0.0f, 0.0f, 0.0f,
                  1.0f, 1.0f, 0.0f,
                  1.0f, 0.0f, 1.0f,
                  1.0f, 1.0f, 1.0f
              };


These are loaded into the vertex array object, and rendered using glDrawElements. I have tested this without using any matrix transformations and it renders the square on screen just fine with the colours. However I now want to render this with a perspective projection, so I have defined the following matrices:

projectionMatrix = Matrices.perspective(70.0f, (float) DISPLAY_WIDTH/(float) DISPLAY_HEIGHT, 0.1f, 100.0f);
viewMatrix = Matrices.lookAt(new Vec3(0.0f, 0.0f, 4.0f), new Vec3(0,0,0), new Vec3(0,1,0));
modelMatrix = new Mat4(1.0f);


My vertex shader looks like this:

#version 440 core

layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vColour;

layout(location = 0) out vec3 outColour;

uniform mat4 pMatrix;
uniform mat4 vMatrix;
uniform mat4 mMatrix;

void main(void) {
	mat4 mvpMatrix = pMatrix * vMatrix * mMatrix;
	outColour = vColour;
	gl_Position = mvpMatrix * vec4(vPosition,1);
}


Of course, I set each uniform variable accordingly using a helper function I wrote:

    public static void setShaderMat4Attribute(int programId, String attributeName, Mat4 attributeValue) {
        GL20.glUseProgram(programId);
        int index = GL20.glGetUniformLocation(programId, attributeName);
        if (index > -1) {
            FloatBuffer buffer = attributeValue.getBuffer();
            buffer.flip();
            GL20.glUniformMatrix4(index, false, buffer);
        } else {
            System.err.println("WARNING: Could not find " + attributeName + " in provided shader!");
        }
        GL20.glUseProgram(0);
    }


However all I get is a black screen. Changing the lookAt variables seems to make no difference whatsoever. The way I understand this, my camera should be at world position (0,0,4) and looking at the origin (0,0,0) which will place it essentially right in front of the square, 4 units away. Just in case, I also tried placing the camera at (0,0,-4) in case my indices were back-to-front and I was actually looking at the back of the square, and I turned off back face culling as a further measure, but still nothing but blackness.

I've done the usual sanity checks on my code such as ensuring I am writing the viewMatrix matrix to the vMatrix uniform variable and so on, and I'm happy that the vertices and colour data is being handled correctly as this works when I treat the square's coordinates as screen space coordinates (i.e. no matrix manipulation at all). My rendering loop looks like this:

        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        
        ShaderUtils.setShaderMat4Attribute(shaderProgram, "pMatrix", projectionMatrix);
        ShaderUtils.setShaderMat4Attribute(shaderProgram, "vMatrix", viewMatrix);
        ShaderUtils.setShaderMat4Attribute(shaderProgram, "mMatrix", modelMatrix);
        
        GL20.glUseProgram(shaderProgram);

        GL30.glBindVertexArray(vaoId);
        GL20.glEnableVertexAttribArray(0);
        GL20.glEnableVertexAttribArray(1);

        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indId);
        GL11.glDrawElements(GL11.GL_TRIANGLES, indicesCount, GL11.GL_UNSIGNED_INT, 0);
        GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
        
        GL20.glDisableVertexAttribArray(0);
        GL20.glDisableVertexAttribArray(1);
        GL30.glBindVertexArray(0);
        GL20.glUseProgram(0);


Can anyone point out where I've gone wrong? I imagine the JGLM library would be reliable (at least for the basic stuff) since it is a straight port of a respected and much-used OpenGL library, so I must be using it wrong...

Kai

It is most likely due to JGLM storing the matrix layout in "row-major" (instead of "column-major" which OpenGL expects) when you convert it to a FloatBuffer before passing it to glUniformMatrix4.
See if there is any "transpose" on the matrix object. Or transpose the final float values in the buffer yourself. Or just use "true" as the second argument to glUniformMatrix4.

Neoptolemus

Thanks for the quick response, Kai. I hadn't considered that as a possibility.

I tried your suggestions but still no luck. I modified my setShaderMat4Attribute function to also call attributeValue = attributeValue.transpose(); before retrieving the buffer, but that didn't help, and I then also tried setting the second parameter in glUniformMatrix4 to true (both with and without the transpose) but again no dice. For good measure, I also re-ran all my other tests (setting the camera Z to +4 and -4, turning off back face culling etc.).

This is turning into quite the mystery! Any suggestions on other math libraries I could try as an alternative? Or perhaps I should just write my own!

Kai

Sorry about that not working. Was a quick-shot from me, without knowing JGLM, actually. :)
The demo sources of LWJGL3 have a small implementation of matrix/vector math with a convenient and GC-friendly Camera implementation with all your lookat and perspective methods.
And at least I would be very happy about you contributing to that. :)
Although I doubt now that the issue is really with JGLM.

Neoptolemus

Yeah I doubt the issue lies with JGLM, it's probably just that I'm not using it correctly. That said, a math library built from the ground up to support LWJGL would of course be much better. I'd be happy to contribute to it as I go along, are you one of the owners of that project? Would be happy to send over any updates I make to the library as I go along for consideration.

I've also been writing some other utilities like a parser for OBJ and FBX binary files, and a toolset for doing stuff like triangulating (if the model is defined in quads), bitangent and binormal calculation etc, so if those are of interest I'm also happy to share them with the world (when they're finished of course).

Kai

No, I am not one of the owners, just a code and wiki contributor.
But because there being so many people now asking for at least a math library in LWJGL 3, it would be worth conceiving a new project in github for that.
I don't think it will make it in LWJGL 3 directly, as LWJGL 3 is all about just providing a slim binding to underlying native libraries. But certainly, some side-projects for utilities would be great, because let's face it there: despite oft its name having "game library" in it, LWJGL 3 in its own is pretty useless for building games, especially for newcomers, since it is lacking all of the conveniences. ;)
Yeah, pros would know their way around the Java ecosystem to find appropriates, but if you just start, you're basically screwed ;)

Neoptolemus

I'll PM you since this is moving off-topic now :)

asyx

I actually have the same problem. Either we don't know how to use this library or something is broken. The newest release is only 24 days old or something. Maybe nobody noticed yet?