Reputation: 6086
I'm trying to create a simple Camera class for OpenGL using C++. So it basically uses the following functions:
void setModelviewMatrix () {
float m[16];
Vector3 eVec(eye.x, eye.y, eye.z);
m[0]=u.x; m[4]=u.y; m[8]=u.z; m[12]=-eVec.dotProduct(u);
m[1]=v.x; m[5]=v.y; m[9]=v.z; m[13]=-eVec.dotProduct(v);
m[2]=n.x; m[6]=n.y; m[10]=n.z; m[14]=-eVec.dotProduct(n);
m[3]=0; m[7]=0; m[11]=0; m[15]=1.0;
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(m);
}
void set (Point3 newEye, Point3 newLook, Vector3 newUp) {
eye.set(newEye);
n.set(eye.x-newLook.x, eye.y-newLook.y, eye.z-newLook.z);
u.set(newUp.crossProduct(n));
n.normalize();
u.normalize();
v.set(n.crossProduct(u));
setModelviewMatrix();
}
void setShape (float vAng, float asp, float nearD, float farD) {
viewAngle = vAng;
aspect = asp;
nearDist = nearD;
farDist = farD;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(viewAngle, aspect, nearDist, farDist);
}
So I tested it by replacing the working standard camera setup (see below) with my new camera setup (below as well). From my point of view, the new setup does exactly the same thing as the old one. But still, the result is different: With the new setup the only thing I can see is a blank white screen and not the object that was displayed before. Why is that?
Old camera setup (working):
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-64/48.0, 64/48.0, -1.0, 1.0, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(2.3, 1.3, 2, 0, 0.25, 0, 0, 1, 0);
New setup (not working):
Point3 eye = Point3(2.3, 1.3, 2);
Point3 look = Point3(0, 0.25, 0);
Vector3 up = Vector3(0, 1, 0);
cam.setShape(30.0f, 64.0f/48.0f, 0.1f, 100.0f);
cam.set(eye, look, up);
Upvotes: 0
Views: 2130
Reputation: 6086
Sorry, the problem had nothing to do with the implementation of these methods. It was actually a problem with Visual Studio. As I switched from C to C++ and I didn't change the setup, the problem was caused by that. I tried implementing the camera functions in C and it worked. Thanks for your help, though.
Upvotes: 0
Reputation: 43359
You have forgotten that OpenGL uses column-major matrices. Assuming those are basis vectors, they should each span a column instead of row. This is the layout that OpenGL uses for matrices when stored in memory:
http://i.msdn.microsoft.com/dynimg/IC534287.png
void setModelviewMatrix () {
GLfloat m[16];
m[0]=u.x; m[4]=v.x; m[ 8]=n.x; m[12]=eye.x;
m[1]=u.y; m[5]=v.y; m[ 9]=n.y; m[13]=eye.y;
m[2]=u.z; m[6]=v.z; m[10]=n.z; m[14]=eye.z;
m[3]=0.0f; m[7]=0.0f; m[11]=0.0f; m[15]=1.0f;
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(m);
}
You are free to use whatever memory layout you want if your matrix class does all of the calculations, but the second you pass a matrix to OpenGL it expects a particular layout. Even if you are using shaders, OpenGL expects matrix uniforms to be column-major by default.
Upvotes: 3