JOML-CI / JOML

A Java math library for OpenGL rendering calculations
MIT License
728 stars 104 forks source link

Rotate matrix help required #268

Closed Pinkolik closed 4 years ago

Pinkolik commented 4 years ago

Hello! I've been studying OpenGL with help of this great site https://learnopengl.com/. And yesterday I got to the lesson about coordinate systems (https://learnopengl.com/Getting-started/Coordinate-Systems) when I encountered a problem, which I think can be related to JOML. You see, I'm coding in Java so I use LWJGL and JOML. I think I've done all steps correctly but my result is different from the one desribed in the lesson. I'm not too good in matricies and algebra, so I'm stuck and can't figure out what's wrong. Here's how it looks like: (https://imgur.com/a/QjJO1Rh) You can notice that it looks like the cubes move towards the camera and grow in diagonal. I'm sure that's not correct. I've tried all kinds of rotations, but I always get this result. So I hope you could help me. Here's my code of the main loop.

while (!glfwWindowShouldClose(window)) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
            texture1.use();
            texture2.use(1);
            shader.use();
            try (MemoryStack stack = stackPush()) {
                FloatBuffer view = new Matrix4f().translate(new Vector3f(0, 0, -3.0f)).get(stack.mallocFloat(16));
                FloatBuffer projection = new Matrix4f().perspective((float) Math.toRadians(45), 800.0f / 600.0f, 0.1f, 100.0f)
                                                       .get(stack.mallocFloat(16));
                shader.setMatrix4f("view", view);
                shader.setMatrix4f("projection", projection);
            }
            glBindVertexArray(vao);
            for (int i = 0, cubePositionsLength = cubePositions.length; i < cubePositionsLength; i++) {
                Vector3f cubePosition = cubePositions[i];
                try (MemoryStack stack = stackPush()) {
                    double angle = 20.0f * i + glfwGetTime();
                    FloatBuffer model = new Matrix4f().translate(cubePosition).rotate((float) angle, 0.5f, 1.0f, 0.0f)
                                                      .get(stack.mallocFloat(16));
                    shader.setMatrix4f("model", model);
                }
                glDrawArrays(GL_TRIANGLES, 0, 36);
            }

            glfwSwapBuffers(window); // swap the color buffers

            // Poll for window events. The key callback above will only be
            // invoked during this call.
            glfwPollEvents();
        }

And here's my vertex shader:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 TexCoord;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    TexCoord = aTexCoord;
}

Thank you in advance!

httpdigest commented 4 years ago

Code looks good to me. Can you provide a full MCVE (minimal complete and verifiable example)? Do the cubePositions[] possibly change? And what does shader.setMatrix4f(...) look like?

Pinkolik commented 4 years ago

Here's the full project. Don't worry, it's small, only main programm class and two helper classes. worlds.zip As far as I can see cubePositions[] are not modified in any way. And shader.setMatrix4f(...) looks like this:

    public void setMatrix4f(final String name, final FloatBuffer matrix4f) {
        int location = glGetUniformLocation(shaderProgramId, name);
        glUniformMatrix4fv(location, false, matrix4f);
    }
httpdigest commented 4 years ago

Okay, the problem is that the rotation axis in your Matrix4f.rotate(4-floats) call in your code is not normalized/unit. See the JavaDocs of this method:

The axis described by the three components needs to be a unit vector.

Pinkolik commented 4 years ago

Normalization solved the problem, thank you very much! I will check javadocs first from now on.