-2

I've recently started a project with LWJGL 3 (Lightweight Java Game Library 3) and Java, and I've been trying to render a simple cube. However, my code currently displays an empty black screen.

This is my render code:

public void renderObject(Camera camera, ShaderProgram shader) {
    GL11.glEnable(GL11.GL_DEPTH_TEST);
    GL11.glDepthFunc(GL11.GL_LEQUAL);
    GL11.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); 
    Matrix4f mvpMatrix = Matrix4f.multiply(projection, Matrix4f.multiply(entity.modelMatrix(), view)); 
    shader.uniformMatrix4f("mvpMatrix", mvpMatrix);
    indexBuf.bind();
    GL13.glActiveTexture(GL13.GL_TEXTURE0); 
    entity.getTexturedMesh().bindTexture(); 
    GL11.glDrawElements(GL11.GL_TRIANGLES, entity.getTexturedMesh().mesh.getIndexVec().size(), GL11.GL_UNSIGNED_INT, 0); 
    indexBuf.unbind();
    vao.unbind();
    shader.stop();
}

This is my vertex shader:

#version 450 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoords;

out vec3 color;
out vec2 pass_texCoords;

uniform mat4 mvpMatrix;

void main(void) {

    gl_Position = mvpMatrix * vec4(position, 1.0);
    color = vec3(0.0, 1.0, 0.0);
    pass_texCoords = texCoords;
}

This is my fragment shader:

#version 450 core

in vec3 color;
in vec2 pass_texCoords;

out vec4 out_color;
uniform sampler2D textureSampler;

void main(void) {
    out_color = texture(textureSampler,pass_texCoords);
}

(FYI, Matrix4f is a custom math class that I made. )

Remarks: I discovered that if I change gl_Position = mvpMatrix * vec4(position, 1.0) to glPosition = vec4(position, 1.0), then it renders (although I can see only one face of the cube). One can therefore infer that the problem is with mvpMatrix.

However, I made two other discoveries that seemed to contradict my hypothesis.

First, I printed out the mvpMatrix in renderObject and found that it was indeed correct.

Therefore, I deduced that the problem must be with the function uniformMatrix4f(), which was supposed to pass the uniform from the code to the shader.

To test my hypothesis, I decided to make a uniform matrix called testMatrix, which was just

[0, 0, 0, 0]
[0, 1, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]

and added this line to the code:

shader.uniformMatrix4f("testMatrix", testMatrix);

I had also discovered that you can debug shaders by passing the value to the color.

Therefore, I changed gl_Position = mvpMatrix * vec4(position, 1.0) to glPosition = vec4(position, 1.0) and out_color = texture(textureSampler,pass_texCoords) to out_color = vec4(color, 1.0).

Then I changed color = vec3(0.0, 1.0, 0.0) to

color = vec3(testMatrix[0][0], testMatrix[1][1], testMatrix[2][2]);

If my hypothesis were correct, as I expected, then I would probably get a blank screen. However, if my hypothesis were false, the color would be vec3(0, 1, 0), or green, and I would see a green square.

When I rendered it, I saw a green square, not a blank screen, which was extremely puzzling, and since I can't find any other source of the problem, I'm stuck.

genpfault
  • 51,148
  • 11
  • 85
  • 139
new Q Open Wid
  • 2,225
  • 2
  • 18
  • 34

1 Answers1

0

It's been very, VERY long since I solved this problem, but I realized I was storing the transpose of the matrix instead of the matrix itself when I was putting the uniform to the shader. The reason why my color = vec3(testMatrix[0][0], testMatrix[1][1], testMatrix[2][2]) didn't work was because the matrix values I checked were all on the diagonal, which means they were unaffected.

I fixed this by simply changing the 'transposed' attribute from false to true.

GL20.glUniformMatrix4fv(loc, false, matrixBuffer);

->

GL20.glUniformMatrix4fv(loc, true, matrixBuffer);

More explanation:

I was using a one-dimensional array buffer to store the matrix (as this made it easier to store it into the uniform buffer).

Here is a 4x4 matrix for reference:

m00 m01 m02 m03
m10 m11 m12 m13
m20 m21 m22 m23
m30 m31 m32 m33

To convert the two-dimensional coordinates to the one-dimensional coordinates, I used this function:

m[x][y] -> [x + y * sz]

Which means that my array was mapped like this:

0 4  8 12
1 5  9 13
2 6 10 14
3 7 11 15

I thought this was the right order. But it turns out this is exactly the transpose of the order I needed to put my matrices in!

I don't want this answer to get too lengthy, but you can find more info here.

new Q Open Wid
  • 2,225
  • 2
  • 18
  • 34