OpenGL 2D投影矩阵无法绘制任何内容。

3

我正在使用OpenGL进行2D渲染,并希望使用实际像素坐标。这意味着我希望(0,0)在窗口的左上角,而(宽度,高度)在窗口的右下角(其中宽度和高度是窗口的像素尺寸)。为了实现这一点,我使用glOrtho生成投影矩阵,然后将其传递给顶点着色器:

GL11.glViewport(0, 0, width, height);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glOrtho(0f, width, height, 0f, -1f, 1f);
GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, projectionBuffer);
GL11.glLoadIdentity();

我正在使用LWJGL,它没有glm的绑定,因此我使用上面的OpenGL调用获取一个2D正交矩阵。我重置了投影矩阵,以便它不会影响我后面的绘制调用。之后,projectionBuffer,一个FloatBuffer,被填充了由glOrtho生成的投影矩阵。

生成的投影矩阵如下(我不知道这是否有帮助):

0.0015625 0.0 0.0 1.0
0.0 -0.0027777778 0.0 -1.0
0.0 0.0 -1.0 0.0
0.0 0.0 0.0 1.0

我的顶点着色器如下:

#version 330 core

layout (location = 0) in vec4 vertex;

out vec2 TexCoords;

uniform mat4 model;
uniform mat4 projection = mat4(1.0);

void main()
{
    TexCoords = vertex.zw;
    gl_Position = projection * model * vec4(vertex.x, vertex.y, 0.0, 1.0);
}

当我初始化shader时,我使用glUniformMatrix4来设置投影矩阵的值。我确信这是成功完成的,因为当我使用glGetUniform时,它返回相同的投影矩阵。
每个纹理四边形被绘制时都会产生模型矩阵。每个四边形共享相同的顶点和UV,这些都存储在单个VBO中的同一个VAO中。顶点数据在绘制每个四边形时共享,不同的模型矩阵应用于每个四边形。正确计算模型矩阵以生成真实的屏幕坐标。例如,左上角位于(0,0),宽度/高度为128的正方形将产生以下模型矩阵:
128.0 0.0 0.0 0.0
0.0 128.0 0.0 0.0
0.0 0.0 1.0 0.0
0.0 0.0 0.0 1.0

使用glUniformMatrix4,成功向着色器传递了这个模型矩阵,并且我已经检查过了。

为了使用四边形的顶点数据来初始化共享的VAO,我使用以下代码:

vao = GL30.glGenVertexArrays();
int vbo = GL15.glGenBuffers();
GL30.glBindVertexArray(vao);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, QUAD_BUFFER, GL15.GL_STATIC_DRAW);

GL20.glEnableVertexAttribArray(0);
GL20.glVertexAttribPointer(0, 4, GL11.GL_FLOAT, false, 16, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);

QUAD_BUFFER 是包含顶点和纹理坐标数据的 float[]

最后,要绘制一个带有纹理的四边形,我使用以下代码:

shader.setMatrix4f("model", model);//Makes a call to glUniformMatrix4 - model is the model matrix as explained above.
GL13.glActiveTexture(GL13.GL_TEXTURE0);
texture.bind(); 
GL30.glBindVertexArray(vao);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, 6);

问题在于,当我运行应用程序时,窗口上没有绘制任何内容,它仍然保持完全黑色。如果不使用着色器,我可以使用旧方法(glBegin等)绘制形状。我无法弄清楚我做错了什么。
1个回答

1
我能够解决这个问题,非常感谢Java游戏论坛的某位用户。他向我指出,调用glOrtho会修改已加载的矩阵,因此在进行glOrtho调用之前,只需调用glLoadIdentity即可。现在,我已经转而使用glm的Java端口进行这些计算。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接