0
votes

I have created a simple 2D area using OpenGL, comprised of tiles. These tiles have been stretched relative to the screen's aspect ratio by default. To fix this I have attempted to use an orthographic projection matrix. Here is how I created it:

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

The problem probably lies here but I just can't find it. I then call this method with the creation of my renderer, store it in a uniform variable and use it in the vertex shader like so:

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

Where projectionMatrix is a mat4 which corresponds to the previously created orthographic projection matrix.

Right now absolutely nothing except for the clear color renders.

EDIT:

The orthographic projection matrix is created and loaded into the shaders right after the renderer's creation and after the shader's creation.

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

The rest of the matrices are passed in at each render with the loadUniforms() method.

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

Finally this is what the vertex shader looks like:

#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
orthoMatrix.m00 = 2 / (r - 1)? Shouldn't that be (r - l) instead? 1 != l.genpfault
@genpfault Thanks for pointing that out! but the problem is still thereDylan Deshler
Time for a MCVE then.genpfault
What's the order of the elements in your matrix struct/class?Reto Koradi
If it rendered fine before, then you should now have a rendering of less than a pixel in size. Try to include a scaling factor in the matrix (multiply m00 and m11 by something big (e.g. 100) to see if that's the case). And you might neet to transpose the matrix (swap columns and rows). That's why @RetoKoradi wanted to see the matrix declaration.Nico Schertler

1 Answers

0
votes

It has been a long and arduous task (if I may sound incompetent myself). But I have found a solution to my problem, there is probably a better way to solve it, but this is how I did it.

I changed the createProjectionMatrix() to look like

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

Multiplying m00 and m11 by a large number is the only way I am able to see anything besides the clear color. If I remember this correctly, it is because the renderer is rendering at less than a pixel. This idea was presented to me by @NicoSchertler. So thank you very much! The shaders looks the same and now it runs well. If anyone has a less bootleg solution please share it, as I will be glad to see how it was solved. Here is a link that was very helpful to me, OpenGL 3+ with orthographic projection of directional light.