OpenGL正交矩阵无法正常工作

时间:2015-06-23 20:18:40

标签: opengl matrix 2d glsl orthographic

我使用OpenGL创建了一个简单的2D区域,由瓷砖组成。默认情况下,这些图块已相对于屏幕的纵横比进行拉伸。为了解决这个问题,我试图使用正交投影矩阵。以下是我创建它的方法:

public void createProjectionMatrix() {
    float left = 0;
    float right = DisplayManager.getScreenWidth();
    float top = 0;
    float bottom = DisplayManager.getScreenHeight();
    float near = 1;
    float far = -1;

    projectionMatrix.m00 = 2 / (r - l);
    projectionMatrix.m11 = 2 / (t - b);
    projectionMatrix.m22 = -2 / (f - n);
    projectionMatrix.m30 = - (r + l) / (r - l);
    projectionMatrix.m31 = - (t + b) / (t - b);
    projectionMatrix.m32 = - (f + n) / (f - n);
    projectionMatrix.m33 = 1;
}

这个问题可能就在这里,但我找不到它。然后我通过创建渲染器调用此方法,将其存储在一个统一变量中,并在顶点着色器中使用它,如下所示:

vec4 worldPosition = transformationMatrix * vec4(position, 0, 1);
gl_Position = projectionMatrix * viewMatrix * worldPosition;

其中projectionMatrix是mat4,它对应于先前创建的正交投影矩阵。

现在除了清晰的颜色外,什么都没有。

编辑:

创建正交投影矩阵并在渲染器创建后和着色器创建后立即加载到着色器中。

public Renderer() {
    createOrthoMatrix();
    terrainShader.start();
    terrainShader.loadProjectionMatrix(projectionMatrix);
    terrainShader.stop();
    GL11.glEnable(GL13.GL_MULTISAMPLE);
    GL11.glClearColor(0, 0, 0.5f, 1);
}

使用loadUniforms()方法在每个渲染中传入其余的矩阵。

for(Terrain t : batch) {
    loadUniforms(t, terrainManager, camera, lights);
    GL11.glDrawElements(GL11.GL_TRIANGLES, model.getModel().getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
}

private void loadUniforms(Terrain t, TerrainManager tm, Camera camera, List<Light> lights) {
    Matrix4f matrix = Maths.createTransformationMatrix(t.getPosition(), 0, 0, 0, 1);
    terrainShader.loadTransformationMatrix(matrix);
    terrainShader.loadViewMatrix(camera);
    terrainShader.loadNumberOfRows(tm.getNumberOfRows());
    terrainShader.loadOffset(t.getOffset());
    terrainShader.loadLights(lights);
}

最后这是顶点着色器的样子:

#version 400 core

in vec2 position;

uniform mat4 transformationMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

void main(void) {
vec4 worldPosition = transformationMatrix * vec4(position, 0, 1);
gl_Position = projectionMatrix * viewMatrix * worldPosition;
}

1 个答案:

答案 0 :(得分:0)

这是一项漫长而艰巨的任务(如果我自己听起来不称职)。但是我已经找到了解决问题的方法,可能有更好的方法来解决它,但这就是我做到的。

我将createProjectionMatrix()更改为

public void createProjectionMatrix() {
    float width = Display.getWidth();
    float height = Display.getHeight();
    float left = -width;
    float right = width * 1f;
    float top = height * 1f;
    float bottom = -height;
    float near = 0;
    float far = 10;

    projectionMatrix.m00 = (2f / (right - left)) * 1000;
    projectionMatrix.m11 = (2f / (top - bottom)) * 1000;
    projectionMatrix.m22 = 2f / (far - near);
    projectionMatrix.m30 = - (right + left) / (right - left);
    projectionMatrix.m31 = - (top + bottom) / (top - bottom);
    projectionMatrix.m32 = -(far + near) / (far - near);
    projectionMatrix.m33 = 1;
}

将m00和m11乘以大数是我能够看到除了清晰颜色之外的任何东西的唯一方法。如果我没记错,那是因为渲染器渲染的像素不到一个像素。这个想法是由@NicoSchertler呈现给我的。非常感谢你!着色器看起来一样,现在运行良好。如果有人有较少的盗版解决方案请分享,因为我很高兴看到它是如何解决的。这是一个对我很有帮助的链接OpenGL 3+ with orthographic projection of directional light