Problem with orthographic projection (2D)

Hello, I’ve started learning openGL and got to the matrices part. I am trying to display meshes in the right aspect ratio (so they’re not stretched anymore) using glm::ortho but when I try to do this nothing is visible. When I pass an identity matrix instead of glm::ortho it does work. It also works when I only pass the transform matrix or no matrices at all.

here is the code

vertex shader:

#version 330 core

layout (location = 0) in vec2 aPos;
layout (location = 1) in vec3 aCol;
layout (location = 2) in vec2 aTexCoord;

out vec3 Color;
out vec2 TexCoord;

uniform mat4 Transform;
uniform mat4 Projection;

void main()
{
	gl_Position = Projection * Transform * vec4(aPos, 1.0, 1.0);
	Color = aCol;
	TexCoord = aTexCoord;
}

I have a Camera struct with a Viewport struct inside, and I update the windowWidth and height in an update loop:

struct Camera
{
	struct Viewport
	{
		int windowWidth = 500;
		int windowHeight = 500;

		float left{ 0 }, right{ 0 }, top{ 0 }, bottom{ 0 };
	};
	Viewport viewport;
	glm::vec2 position = glm::vec2(0, 0);

	void SetProjection()
	{
		viewport.left = -viewport.windowWidth * 0.5f;
		viewport.right = viewport.windowWidth * 0.5f;
		viewport.top = viewport.windowHeight * 0.5f;
		viewport.bottom = -viewport.windowHeight * 0.5f;

		projection = glm::mat4(1.0f);

                /* doesn't work when I uncomment this
		projection = glm::ortho(
			viewport.left + position.x,
			viewport.right + position.x,
			viewport.bottom + position.y,
			viewport.top + position.y,
			.1f, 1.f);
             */
	}

	glm::mat4 GetProjection()
	{
		return projection;
	}

private:
	glm::mat4 projection;
};

updating the resolution:

SDL_GL_GetDrawableSize(window, &camera.viewport.windowWidth, &camera.viewport.windowHeight);
glViewport(0, 0, camera.viewport.windowWidth, camera.viewport.windowHeight);

Thanks in advance!

This results in eye-space Z being limited to the range [-0.1,-1]. Using an identity matrix would result in the range being [-1,1]. Are eye-space Z coordinates negative? That’s fairly typical when using a perspective projection (conventionally, the positive Z axis is pointing out of the screen, so negative Z is in front of the viewer, positive Z is behind). A perspective projection cannot include the Z=0 plane (as it results in division by zero), so the near and far clip planes must both be on the same side of the viewpoint (i.e. Znear and Zfar must have the same sign). This isn’t an issue for orthographic projections; 2D rendering often has a Z range of [-1,1] with primitives drawn on the Z=0 plane.

The shader is forcing object-space Z to 1:

So unless the model-view matrix (Transform) is changing that, these coordinates will be outside of the clip volume.

Also, even if you replaced the projection matrix with an identity matrix, those coordinates will be on the edge of the clip volume, so you’re relying upon there being no rounding error whatsoever (that happens to be true in the case where all of the matrix elements are all 0.0, -1.0 or 1.0, but it’s unwise to rely upon it).

2D rendering typically uses an orthographic projection with a Z range of [-1,1] with primitive coordinates having Z=0 (so they’re right in the middle of the clip volume, not on the edge of it).

1 Like

wow thank you so much! I didn’t realize that was what the near and far plane did.