我编写了一个LWJGL3代码来在屏幕上渲染一个四边形.我甚至给它添加了投影矩阵,但我仍然看不到四边形的外观有任何变化.如果我改变锥体的视野,四边形会变小(这是我所期望的),但四边形仍然是矩形,尽管它应该是正方形!

下面是渲染器类:

    ShaderReader reader = new ShaderReader();
    Shader shader = null;
    Mesh mesh;
    
    private static final float FOV = 45f;
    private static final float Z_NEAR = 0.01f;
    private static final float Z_FAR = 1000f;
    private static Matrix4f projectionMatrix;
    
    float[] vertices = {
            -0.5f, 0.5f, -5.0f,
            -0.5f, -0.5f,-5.0f,
            0.5f, -0.5f, -5.0f,
            0.5f, 0.5f, -5.0f
    };
    
    int[] indices = {
            0,1,3,
            3,1,2
    };
    
    public void init(Window window) {
        GL11.glClearColor(.2f, .8f, 1f, 1f);
        shader = new Shader(reader);
        
        shader.createVertexShader(reader.readFile("shader.vs"));
        shader.createFragmentShader(reader.readFile("shader.fs"));
        
        shader.link();
        
        mesh = new Mesh(vertices, indices);
        
        float aspectRatio = 640 / 480;
        
        projectionMatrix = new Matrix4f();
        projectionMatrix.perspective((float) (Math.toRadians(FOV)), 1, Z_NEAR, Z_FAR);
    }
    
    public void clear() {
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
    }
    
    public void render() {
        clear();
        
        shader.bind();
        
        shader.setUniform("projectionMatrix", projectionMatrix);
        
        GL30.glBindVertexArray(mesh.getVaoID());
        GL20.glEnableVertexAttribArray(0);
        
        GL11.glDrawElements(GL11.GL_TRIANGLES, mesh.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);;
        
        GL20.glDisableVertexAttribArray(0);
        GL30.glBindVertexArray(0);
    }

下面是Shader类:

private int programID;
    private int vertexShaderID;
    private int fragmentShaderID;
    
    public Shader(ShaderReader reader) {
        programID = GL20.glCreateProgram();
        if (programID ==0)  {
            System.err.println("Error : Couldn't create program");
        }
    }
    
    public void createVertexShader(String shaderCode) {
        vertexShaderID = createShader(shaderCode, GL20.GL_VERTEX_SHADER);
    }
    
    public void createFragmentShader(String shaderCode) {
        fragmentShaderID = createShader(shaderCode, GL20.GL_FRAGMENT_SHADER);
    }
    
    private int createShader(String shaderCode, int type) {
        int shaderID = GL20.glCreateShader(type);
        if (shaderID == 0) {
            System.err.println("Error : Couldn't create shader");
        }
        
        GL20.glShaderSource(shaderID, shaderCode);
        GL20.glCompileShader(shaderID);
        
        if ((GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS)) != 1) {
            System.err.println("Error: Couldn't Compile Shader, " + GL20.glGetShaderInfoLog(shaderID));
        } 
        
        GL20.glAttachShader(programID, shaderID);
        
        return shaderID;
    }
    
    public void link() {
        GL20.glLinkProgram(programID);
        
        if ((GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS)) != GL11.GL_TRUE) {
            System.err.println("Error: Couldn't Link Program, " + GL20.glGetProgramInfoLog(programID, 1024));
        }
        
        if (vertexShaderID != 0) {
            GL20.glDetachShader(vertexShaderID, programID);
        }
        
        if (fragmentShaderID != 0) {
            GL20.glDetachShader(fragmentShaderID, programID);
        }
        GL20.glValidateProgram(programID);
        
        if ((GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS)) != GL11.GL_TRUE) {
            System.err.println("Error: Couldn't Validate Program, " + GL20.glGetProgramInfoLog(programID));
        }
        
        
    }
    
    public void setUniform(String name, Matrix4f mat) {
        int location = GL20.glGetUniformLocation(programID, name);
        FloatBuffer buffer = BufferUtils.createFloatBuffer(16);
        mat.get(buffer);
        GL20.glUniformMatrix4fv(location, false, buffer);
    } 
    
    public void bind() {
        GL20.glUseProgram(programID);
    }
    
    public void unBind() {
        GL20.glUseProgram(0);
    }

我的项目的源文件夹:https://www.dropbox.com/scl/fo/hwlnz913jm6c9xli2dsb6/h?dl=0&rlkey=b2zj0w6kttwu3b1di9rejwnq3

[渲染的四边形] (https://i.stack.imgur.com/H932c.jpg)

我首先使用JOML编程投影矩阵,还试图分别计算和放置矩阵中的值,但四边形显示为矩形而不是正方形,尽管当我更改FOV时大小发生了变化.请帮帮我!

推荐答案

您用于计算投影矩阵的代码有多个问题:

float aspectRatio = 640 / 480;
projectionMatrix = new Matrix4f();
projectionMatrix.perspective((float) (Math.toRadians(FOV)), 1, Z_NEAR, Z_FAR);

首先,除法640 / 480是一个integer除法,所以无论后来被赋给一个浮点变量,除法640 / 480总是恰好是1.

其次,在调用perspective的过程中,实际上并没有使用use这个变量.您只需在这里使用文字常量1作为参数.

因此,将长宽比的计算更改为(float) 640 / 480640f / 480,并实际使用aspectRatio变量作为perspective调用的第二个参数:

float aspectRatio = (float) 640 / 480;
projectionMatrix = new Matrix4f();
projectionMatrix.perspective((float) (Math.toRadians(FOV)), aspectRatio, Z_NEAR, Z_FAR);

Java相关问答推荐

如何跟踪我在数组中的位置

将linkedHashMap扩展到Java中的POJO类

为什么如果数组列表中有重复项,我的代码SOMETIMES不返回true?

使用包私有构造函数强制子类Java类

Mat. n_Delete()和Mat. n_release的区别

inteliJ中是否有一个功能可以自动在块注释中的/*后面添加一个空格?''

Java inline Double条件和值解装箱崩溃

如何修复IndexOutOfBoundsException在ClerView适配器的onRowMoved函数?

我无法获取我的Java Spring应用程序的Logback跟踪日志(log)输出

如何正确创建序列图?

由于我在Main方法中关闭了 scanner ,但在该方法中创建了一个新的 scanner ,因此出现了错误

如何使用带有谓词参数的方法,而不使用lambda表达式

使用UTC时区将startDatetime转换为本地时间

我可以在MacOS上使用什么Java函数来在适当的设备上以适当的音量播放适当的alert 声音?

SpringBoot Kafka自动配置-适用于SASL_PLAYTEXT的SSLBundle 包,带SCRAM-SHA-512

用OSQL创建索引

使用多个RemoteDatabase对象的一个线程

%This内置函数示例

在java中使用不同的application.properties-jar而不使用Spring

如何在右击时 Select 新行?