【问题标题】:I use LWJGL and the JOML library, but when I multiply matrices it doesn't work我使用 LWJGL 和 JOML 库,但是当我将矩阵相乘时它不起作用
【发布时间】:2021-09-12 14:28:18
【问题描述】:

我最近开始学习 LWJGL,我正在尝试让一个简单的着色器工作。我遵循了一个“旧”教程,但是当我运行代码时没有出现任何形状(窗口打开但它只是黑色)。这是我的着色器的 .vs 文件:

#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);
}

我不知道要发送什么来显示问题,但这是我的主文件

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();
    }
}

这是着色器功能的代码:

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);
    }
}

这是相机的代码:

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;
    }
}

这里是转换的代码:

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;
    }
}

和网格类

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);
    }
}

我使用 macOS。我希望我很清楚,有人可以帮助我。

【问题讨论】:

  • 您应该向我们发送更多代码,因为问题可能出在其他类中。
  • 无论如何,我建议你先尝试一下,有一些基本的东西:1)在while循环中,删除变换的旋转并设置一个简单的位置,如new Vector3f(0, 0, 0) 2)相机相同的东西3)尝试按比例放大您要渲染的对象。也许它太小了,或者它的比例设置为 0!我无法向您解释如何更改 Mesh 比例,因为您没有向我们发送它的代码,但您可以尝试。 (另外,对不起我的英语不好大声笑)
  • 您也可以尝试添加一个简单的相机运动(或者只是尝试手动更改相机位置来启动程序),然后在窗口中移动,因为网格可能不在该位置你认为是
  • 谢谢,我会试试的,我会在问题中添加更多代码
  • 您可以尝试的另一件重要的事情是将camera.setPersepective() 的最后两个值设置为... , 0.0f, 10000.0f)。如果你不改变这个,你的物体可能离相机太近或太远,所以它不会被渲染

标签: java macos 3d lwjgl joml


【解决方案1】:

问题是在着色器类中,我设置的值太早了,因此矩阵乘法无法工作。我们只需要放

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

在 Shader 类中的 setCamera 和 setTransform 结束时

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 2019-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 2022-06-30
  • 1970-01-01
相关资源
最近更新 更多