Reputation: 120
I'm implementing a renderer that handles every translation- / view- / model- / projection-matrix (I don't use glRotate / glTranslate etc.).
I have placed several blue objects along the positive z-axis and some red objects on the positive x-axis (So I should be able to see the red objects to my left and the blue ones straight ahead using identity rotation on my camera). It is right-hand-orientation, right?
The problem is that I have to turn 180 deg around the y-axis to see my objects. It appears as the identity rotation is looking in -z.
I'm constructing my View matrix by taking the inverse of the cameras matrix [Rot Tr] and then I put it in a array column-wise and pass it to my shader.
For the objects (World matrix) I just pass the matrix [Rot Tr] column-wise to the shader. Should I negate the translation?
The projection matrix is for now constructed in the vertex shader as I am working my way through. As you can se below I'm doing
position = proj*view*model*gl_Vertex;
At the moment I use gl_Vertex (I use glutSolidCube after loading identity matrix as my scene objects).
uniform mat4 view;
uniform mat4 model;
varying vec4 pos;
void main()
{
pos = gl_Vertex;
float aspect = 1.0;
float fovy = 1.5;
float f = 1.0 / tan(fovy * 0.5);
float near = 1.0;
float far = 100.0;
float tt = 1.0 / (near - far);
mat4 proj = mat4(f/aspect, 0.0, 0.0, 0.0,
0.0, f, 0.0, 0.0,
0.0, 0.0, (near+far)*tt, -1.0,
0.0, 0.0, 2.0*near*far*tt, 0.0);
gl_Position = proj * view * model * pos;
}
In my fragment shader I set the color = pos so that I can see the color of the axis and the colors appears correct. I think the objects are correctly placed in the scene but with Identity matrix as rotation I'm still looking the opposite way.
What could I have missed? Am I passing the correct matrices in a correct manner?
Upvotes: 1
Views: 4141
Reputation: 470
Alright completely rewrote this last night and I hope you find it useful if you haven't already came up with your own solutions or someone else who comes along with a similar question.
By default your forward vector looks down the -Z, right vector looks down the +X, and up vector looks down the +Y.
When you decide to construct your world it really doesn't matter where you look if you have a 128x128 X,Z world and you are positioned in the middle at 64x64 how would any player know they are rotated 0 degrees or 180 degrees. They simply would not.
Now you mentioned you dislike the glRotatef and glTranslatef. I as well will not use methods that handle the vector and matrix math. Firstly I use a way where I keep track of the Forward, Up, and Right Vectors. So imagine yourself spinning around in a circle this is you rotating your forward vector. So when a player wants to let's say Run Straight ahead. you will move them along the X,Z of your Forward vector, but let's say they also want to strafe to the right. Well you will still move them along the forward vector, but imagine 90 degrees taken off the forward vector. So if we are facing 45 degrees we are pointing to the -Z and -X quadrant. So strafing will move us in the -Z and +X quadrant. To do this you simple do negate the sin value. Examples of both below, but this can be done differently the below is rough example to better explain the above.
Position.X -= Forward.X; //Run Forward.
Position.Z -= Forward.Z;
Position.X += Forward.Z; //Run Backwards.
Position.Z += Forward.Z
Position.X += Forward.X; //Strafe Right.
Position.Z -= Forward.Z;
Position.X -= Forward.X; //Strafe Left.
Position.Z += Forward.Z;
Below is how I initialize my view matrix. These are to only be performed one time do not put this in any looping code.
glMatrixMode(GL_MODELVIEW);
view_matrix[4] = 0.0f; //UNUSED.
view_matrix[3] = 0.0F; //UNUSED.
view_matrix[7] = 0.0F; //UNUSED.
view_matrix[11] = 0.0F; //UNUSED.
view_matrix[15] = 1.0F; //UNUSED.
update_view();
glLoadMatrix(view_matrix);
Then this is the update_view() method. This is to only to be called during a change in the view matrix.
public void update_view()
{
view_matrix[0] = Forward[0];
view_matrix[1] = Up[1] * Forward[1];
view_matrix[2] = Up[0] * -Forward[1];
view_matrix[5] = Up[0];
view_matrix[6] = Up[1];
view_matrix[8] = Forward[1];
view_matrix[9] = Up[1] * -Forward[0];
view_matrix[10] = Up[0] * Forward[0];
}
The Position vectors are matricies [12], [13], and [14] and are negated. You can choose to store these or just use matrix[12], [13], [14] as the vector for position.
view_matrix[12] = -Position.x;
view_matrix[13] = -Position.y;
view_matrix[14] = -Position.z;
Upvotes: 0
Reputation: 162164
The problem is that I have to turn 180 deg around the y-axis to see my objects. It appears as the identity rotation is looking in -z.
Yes it is. The coordinate systems provided yb OpenGL in form for glOrtho and glFrustum are right handed (take your right hand, let the thumb towards the right, the index finger up, then the index finger will point toward you). If you modeled your matrix calculations along those, then you'll get a right handed system as well.
Upvotes: 0
Reputation: 473212
A right-handed coordinate system always looks down the -Z axis. If +X goes right, and +Y goes up (which is how all of OpenGL works), and the view is aligned to the Z axis, then +Z must go towards the viewer. If the view was looking down the +Z axis, then the space would be left-handed.
Upvotes: 2