Search code examples
javamacos3dlwjgljoml

I use LWJGL and the JOML library, but when I multiply matrices it doesn't work


I start learning LWJGL very recently and I am trying to get a simple shader to work. I followed an "old" tutorial but when I run the code no shapes appear (the window open but it is just black). Here is my .vs file for my shader :

#version 330

layout (location = 0) in vec3 position;

uniform mat4 transformWorld;
uniform mat4 transformObject;
uniform mat4 cameraProjection;

void main() {
    gl_Position = cameraProjection * transformWorld * transformObject * vec4(position, 1);
}

I don't know what to send to show the problem but here is my main file

public class Main {
    public static void main(String[] args) {
        Window window = new Window();
        window.createWindow(700, 700, "window");
        window.init();
        
        Mesh mesh = new Mesh();
        mesh.create(new float[] {
                -1, -1 ,0,
                0, 1  ,0,
                1, -1 ,0
        });
        
        Shader shader = new Shader();
        shader.create("basic");
        
        Camera camera = new Camera();
        Transform transform = new Transform();
        
        camera.setPersepective((float)Math.toRadians(70), 640.0f / 480.0f, 0.01f, 1000.0f);
        camera.setPosition(new Vector3f(0, 1, 3));
        camera.setRotation(new Quaternionf(new AxisAngle4f((float)Math.toRadians(-30), new Vector3f(1, 0, 0))));
        
        boolean isRunning = true;
        float x = 0;
        
        while(isRunning) {
            isRunning = !window.shouldColse();
            
            x += 0.01f;
            transform.setPosition(new Vector3f((float)Math.sin(Math.toRadians(x)), 0, 0));
            transform.getRotation().rotateAxis((float)Math.toRadians(1), 0, 1, 0);
            
            glfwPollEvents();
            
            glClear(GL_COLOR_BUFFER_BIT);
            
            shader.useShader();
            shader.setCamera(camera);
            shader.setTranform(transform);
            mesh.draw();
            
            window.swapBuffers();
        }
        shader.destroy();
        mesh.destroy();
        window.destroy();
    }
}

Here is the code for the shader function:

public void setCamera(Camera camera) {
    if (uniMatProjection != -1) {
        float matrix[] = new float[16];
        camera.getProjection().get(matrix);
        glUniformMatrix4fv(uniMatProjection, false, matrix);
    }
    if (uniMatTransformWorld != -1) {
        float matrix[] = new float[16];
        camera.getTransformation().get(matrix);
        glUniformMatrix4fv(uniMatTransformWorld, false, matrix);
    }
}
    
public void setTranform(Transform transform) {
    if (uniMatTransformObject != -1) {
        float matrix[] = new float[16];
        transform.getTransformation().get(matrix);
        glUniformMatrix4fv(uniMatTransformObject, false, matrix);
    }
}

Here is the code for the camera:

public class Camera {
    private Vector3f position;
    private Quaternionf rotation;
    private Matrix4f projection;
    
    public Camera() {
        this.position = new Vector3f();
        this.rotation = new Quaternionf();
        this.projection = new Matrix4f();
    }
    
    public Matrix4f getTransformation() {
        Matrix4f returnValue = new Matrix4f();
        
        returnValue.rotate(rotation.conjugate(new Quaternionf()));
        returnValue.translate(position.mul(-1, new Vector3f()));
        
        return returnValue;
    }
    
    public void setOrthographics(float left, float right, float top, float bottom) {
        projection.setOrtho2D(left, right, bottom, top);
    }
    
    public void setPersepective(float fov, float aspectRatio, float zNear, float zFar) {
        projection.setPerspective(fov, aspectRatio, zNear, zFar);
    }

    public Vector3f getPosition() {
        return position;
    }

    public void setPosition(Vector3f position) {
        this.position = position;
    }

    public Quaternionf getRotation() {
        return rotation;
    }

    public void setRotation(Quaternionf rotation) {
        this.rotation = rotation;
    }

    public Matrix4f getProjection() {
        return projection;
    }
}

Here the code for the transform:

public class Transform {
    private Vector3f position;
    private Quaternionf rotation;
    private Vector3f scale;
    
    public Transform() {
        position = new Vector3f();
        rotation = new Quaternionf();
        scale = new Vector3f(1); 
    }
    
    public Matrix4f getTransformation() {
        Matrix4f returnValue = new Matrix4f();
        
        returnValue.translate(position);
        returnValue.rotate(rotation);
        returnValue.scale(scale);
        
        return returnValue;
    }

    public Vector3f getPosition() {
        return position;
    }

    public void setPosition(Vector3f position) {
        this.position = position;
    }

    public Quaternionf getRotation() {
        return rotation;
    }

    public void setRotation(Quaternionf rotation) {
        this.rotation = rotation;
    }

    public Vector3f getScale() {
        return scale;
    }

    public void setScale(Vector3f scale) {
        this.scale = scale;
    }
}

and the Mesh class

public class Mesh {

    private int vertexArrayObject;
    private int vertexBufferObject;
    
    private int vertexCount;
    
    public Mesh() {
    }
    
    public boolean create(float vertices[]) {
        vertexArrayObject = glGenVertexArrays();
        glBindVertexArray(vertexArrayObject);
        
        vertexBufferObject = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
        glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
        
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
        
        glBindVertexArray(0);
        
        vertexCount = vertices.length / 3;
        
        return true;
    }
    
    public void destroy() {
        glDeleteBuffers(vertexBufferObject);
        glDeleteVertexArrays(vertexArrayObject);
    }
    
    public void draw() {
        glBindVertexArray(vertexArrayObject);
        
        glEnableVertexAttribArray(0);
        
        glDrawArrays(GL_TRIANGLES, 0, vertexCount);
        
        glDisableVertexAttribArray(0);
        
        glBindVertexArray(0);
    }
}

And I work with macOS. I hope I am clear and someone could help me.


Solution

  • The problem was that in the shader class, I was setting values too early, and the matrices multiplication can't work because of that. We just need to put

    uniMatProjection = glGetUniformLocation(program, "cameraProjection");
            uniMatTransformWorld = glGetUniformLocation(program, "transformWorld");
            uniMatTransformObject = glGetUniformLocation(program, "transformObject");
    

    at the end of setCamera and setTransform in the Shader class