From my understanding,
gluLookAt(
eye_x, eye_y, eye_z,
center_x, center_y, center_z,
up_x, up_y, up_z
);
is equivalent to:
glRotatef(B, 0.0, 0.0, 1.0);
glRotatef(A, wx, wy, wz);
glTranslatef(-eye_x, -eye_y, -eye_z);
But when I print out the ModelView
matrix, the call to glTranslatef()
doesn't seem to work properly. Here is the code snippet:
#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;
static const int Rx = 0;
static const int Ry = 1;
static const int Rz = 2;
static const int Ux = 4;
static const int Uy = 5;
static const int Uz = 6;
static const int Ax = 8;
static const int Ay = 9;
static const int Az = 10;
static const int Tx = 12;
static const int Ty = 13;
static const int Tz = 14;
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat lmodel_ambient[] = { 0.8, 0.0, 0.0, 0.0 };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
}
void displayModelviewMatrix(float MV[16]) {
int SPACING = 12;
cout << left;
cout << "\tMODELVIEW MATRIX\n";
cout << "--------------------------------------------------" << endl;
cout << setw(SPACING) << "R" << setw(SPACING) << "U" << setw(SPACING) << "A" << setw(SPACING) << "T" << endl;
cout << "--------------------------------------------------" << endl;
cout << setw(SPACING) << MV[Rx] << setw(SPACING) << MV[Ux] << setw(SPACING) << MV[Ax] << setw(SPACING) << MV[Tx] << endl;
cout << setw(SPACING) << MV[Ry] << setw(SPACING) << MV[Uy] << setw(SPACING) << MV[Ay] << setw(SPACING) << MV[Ty] << endl;
cout << setw(SPACING) << MV[Rz] << setw(SPACING) << MV[Uz] << setw(SPACING) << MV[Az] << setw(SPACING) << MV[Tz] << endl;
cout << setw(SPACING) << MV[3] << setw(SPACING) << MV[7] << setw(SPACING) << MV[11] << setw(SPACING) << MV[15] << endl;
cout << "--------------------------------------------------" << endl;
cout << endl;
}
void reshape(int w, int h) {
float ratio = static_cast<float>(w)/h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, ratio, 1.0, 425.0);
}
void draw() {
float m[16];
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, m);
gluLookAt(
300.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f
);
glColor3f(1.0, 0.0, 0.0);
glutSolidCube(100.0);
glGetFloatv(GL_MODELVIEW_MATRIX, m);
displayModelviewMatrix(m);
glutSwapBuffers();
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 100);
glutCreateWindow("Demo");
glutReshapeFunc(reshape);
glutDisplayFunc(draw);
init();
glutMainLoop();
return 0;
}
No matter what value I use for the eye
vector:300, 0, 0
or0, 300, 0
or0, 0, 300
the translation vector is the same, which doesn't make any sense because the order of code is in backward order so glTranslatef
should run first, then the 2 rotations. Plus, the rotation matrix, is completely independent of the translation column (in the ModelView matrix), then what would cause this weird behavior?
Here is the output with the eye vector is (0.0f, 300.0f, 0.0f)
MODELVIEW MATRIX
--------------------------------------------------
R U A T
--------------------------------------------------
0 0 0 0
0 0 0 0
0 1 0 -300
0 0 0 1
--------------------------------------------------
I would expect the T
column to be (0, -300, 0)
! So could anyone help me explain this?
The implementation of gluLookAt
from http://www.mesa3d.org
void GLAPIENTRY
gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
GLdouble upz)
{
float forward[3], side[3], up[3];
GLfloat m[4][4];
forward[0] = centerx - eyex;
forward[1] = centery - eyey;
forward[2] = centerz - eyez;
up[0] = upx;
up[1] = upy;
up[2] = upz;
normalize(forward);
/* Side = forward x up */
cross(forward, up, side);
normalize(side);
/* Recompute up as: up = side x forward */
cross(side, forward, up);
__gluMakeIdentityf(&m[0][0]);
m[0][0] = side[0];
m[1][0] = side[1];
m[2][0] = side[2];
m[0][1] = up[0];
m[1][1] = up[1];
m[2][1] = up[2];
m[0][2] = -forward[0];
m[1][2] = -forward[1];
m[2][2] = -forward[2];
glMultMatrixf(&m[0][0]);
glTranslated(-eyex, -eyey, -eyez);
}
The position of the eye point. The position of the eye point. The position of the eye point. The position of the reference point.
first 3 parameters are camera position next 3 parameters are target position the last 3 parameters represent the rolling of camera.
The “up vector” has the same direction as the line-of-sight (which is a vector between the “eye” and the “center” point). For this case, the “same direction” includes both positive and negative directions.
If we let a rotation and translation matrix like your modelview matrix
Rxx Rxy Rxz Tx
Ryx Ryy Ryz Ty
Rzx Rzy Rzz Tz
0 0 0 1
act on an arbitrary vector
x
y
z
1
we get
Rxx x + Rxy y + Rxz z + Tx
Ryx x + Ryy y + Ryz z + Ty
Rzx x + Rzy y + Rzz z + Tz
1
(I'm writing things so vectors get multiplied by matrices on the left).
This shows that the translation components of the matrix give the translation to apply after doing the rotation. That's why they aren't the same as your (-eye_x, -eye_y, -eye_z) vector, because as you point out that translation is being done before the rotation.
The reason that the translation is always along the -z direction is because in the view frame the -z direction points towards the centre. Since you always have the centre 300 units from the eye, all of your eye positions put the centre at (0, 0, -300) in the view frame. Therefore, because the centre starts at the origin before we do any translating, the translation to give it the correct co-orindates must be (0, 0, -300).
Also, you might have noticed this, but the modelview matrix you show is pathological because you have the up vector pointing along the view direction (from eye to centre). That explains why it has two full rows of zeros.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With