Oddness for own gluLookAt implementation
category: general [glöplog]
Hey,
I'm doing my own gluLookAt function for university and followed the recipe given at the gluLookAt documentation for making a pretty matrix with all the stuff I need. However, when I apply it, I don't get exactly the same result as with gluLookAt - everything is slightly further away.
Here's the code for the full example. Each frame switches between drawing a blue wire cube with my own lookAt function and the gluLookAt function. If you can spot the error it would be really nice.
I'm doing my own gluLookAt function for university and followed the recipe given at the gluLookAt documentation for making a pretty matrix with all the stuff I need. However, when I apply it, I don't get exactly the same result as with gluLookAt - everything is slightly further away.
Here's the code for the full example. Each frame switches between drawing a blue wire cube with my own lookAt function and the gluLookAt function. If you can spot the error it would be really nice.
Code:
/* 02561-02-00-2009.cpp*/
#include <windows.h>
#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
void initgl(void);
void display (void);
void axis (void);
void reshape (int w, int h);
int main (int argc, char** argv) {
glutInit (&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Exercise 02561-02");
initgl ();
glutDisplayFunc (display);
glutReshapeFunc (reshape);
glutIdleFunc (display);
glutMainLoop ();
return 0;
}
void initgl (void) {
glClearColor (0., 0., 0., 0.);
glShadeModel (GL_FLAT);
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//glOrtho (-6., 6., -6., 6., -6., 6.);
gluPerspective(90, (float)w/h, 0.1f, 100.f);
}
void lookAt(float eyex, float eyey, float eyez,
float orgx, float orgy, float orgz,
float upx, float upy, float upz)
{
//Calculate eye direction vector
float vpnx = orgx - eyex;
float vpny = orgy - eyey;
float vpnz = orgz - eyez;
//Normalize it
float len = sqrt(vpnx * vpnx + vpny * vpny + vpnz * vpnz);
vpnx /= len;
vpny /= len;
vpnz /= len;
//Calculate right vector
float rvx = vpny * upz - vpnz * upy;
float rvy = vpnz * upx - vpnx * upz;
float rvz = vpnx * upy - vpny * upx;
//Calculate new up vector
float nux = rvy * vpnz - rvz * vpny;
float nuy = rvz * vpnx - rvx * vpnz;
float nuz = rvx * vpny - rvy * vpnx;
//Put it all in a pretty Matrix
float mat[16] = {
rvx, nux, -vpnx, 0,
rvy, nuy, -vpny, 0,
rvz, nuz, -vpnz, 0,
0, 0, 0, 1
};
//Apply the matrix and translate to eyepoint
glMultMatrixf(mat);
glTranslatef(-eyex, -eyey, -eyez);
}
void display (void) {
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
static int i = 0;
if(i ^= 1) {
glColor3f (0,0,1);
lookAt(1, 1, 1, 0, 0, 0, 0, 1, 0);
}
else {
glColor3f (0,1.,0);
gluLookAt(1, 1, 1, 0, 0, 0, 0, 1, 0);
}
axis();
glRotatef((float)timeGetTime()/100, 0, 1, 0);
glutWireCube (1.);
glutSwapBuffers();
}
void axis (void) {
/*Plot part of axis and an auxiliary line*/
GLfloat v0[] = {0., 0., 0.};
GLfloat vx[]= {4., 0., 0.};
GLfloat vy[]= {0, 4., 0.};
GLfloat vz[]= {0., 0., 4.};
GLfloat v0x1[] = {1., 0., 0.};
GLfloat vyx1[] = {1., 3., 0.};
glPushAttrib(GL_CURRENT_BIT);
glColor3f (1., 0., 0.);
glBegin (GL_LINES);
glVertex3fv (v0);
glVertex3fv (vx);
glEnd ();
glBegin (GL_LINES);
glVertex3fv (v0);
glVertex3fv (vy);
glEnd ();
glBegin (GL_LINES);
glVertex3fv (v0);
glVertex3fv (vz);
glEnd ();
glBegin (GL_LINES);
glVertex3fv (v0x1);
glVertex3fv (vyx1);
glEnd ();
glPopAttrib();
}
Oh, and btw, I only did the lookAt function, all the bad code is not me.
You're at university.. you copied 80% of the code and implemented a recipe for the other 20%, and now your asking others to solve the problem..
On first glance, you should normalize the right vector as well before using it in cross product.
I get your point of view, but I'm not here because I want an easy road through uni, I'm here because I've actually been fiddling around with this little code snippet for way more time than I should and have starred myself dumbstruck on it.
My professor's teaching abilities are very limited, and I won't be seeing the assistant teachers (who are usually stressed in class) before wednesday. I solved the majority of the assignment, but I want to get to the bottom of it, and I have no idea where to look for a solution. I am just curious.
My professor's teaching abilities are very limited, and I won't be seeing the assistant teachers (who are usually stressed in class) before wednesday. I solved the majority of the assignment, but I want to get to the bottom of it, and I have no idea where to look for a solution. I am just curious.
Doh, thanks snoutmate.
(I forgot that | a cross b | == |a| * |b| only for right angles, bit embarassing)
Yeah. Normalization might help. Nice variable name "orgy" ;D
#include <vectormath.h>
(...)
Matrix4 m = Matrix4::lookAt(Vector(x,x,x), Vector(x,x,x), Vector(x,x,x));
glLoadMatrixf((float*)&m);
(...)
(...)
Matrix4 m = Matrix4::lookAt(Vector(x,x,x), Vector(x,x,x), Vector(x,x,x));
glLoadMatrixf((float*)&m);
(...)