# Projection Matrix Breaks My Rectangle

This is my vertex shader, shown below.

#version 330 core

in vec3 a_position;
in vec4 a_colour;

// FOV = 70, near plane = 0.1, far plane = 1000
const mat4 u_projection = mat4(
1.428148, 0.0, 0.0, 0.0,
0.0, 1.428148, 0.0, 0.0,
0.0, 0.0, -1.0001999, -0.20002,
0.0, 0.0, -1.0, 0.0
);

//uniform mat4 u_projection;
//uniform mat4 u_view;
uniform mat4 u_transformation;

out vec4 v_colour;

void main() {

gl_Position = u_projection * u_transformation * vec4(a_position, 1);
v_colour = a_colour;
}


Whenever I take out u_projection, my square appears. When I add it back, the square is malformed.

The vertices of my square are as follows, aka the contents of a_position.

float[] vertices = {
0, 0, 0.5f,
0.5f, 0.5f, 0.5f,
0, 0.5f, 0.5f,
0, 0, 0.5f,
0f, 0.5f, 0.5f,
0, 0.5f, 0.5f
};


The position of the square is (0, 0, 0), the rotation is (0, 0, 0) and the scale is 1. These are computed into u_transformation and uploaded. This works perfectly.

If I change the -1.0001999 and the last 0 to 1 part to 1 then the square is not hidden.

void bindAttribute(int index, String name) {
GL20.glBindAttribLocation(program, index, name);
}
bindAttribute(0, "a_position");
bindAttribute(1, "a_colour");

• what happens if you move the rectangle by + or -0.2 in x axis? Feb 27, 2016 at 10:31
• There's actually a bit more missing information. What aspect ratio did you use to calculate the projection matrix? Feb 27, 2016 at 10:42
• @wondra, imgur.com/a/BuOHw - first: x=0, second: x=0.2, third: x=-0.2, that's really strange! This is with the matrix applied. Feb 27, 2016 at 11:06
• @Nasser, the ratio is 500 / 800 pixels Feb 27, 2016 at 11:06
• The square is now malformed when the matrix is applied (as I wasn't doing it correctly before). Feb 27, 2016 at 11:06

First of all, there's something fishy about your vertices. If we write them out properly:

float[] vertices = {
0.0f, 0.0f, 0.5f, // (1)
0.5f, 0.5f, 0.5f, // (2)
0.0f, 0.5f, 0.5f, // (3)
0.0f, 0.0f, 0.5f, // (1)
0.0f, 0.5f, 0.5f, // (3)
0.0f, 0.5f, 0.5f  // (3)
};


You have only 3 distinct vertices, so if you are seeing a rectangle, then you need to call you GPU manufacturer! (or check your glVertexAttribPointer calls)

Your projection matrix doesn't look correct... I believe the reason your triangle (it's not a rectangle) is disappearing is that you are specifying your projection matrix in row-major order. The way you represented your matrix:

const mat4 u_projection = mat4(
1.428148, 0.0, 0.0, 0.0,
0.0, 1.428148, 0.0, 0.0,
0.0, 0.0, -1.0001999, -0.20002,
0.0, 0.0, -1.0, 0.0
);


Actually produces the following transformation matrix:

[1.428148, 0.0     , 0.0       ,  0.0 ]
[0.0     , 1.428148, 0.0       ,  0.0 ]
[0.0     , 0.0     , -1.0001999, -1.0 ]
[0.0     , 0.0     , -0.20002  ,  0.0 ]


This also implies that you are using an aspect ratio of 1.0, whereas you state in the comments that you have a 500x800 aspect ratio, but let's stick to this matrix for now. What you should have is:

const mat4 u_projection = mat4(
1.428148, 0.0, 0.0, 0.0,
0.0, 1.428148, 0.0, 0.0,
0.0, 0.0, -1.0001999, -1.0,
0.0, 0.0, -0.20002, 0.0
);


Notice that the -1.0 and the -0.20002 are swapped.

Now, let's multiply the transformation matrix by the coordinates of your triangle (again there are only 3), the clip-space coordinates we get are:

vertex (1): [0.0, 0.0, -0.70012, -0.5]

vertex (2): [0.714074, 0.714074, -0.70012, -0.5]

vertex (3): [0.0, 0.714074, -0.70012, -0.5]

Ah! We have a negative w value, and a more negative z value (-0.5 and -0.70012, respectively). This is because you placed your z-values at 0.5, when by OpenGL convention, in view space, the negative z axis points away from the viewer, so you should change those to -0.5, so that the triangle actually lies between your near and far clip planes.

So, let's say we do that, our unique vertices become:

float[] vertices = {
0.0f, 0.0f, -0.5f, // (1)
0.5f, 0.5f, -0.5f, // (2)
0.0f, 0.5f, -0.5f, // (3)
};


Now, your clip space coordinates become:

vertex (1): [0.0, 0.0, -0.3008, 0.5]

vertex (2): [0.714074, 0.714074, -0.3008, 0.5]

vertex (3): [0.0, 0.714074, -0.3008, 0.5]

Now, your triangle should be partially in your window; i.e., because vertices 2 and 3 are actually outside of clip space. Remember that, if you want your triangle to (at least partially) appear, then at least one if its coordinates has to have all x, y and z values between -w and +w. There are several things you can do to fix this, such as increasing your fov angle. It depends on what you want to do.

• I think his geometry was degenerate, so he looked for problems. Since his proj is wrong, someone suggested Transpose() which he tried and then hardcoded into the shader as a Row-Column-Row-Major matrix, LOL. So, by Transposing() it back to Row-Column-Row-Column-Major it "appears to work perfectly". I can't imagine how many different things he's tried.
– Jon
Feb 27, 2016 at 12:48
• @Jon, a lot of things! I've learnt what transposing is though. The hard coding was temporary and just to ask the question. Feb 27, 2016 at 13:02
• @Nasser, thanks a bunch. The killer actually was my glVertexAttribPointer calls. The 4 should have been a 3 for attribute size. After 3 hours, I will never forget that. Feb 27, 2016 at 16:03
• @Lolums, wow I was certain (again) it was going to be the first two really easy things and that glVertexAttribPointer wasn't relevant. Since I use DirectX, can you (or anyone) confirm if this is analogous to a DX InputLayout? Was the incorrect setting loading Point2's X into Point1's W?
– Jon
Feb 27, 2016 at 18:07
• @Lolums OpenGL is quite an awkward API, with subpar tools for debugging. I've found that the best way to learn is by making mistakes like this one Feb 27, 2016 at 18:21