I'm getting back into OpenGL graphics programming and I'm having trouble with projection matrices when it comes to the z near and z far values. They don't work how I thought they would, so I think I'm doing something wrong.
Starting off simple I have a default out of the box OpenGL 3.3 context. I am drawing a red square using a vertex buffer / index buffer and I am passing a single matrix setup as a orthographic projection to my shaders that acts as the MVP matrix.
The red square does show on the screen. BUT I have some major confusion about the z near and z far values needed in the ortho matrix and their relationship to vertices.
When I create my ortho matrix I set the z near as 0.0f and the z far as 1.0f
mvp.toOrtho(800.0f, 600.0f, 0.0f, 1.0f);
So I expect that my “camera” is at x: 0, y: 0, z: 0 and is looking down the Z axis. Where Z gets more negative as you go further (Right Hand Coord System). I also expect anything outside of a 0.0f to 1.0f range (0.0f to -1.0f z index) will not be visible on the screen,
Now, when my red square's vertices have the Z index set to a value between 0.0f and -1.0f it will show on the screen. If the Z index is a value of -2.0f and lower nothing shows on the screen. Which makes sense, because the direction of the “camera” is looking down the Z axis where further out is a more negative Z value.
However, if I set the Z index value of my vertices to a 1.0f value I still see the red square on the screen. Why is this happening? Wouldn't the red square be “off screen” or behind the camera because it has a Z index of 1.0f?
Just as a FYI, setting the value to 2.0f, so 100% outside of the z near / z far range, the red square does not show.
What am I doing wrong? Or what am I missing?
Implementation of my Ortho Matrix
void Matrix4::toOrtho(float viewWidth, float viewHeight, float zNear, float zFar) {
//Col 1
data[0] = 2.0f / viewWidth;
data[1] = 0.0f;
data[2] = 0.0f;
data[3] = 0.0f;
//Col 2
data[4] = 0.0f;
data[5] = 2.0f / viewHeight;
data[6] = 0.0f;
data[7] = 0.0f;
//Col 3
data[8] = 0.0f;
data[9] = 0.0f;
data[10] = 1.0f / (zNear - zFar);
data[11] = 0;
//Col 4
data[12] = 0.0f;
data[13] = 0.0f;
data[14] = zNear / (zNear - zFar);
data[15] = 1.0f;
}
Data in my buffer
//With Index bufffer
float size = 64.0f;
float zIndex = 1.0f;
vertices[0] = 0.0f;
vertices[1] = 0.0f;
vertices[2] = zIndex;
vertices[3] = size;
vertices[4] = 0.0f;
vertices[5] = zIndex;
vertices[6] = 0.0f;
vertices[7] = size;
vertices[8] = zIndex;
vertices[9] = size;
vertices[10] = size;
vertices[11] = zIndex;
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 1;
indices[4] = 3;
indices[5] = 2;
Vertex Shader
#version 330 core
layout(location = 0) in vec3 pos;
uniform mat4 MVP;
void main() {
gl_Position = MVP * vec4(pos.x, pos.y, pos.z, 1.0);
}