Problem with Matrices and FloatBuffers

So I can’t seem to fix my rendering code in lwjgl. I’ve narrowed the problem down to how I’m loading a Matrix4f into glUniformMatrix4() as a FloatBuffer.
Long story short, I know:

public FloatBuffer toBuffer(Matrix4f mat){
        	    	FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);
        	    	matrixBuffer.clear();
        	    	mat.store(matrixBuffer);
        	    	matrixBuffer.flip();
        	    	return matrixBuffer;    	
         }

Does not return a buffer that renders properly (black screen).
And I know that:

private final static FloatBuffer direct = BufferUtils.createFloatBuffer(16);
        
        public FloatBuffer toBuffer() {
                direct.clear();
                direct.put(matrix); // matrix is a float[16]
                direct.flip();
                return direct;
        }

works.
Why? What is different here? Is there a more convenient way to upload a Matrix4f to lwjgl than my first snippet or an easy way to convert a Marix4f to a float[]?
I’m really stumped. Thanks.

Matrix4f.store uses column-major order, for OpenGL:

You may need to transpose the matrix. Luckily glUniformMatrix includes a parameter for that… :slight_smile:

That’s one of the things I thought! :frowning: I tried both mat.storeTranspose(matrixBuffer) and using ‘true’ for that parameter.
Thanks, any other ideas?

EDIT: Just to be clear, I tried them separately

Davedes, I just read your shader tutorial. I cannot understand why this :

public void setUniformMatrix(int loc, boolean transposed, Matrix4f mat) { 
if (loc==-1)
 return; 
if (buf16Pool == null) 		
 buf16Pool = BufferUtils.createFloatBuffer(16); 	
buf16Pool.clear(); 	
mat.store(buf16Pool); 	
buf16Pool.flip(); 	
glUniformMatrix4(loc, transposed, buf16Pool); 
}

Would work and mine would not.

Probably because your matrix is incorrect or your vertex shader is not using the matrix correctly. Can’t really help without seeing more code… :point:

Allright, I’m off work. To start with, I am using the identity matrix to simplify things. I am using code from ra4king’s ports of the arcsynthesis tutorials and it works with his Matrix4 class but when I do it with the lwjgl Matrix4f class It does not work correctly.

Here is the rendering code. The Init() method (not included) is pretty standard vbo/vao binding stuff and I know it works because the draw method alternates between using the two matrix classes once every second. The Matrix4 class by ra4king works and the Matrix4f class does not. It flashes between a cube and black screen. It is pretty ugly because I’ve temporarily cut everything else away for debugging.

 public void draw() {
                	 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
                        Matrix4 modelToCameraMatrix = new Matrix4().clearToIdentity().translate(0, 0, -5);
                        
                        program.begin();
                        time++;
                        glBindVertexArray(vao); // vao is a simple cube 
                        if (time <=60) // doesn't work
                        	glUniformMatrix4(cameraToClipMatrixUniform, true, toBuffer(camtoclip)); // have tried true and false for second param.
                        else if (time <=120) // does
                        	glUniformMatrix4(cameraToClipMatrixUniform, false, cameraToClipMatrix.toBuffer());
                        else 
                        	time = 0;
                                glUniformMatrix4(modelToCameraMatrixUniform, false, modelToCameraMatrix.toBuffer());
                                glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_SHORT, 0);
                        
                        glBindVertexArray(0);
                        System.out.print(toBuffer(camtoclip) == cameraToClipMatrix.toBuffer());
                        program.end();
                }
                
                public FloatBuffer toBuffer(Matrix4f mat){
        	    	FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);
        	    	matrixBuffer.clear();
        	    	mat.store(matrixBuffer); //have tried mat.storeTranspose(matrixBuffer) here
        	    	matrixBuffer.flip();
        	    	return matrixBuffer;    	
        	    }
        

This is the toBuffer() method from Matrix4. The variable ‘matrix’ is a class scope float[].

        private final static FloatBuffer direct = BufferUtils.createFloatBuffer(16);
        
        public FloatBuffer toBuffer() {
                direct.clear();
                direct.put(matrix); // 'matrix' is a float[]
                direct.flip();
                return direct;
        }

Here are the declarations and inits for the matricies.

        private Matrix4f camtoclip;
        private Matrix4 cameraToClipMatrix;
                cameraToClipMatrix = new Matrix4().clearToIdentity()
                camtoclip = new Matrix4f();

Thanks again. There’s a wheelbarrow full of medals here for whoever can explain what is wrong.

EDIT: Heres my vert shader

#version 330

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;

smooth out vec4 theColor;

uniform mat4 cameraToClipMatrix;
uniform mat4 modelToCameraMatrix;

void main()
{
	gl_Position = cameraToClipMatrix * modelToCameraMatrix * position;
	theColor = color;
}

Since Matrix4f stores in column-major, keep the second parameter as “false”.

Also does uploading the modelToCameraMatrix always work? If so, that’s really interesting that cameraToClipMatrix isn’t.

That’s what I thought! Yes it does always work. I debugged my own code down to bare bones looking for the problem so I just used your Example6_4 because they’re so similar. Just for debugging this buffer thing. Here is the modified class; nothing but rendering. Here
Please give it a run and see this for yourself.
Here is at least one example of someone using what seems to be identical methods.

So I wrote up this:

System.out.print(matrixBuffer.equals( cameraToClipMatrix.transpose().toBuffer())+"\n");
                System.out.print((camtoclip.m00 == cameraToClipMatrix.get(0))+" ");
                System.out.print((camtoclip.m01 == cameraToClipMatrix.get(1))+" ");
                System.out.print((camtoclip.m02 == cameraToClipMatrix.get(2))+" ");
                System.out.print((camtoclip.m03 == cameraToClipMatrix.get(3))+" "+"\n");
                System.out.print((camtoclip.m10 == cameraToClipMatrix.get(4))+" ");
                System.out.print((camtoclip.m11 == cameraToClipMatrix.get(5))+" ");
                System.out.print((camtoclip.m12== cameraToClipMatrix.get(6))+" ");
                System.out.print((camtoclip.m13 == cameraToClipMatrix.get(7))+" "+"\n");
                System.out.print((camtoclip.m20 == cameraToClipMatrix.get(8))+" ");
                System.out.print((camtoclip.m21 == cameraToClipMatrix.get(9))+" ");
                System.out.print((camtoclip.m22 == cameraToClipMatrix.get(10))+" ");
                System.out.print((camtoclip.m23 == cameraToClipMatrix.get(11))+" "+"\n");
                System.out.print((camtoclip.m30 == cameraToClipMatrix.get(12))+" ");
                System.out.print((camtoclip.m31 == cameraToClipMatrix.get(13))+" ");
                System.out.print((camtoclip.m32 == cameraToClipMatrix.get(14))+" ");
                System.out.print((camtoclip.m33 == cameraToClipMatrix.get(15))+" "+"\n");
                System.out.print("matrixBuffer"+"\n");
                for(int i = 0; i< 16 ; i++){
                	 System.out.print(matrixBuffer.get(i)+" ");
                	 if(i%4 == 3)
                		 System.out.print("\n");
                }
                System.out.print("cameraToClipMatrix.toBuffer()"+"\n");
                for(int i = 0; i< 16 ; i++){
                	 System.out.print(cameraToClipMatrix.toBuffer().get(i)+" ");
                	 if(i%4 == 3)
                		 System.out.print("\n");
                }

to check the matrices and buffers.

And my results were:

false
true true true true 
true true true true 
true true true true 
true true true true 
matrixBuffer
1.0 0.0 0.0 0.0 
0.0 1.0 0.0 0.0 
0.0 0.0 1.0 0.0 
0.0 0.0 0.0 1.0 
cameraToClipMatrix.toBuffer()
1.0 0.0 0.0 0.0 
0.0 1.0 0.0 0.0 
0.0 0.0 1.0 0.0 
0.0 0.0 0.0 1.0 

Either I’m a moron or something strange is going on. :clue:

Found the problem, you didn’t set the camtoclip matrix to translate(0, 0, -5). Without that, the object is being draw ON the camera and since the plane is near-clipped at 1: nothing is drawn :slight_smile:

Also, why did you comment out glCullFace and glFrontFace calls?

Lastly, when you printed out those matrices, you printed their transpose because, remember 0-1-2-3 is the first column yet you were printing them out as the first row. Since they’re both identity matrices then it doesn’t matter because it’s the same both ways, but in the future remember that :wink:

I found another little mistake too. :emo: Thank you, I completely missed that. :slight_smile: I commented out the face culling just to be sure that it wasn’t some error with seeing things inside out or something stupid.
Oh and I know that I was printing in transpose, I knew I should have noted it but I didn’t. Thanks again!