Reputation: 4655
I just got a new PC and now have to get my demo program running with SDL2/OpenGL. I used the program to try out various techniques and used gluLookAt (which, obviously, shouldn't be used any more or even never should have been used).
Now I'm looking for a way to replace the gluLookAt method by building a transformation matrix doing the same as gluLookAt did. I came across this claiming to be usable replacement for gluLookAt (the answer - not the question).
My implementation of it looks like this (I assume j ^ k
means the cross product of j and k - correct me if I'm wrong):
//Compat method: gluLookAt deprecated
void util_compat_gluLookAt(GLfloat eyeX, GLfloat eyeY, GLfloat eyeZ, GLfloat lookAtX, GLfloat lookAtY, GLfloat lookAtZ, GLfloat upX, GLfloat upY, GLfloat upZ) {
Vector3f up (upX, upY, upZ);
Vector3f lookAt (-lookAtX, -lookAtY, -lookAtZ);
Vector3f eye (eyeX, eyeY, eyeZ);
Vector3f i = up ^ lookAt;
Matrix4x4 mat (new GLfloat[16]
{i.getX(), upX, lookAt.getX(), 0,
i.getY(), upY, lookAt.getY(), 0,
i.getZ(), upZ, lookAt.getZ(), 0,
0, 0, 0, 1});
Vector3f translate = mat * (Vector3f()-eye); // Not yet correctly implemented: Negative of vector eye ([0,0,0]-[eyeX,eyeY,eyeZ])
mat.setItem(3,0,translate.getX());
mat.setItem(3,1,translate.getX());
mat.setItem(3,2,translate.getX());
glMultMatrixf(mat.transpose().getComponents());
}
Who did the wrong stuff - my source of information or me? And how can I fix this? NOTE: I won't use this in my actual project, but I still need it for my demo program which will also be reviewed for grading.
Upvotes: 2
Views: 2202
Reputation: 8272
I tried the solution above and found it didn't really work. This page describes the calculations, and when I followed that closely it worked nicely. Like one of the comments above, I also thought it would ok to put the translation into the matrix instead of using a separate glTranslate afterward, but it just didn't work. I'm sure the authors of that page would also have put the translation into the matrix if that was a viable approach.
https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/gluLookAt.xml
void my_gluLookAt(GLfloat eyeX, GLfloat eyeY, GLfloat eyeZ, GLfloat lookAtX, GLfloat lookAtY, GLfloat lookAtZ, GLfloat upX, GLfloat upY, GLfloat upZ) {
vec3 F = vec3(lookAtX - eyeX, lookAtY - eyeY, lookAtZ - eyeZ);
vec3 UP = vec3(upX, upY, upZ);
F.Normalize();
UP.Normalize();
vec3 s = cross(F, UP);
vec3 u = cross(s, F);
float m[16] = {
s.x, u.x, -F.x, 0,
s.y, u.y, -F.y, 0,
s.z, u.z, -F.z, 0,
0, 0, 0, 1
};
glMultMatrixf(m);
glTranslatef(-eyeX, -eyeY, -eyeZ);
}
Upvotes: 0
Reputation: 4655
I just had the idea to implement the gluLookAt compatibility method like gluLookAt is implemented in an older version of Mesa3D: (glu.c of Mesa3D 3.2)
Now it looks as below and works:
//Compat method: gluLookAt deprecated
void util_compat_gluLookAt(GLfloat eyeX, GLfloat eyeY, GLfloat eyeZ, GLfloat lookAtX, GLfloat lookAtY, GLfloat lookAtZ, GLfloat upX, GLfloat upY, GLfloat upZ) {
Vector3f x, y, z;
z = Vector3f(eyeX-lookAtX, eyeY-lookAtY, eyeZ-lookAtZ).normalize();
y = Vector3f(upX, upY, upZ);
x = y ^ z;
y = z ^ x;
x = x.normalize();
y = y.normalize();
// mat is given transposed so OpenGL can handle it.
Matrix4x4 mat (new GLfloat[16]
{x.getX(), y.getX(), z.getX(), 0,
x.getY(), y.getY(), z.getY(), 0,
x.getZ(), y.getZ(), z.getZ(), 0,
-eyeX, -eyeY, -eyeZ, 1});
glMultMatrixf(mat.getComponents());
}
I know this is a way OpenGL is not used today, but somehow all tutorials seem to use gluLookAt
and therefore convey the existence of a camera in OpenGL. I still have to get rid of this point of view about OpenGL myself...
Upvotes: 4