View Full Version : Projection not working as expected

07-26-2014, 11:15 PM
In order to not use any deprecated functions and to learn I'm trying to make my own matrices, but my projection matrix is causing my drawing to disappear. I've tried looking this up and my projection matrix looks consistent with everything I've found, and the z coordinates of my triangle are within the near/far clipping values I made the matrix with. I suspect that I am misunderstanding something about clipping, any advice would really be appreciated.

My projection matrix code:
This is row major but I do set transpose to true in glUniformMatrix4fv, so that's not the problem.

void Camera::makeProjectionMatrix(float FoV, float aspectRatio, float nearClip, float farClip){
float d = 1.0f / ( tanf(FoV*radiansPerDegree/2) );
projectionMatrix[0] = d / aspectRatio;
projectionMatrix[5] = d;
projectionMatrix[10] = (nearClip + farClip) / (nearClip - farClip);
projectionMatrix[11] = (2 * nearClip*farClip) / (nearClip - farClip);
projectionMatrix[14] = -1.0f;
projectionMatrix[15] = 0.0f;

My shader, which works fine if I remove the projection multiplication:

"#version 330\n"
"layout(location = 0)"
"in vec4 position;"
"uniform mat4 P;"
"void main(){"
"gl_Position = P * position;"

Finally here's my parameters and a before and after of a vertex multiplied by the matrix. I might have the aspect ratio inverted but I've tried both ways and that doesn't seem to help.

makeProjectionMatrix(70.0f, 640.0f/480.0f, 0.10f, 10.0f);

//My triangle
VBO.add(0.6f, 0.6f, 1.0f);
VBO.add(0.2f, 0.6f, 1.0f);
VBO.add(0.6f, 0.2f, 1.0f);

//Coordinates of an unprojected verticie
(0.60, 0.60, 1.00, 1.00)
//Projected coordinates
(0.643, 0.857, -1.222, -1.00)

So my projected w is -Z which gives me confidence in the matrix. I don't understand why z has become negative. The values I've used don't seem like they should be clipped to me but that's the only problem I can imagine going on here. Any advice would be great.

Dan Bartlett
07-27-2014, 02:47 AM
I'd recommend using the OpenGL Mathematics (http://glm.g-truc.net/0.9.5/index.html) library rather than re-implementing everything, it's easy to get started with and you could just use:

glm::mat4 Projection = glm::perspective(70.0f, 640.0f / 480.0f, 0.10f, 10.0f);
Looking at the glm::perspective code, it seems to use fov in the y-direction (like gluPerspective does), so has the [0] and [5] terms reversed compared to yours but otherwise appears the same.

I think the default OpenGL camera direction is facing in the -Z direction, so (0.6f, 0.6f, 1.0f) would be behind you unless you re-orientate the camera.

I also assume you're setting the other terms to 0 correctly elsewhere?

07-27-2014, 05:51 AM
I doubly agree with Dan here. 3rd party libraries will help you solve many mundane problems so you can focus on learning how to use elements, then go back and mess with them later.

From the man pages on gluPerspective (http://www.manpagez.com/man/3/gluPerspective/) it looks like your Matrix should look like:

Given f defined as follows:

f = cotangent(fovy/2)

The generated matrix is
------------ 0 0 0

0 f 0 0

zFar+zNear 2*zFar*zNear
0 0 ---------- ------------
zNear-zFar zNear-zFar

0 0 -1 0
. OpenGL uses "column major" ordering, with 0-3 being the first column, 4-7 the second, etc., so it looks like your indices of [11] and [14] need to be swapped.

07-27-2014, 03:57 PM
Thanks I was aware of glm I just wanted to avoid it since I think this was a learning opportunity. My matrices are all zeroed properly (I was just initializing them as identity) and I do transpose while setting the uniform variable to get column major. I have also tried negative Z values but still nothing renders. I'll definitely try glm but I'm still disappointed.

EDIT: Got it working, glm is also working great thanks for the advice. But I was calling the uniform functions with no program bound.