OpenGL GLM camera matrix problem
Moderator: InsideQC Admins
8 posts
• Page 1 of 1
OpenGL GLM camera matrix problem
Hello everyone,
I am having a tad issue with updating the Quake renderer code to OpenGL 3.x+. The problem is the camera. I cannot use gluPerspective anymore so I'm using the GLM library. It works sort of, here is my code.
Also here is an image showing the problem.
http://i.imgur.com/8CskY.jpg
(the sky is to the left, and when I jump the camera moves to the right, at all times no matter the rotation)
The scene feels rotated by 90 degree's and the rotations feel like it's rotating around the player in a big arch.
I'd greatly appreciate any help, I've been stuck on this for a while. I feel like I'm missing something obvious.
I am having a tad issue with updating the Quake renderer code to OpenGL 3.x+. The problem is the camera. I cannot use gluPerspective anymore so I'm using the GLM library. It works sort of, here is my code.
 Code: Select all
projectionMatrix = glm::perspective(r_refdef.fov_y, (float)vid.width / (float)vid.height, 0.01f, 8192.0f);
viewTransMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(r_origin[2], r_origin[1], r_origin[0]));
viewRotMatrix = glm::rotate(viewTransMatrix, r_refdef.viewangles[0], glm::vec3(1.0f, 0.0f, 0.0f));
viewMatrix = glm::rotate(viewRotMatrix, r_refdef.viewangles[1], glm::vec3(0.0f, 1.0f, 0.0f));
modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
Also here is an image showing the problem.
http://i.imgur.com/8CskY.jpg
(the sky is to the left, and when I jump the camera moves to the right, at all times no matter the rotation)
The scene feels rotated by 90 degree's and the rotations feel like it's rotating around the player in a big arch.
I'd greatly appreciate any help, I've been stuck on this for a while. I feel like I'm missing something obvious.

Feared  Posts: 95
 Joined: Fri Jun 11, 2010 11:58 pm
 Location: Wylie, TX
Re: OpenGL GLM camera matrix problem
Feared wrote:Hello everyone,
I am having a tad issue with updating the Quake renderer code to OpenGL 3.x+. The problem is the camera. I cannot use gluPerspective anymore so I'm using the GLM library. It works sort of, here is my code.
 Code: Select all
projectionMatrix = glm::perspective(r_refdef.fov_y, (float)vid.width / (float)vid.height, 0.01f, 8192.0f);
viewTransMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(r_origin[2], r_origin[1], r_origin[0]));
viewRotMatrix = glm::rotate(viewTransMatrix, r_refdef.viewangles[0], glm::vec3(1.0f, 0.0f, 0.0f));
viewMatrix = glm::rotate(viewRotMatrix, r_refdef.viewangles[1], glm::vec3(0.0f, 1.0f, 0.0f));
modelMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
Also here is an image showing the problem.
http://i.imgur.com/8CskY.jpg
(the sky is to the left, and when I jump the camera moves to the right, at all times no matter the rotation)
The scene feels rotated by 90 degree's and the rotations feel like it's rotating around the player in a big arch.
I'd greatly appreciate any help, I've been stuck on this for a while. I feel like I'm missing something obvious.
Infos .... this may or may not be useful.
1) Quake uses Z for up and down, but OpenGL uses Z for depth. As a result, in R_SetupGL does a couple of rotations to effectively make Z go up and down and use Y for depth.
 Code: Select all
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glRotatef (90, 1, 0, 0); // put Z going up
glRotatef (90, 0, 0, 1); // put Z going up
2) "I cannot use gluPerspective" ... I'm not exactly sure what you mean there. You don't actually have to use that glu function. A "substitute" was included in the Q1 source ...
I'm not sure what you mean there though, it looks like the glm:Perspective is going to do the same thing.
 Code: Select all
void MYgluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
GLdouble xmin, xmax, ymin, ymax;
ymax = zNear * tan(fovy * M_PI / 360.0);
ymin = ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
glFrustum (xmin, xmax, ymin, ymax, zNear, zFar);
}
I don't know if any of the above information is useful to you. It does look from that screenshot you have the camera oriented the wrong way.
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't  well like that ever has stopped me before ..

Baker  Posts: 3666
 Joined: Tue Mar 14, 2006 5:15 am
Re: OpenGL GLM camera matrix problem
Baker wrote:1) Quake uses Z for up and down, but OpenGL uses Z for depth. As a result, in R_SetupGL does a couple of rotations to effectively make Z go up and down and use Y for depth.
2) "I cannot use gluPerspective" ... I'm not exactly sure what you mean there. You don't actually have to use that glu function. A "substitute" was included in the Q1 source ...[/code]
I don't know if any of the above information is useful to you. It does look from that screenshot you have the camera oriented the wrong way.
Your first bit of information was helpful.
The reason I am not using MYgluPerspective is because "glFrustum" is depreciated in OGL 3.x as well as "glRotate, glTranslate, etc".
I will try to do a similar rotation with GLM with Z. Thank you.

Feared  Posts: 95
 Joined: Fri Jun 11, 2010 11:58 pm
 Location: Wylie, TX
1: start with a view matrix all 0 except for [2]=1, [4]=1, [9]=1, [15]=1 instead of the regular identity matrix. that should correct your view matrix for quake's coord system
2: the problem is unlikely to be your perspective matrix. any weird/missing polys are more likely due to the y rotation of the view not being handled by the frustum code, resulting in culling  the culling is likely as correct as it was for regular glquake, fix the view matrix instead/first.
2: the problem is unlikely to be your perspective matrix. any weird/missing polys are more likely due to the y rotation of the view not being handled by the frustum code, resulting in culling  the culling is likely as correct as it was for regular glquake, fix the view matrix instead/first.
 Spike
 Posts: 2885
 Joined: Fri Nov 05, 2004 3:12 am
 Location: UK
The "Z going up" thing is in the modelview matrix so it's not relevant if we're talking projection.
Using a znear of 0.01f is a baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad idea. znear should be as high as you can tolerate going, otherwise you'll get really bad precision falloff in your depth calculations (as the final projected depth is nonlinear). Adjusting depth to linear in your vertex shader might look tempting (costs a few instructions but nothing earthshattering so far as Quake is concerned) but then you lose precision for nearby objects, which looks equally bad, if not worse.
So, I'm not 100% familiar with glm but some other things I can see going wrong here.
You're not actually adjusting for r_refdef.viewangles[2] anywhere here. OK, it's 0 or near 0 most of the time, but you need it for completeness.
Does glm::mat4(1.0f) do what you think it's doing?
Your translation has origin[0] and origin[2] swapped.
Anyway, concepts are the same and what's learned/used in one API can transfer to another so here we go.
Generally rather than load each of translate/rotate as separate matrixes, I would multiply them on top of each other. So you'd have:
Then just multiply the 3 for your final MVP which you'll send to your shader. That should work.
Note that I've put the player position into view but the Z going up into world; I just find this approach seems a little clearer as view is then exclusively used for player positioning; all other transforms (including entity transforms) can either go on world or can use their own matrixes. It also enables you to use the view matrix based solely on player position for fog calculations, which is neat.
You don't have to do it that way, in fact it generally doesn't matter which way (load them all onto projection if you wish, even) so long as you get the order correct and are consistent throughout your code.
Using a znear of 0.01f is a baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad idea. znear should be as high as you can tolerate going, otherwise you'll get really bad precision falloff in your depth calculations (as the final projected depth is nonlinear). Adjusting depth to linear in your vertex shader might look tempting (costs a few instructions but nothing earthshattering so far as Quake is concerned) but then you lose precision for nearby objects, which looks equally bad, if not worse.
So, I'm not 100% familiar with glm but some other things I can see going wrong here.
You're not actually adjusting for r_refdef.viewangles[2] anywhere here. OK, it's 0 or near 0 most of the time, but you need it for completeness.
Does glm::mat4(1.0f) do what you think it's doing?
Your translation has origin[0] and origin[2] swapped.
Anyway, concepts are the same and what's learned/used in one API can transfer to another so here we go.
Generally rather than load each of translate/rotate as separate matrixes, I would multiply them on top of each other. So you'd have:
 Code: Select all
projectionMatrix = glm::perspective(r_refdef.fov_y, (float)vid.width / (float)vid.height, 4.0f, 8192.0f); // note znear and fixme  does glm require that we make this identity first?
worldMatrix = glm::mat4(1.0f); // let's assume this sets to identity instead of loading 1 onto each component...
viewMatrix = glm::mat4(1.0f); // let's assume this sets to identity instead of loading 1 onto each component...
worldMatrix = glm::rotate(worldMatrix, 90, glm::vec3(1.0f, 0.0f, 0.0f)); // put Z going up
worldMatrix = glm::rotate(worldMatrix, 90, glm::vec3(0.0f, 0.0f, 1.0f)); // put Z going up
viewMatrix = glm::rotate(viewMatrix, r_refdef.viewangles[2], glm::vec3(1.0f, 0.0f, 0.0f));
viewMatrix = glm::rotate(viewMatrix, r_refdef.viewangles[0], glm::vec3(0.0f, 1.0f, 0.0f));
viewMatrix = glm::rotate(viewMatrix, r_refdef.viewangles[1], glm::vec3(0.0f, 0.0f, 0.1f));
viewMatrix = glm::translate(viewMatrix, glm::vec3(r_origin[0], r_origin[1], r_origin[2]));
Then just multiply the 3 for your final MVP which you'll send to your shader. That should work.
Note that I've put the player position into view but the Z going up into world; I just find this approach seems a little clearer as view is then exclusively used for player positioning; all other transforms (including entity transforms) can either go on world or can use their own matrixes. It also enables you to use the view matrix based solely on player position for fog calculations, which is neat.
You don't have to do it that way, in fact it generally doesn't matter which way (load them all onto projection if you wish, even) so long as you get the order correct and are consistent throughout your code.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for

mh  Posts: 2292
 Joined: Sat Jan 12, 2008 1:38 am
mh wrote:Using a znear of 0.01f is a baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad idea. znear should be as high as you can tolerate going, otherwise you'll get really bad precision falloff in your depth calculations (as the final projected depth is nonlinear). Adjusting depth to linear in your vertex shader might look tempting (costs a few instructions but nothing earthshattering so far as Quake is concerned) but then you lose precision for nearby objects, which looks equally bad, if not worse.
This is interesting, I'll look into adjusting it in the vertex shader.
mh wrote:Does glm::mat4(1.0f) do what you think it's doing?
No, but you've cleared that up.
Many thanks, MH for all the information. Also, thank you everyone else who posted. I learned a good amount from this thread.
Almost forgot: (I still have a few things to work on, as you can tell)

Feared  Posts: 95
 Joined: Fri Jun 11, 2010 11:58 pm
 Location: Wylie, TX
I think this is a really neat project you are doing. I wish you luck.
I like this kind of experimentation
I like this kind of experimentation
The night is young. How else can I annoy the world before sunsrise? Inquisitive minds want to know ! And if they don't  well like that ever has stopped me before ..

Baker  Posts: 3666
 Joined: Tue Mar 14, 2006 5:15 am
There's an article here: http://www.mvps.org/directx/articles/li ... inearz.htm about linear depth adjustment for D3D  and therefore HLSL  but it should be easy to port. I honestly wouldn't bother though; huge chunks of the view model and world geometry will drop out or invert their depth. If you want to try it as a learning experience by all means go ahead (I did), but don't set your heart on it.
I think this is an awesome project, and mirrors a lot of what I've been doing recently in DirectQ. One tip  get the basics of the Quake renderer done first before even trying to implement any fancy stuff.
I think this is an awesome project, and mirrors a lot of what I've been doing recently in DirectQ. One tip  get the basics of the Quake renderer done first before even trying to implement any fancy stuff.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
We knew the words, we knew the score, we knew what we were fighting for

mh  Posts: 2292
 Joined: Sat Jan 12, 2008 1:38 am
8 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 1 guest