A fly-through camera with an object in front?

Hi everyone,

I am pretty new to openGL, and I managed to get a fly-through camera to work. Now I have an issue with keeping a cylinder in front of the camera. The way my fly-through camera works is that I update the values in gluLookAt() accordingly, and it works fine. Then I try to translate the cylinder to the point that I’m looking at:

glPushMatrix();
glTranslatef(a[0], a[1], a[2]);
glPopMatrix();

(where a[0], a[1], a[2] are the 4th, 5th and 6th argument of gluLookAt()), and the cylinder only stays in front of the camera if I move forwards of backwards. The moment I do movements such as yaw and pitch, it distorts gets out of the picture. Can anyone help? Thank you.

The target position might be invalid, how do you compute this one?

I compute it by updating the look-at vector n[] and it works fine. In the beginning I declare the vectors, where u, v and n are the vectors representing the coordinate system of the camera:
GLfloat e[] = {0.0, 1.0, 1.0, 1.0};
GLfloat a[] = {0.0, 0.0, 0.0, 1.0};
GLfloat n[] = {0.0,0.0, 1.0, 0.0};
GLfloat v[] = {0.0, 1.0, 0.0, 0.0};
GLfloat u[] = {1.0, 0.0, 0.0, 0.0};

Then in the keyboard function I modify u, v and n accordingly:

// move with pitch
if (key == 'O' || key == 'o') {

xTemp = v[0];
yTemp = v[1];
zTemp = v[2];
v[0]=cos(alpha)*xTemp - sin(alpha)*n[0];
v[1]=cos(alpha)*yTemp - sin(alpha)*n[1];
v[2]=cos(alpha)*zTemp - sin(alpha)*n[2];
n[0]=sin(alpha)*xTemp + cos(alpha)*n[0];
n[1]=sin(alpha)*yTemp + cos(alpha)*n[1];
n[2]=sin(alpha)*zTemp + cos(alpha)*n[2];

}
if (key == 'K' || key == 'k') {

xTemp = v[0];
yTemp = v[1];
zTemp = v[2];
v[0]=cos(alpha)*xTemp + sin(alpha)*n[0];
v[1]=cos(alpha)*yTemp + sin(alpha)*n[1];
v[2]=cos(alpha)*zTemp + sin(alpha)*n[2];
n[0]=-sin(alpha)*xTemp + cos(alpha)*n[0];
n[1]=-sin(alpha)*yTemp + cos(alpha)*n[1];
n[2]=-sin(alpha)*zTemp + cos(alpha)*n[2];

}

// move with yaw
if (key == 'A' || key == 'a') {

xTemp = u[0];
yTemp = u[1];
zTemp = u[2];
u[0]=cos(alpha)*xTemp + sin(alpha)*n[0];
u[1]=cos(alpha)*yTemp + sin(alpha)*n[1];
u[2]=cos(alpha)*zTemp + sin(alpha)*n[2];
n[0]=-sin(alpha)*xTemp + cos(alpha)*n[0];
n[1]=-sin(alpha)*yTemp + cos(alpha)*n[1];
n[2]=-sin(alpha)*zTemp + cos(alpha)*n[2];

}

if (key == 'D' || key == 'd') {

xTemp = u[0];
yTemp = u[1];
zTemp = u[2];
u[0]=cos(alpha)*xTemp - sin(alpha)*n[0];
u[1]=cos(alpha)*yTemp - sin(alpha)*n[1];
u[2]=cos(alpha)*zTemp - sin(alpha)*n[2];
n[0]=sin(alpha)*xTemp + cos(alpha)*n[0];
n[1]=sin(alpha)*yTemp + cos(alpha)*n[1];
n[2]=sin(alpha)*zTemp + cos(alpha)*n[2];

}

// move forwards and backwards.

int s = 1;

int i;
if (key == 'S' || key == 's') {
for (i=0; i&lt;3; i++) {
e[i] += s*n[i];

}
}
if (key == 'W' || key == 'w') {
for (i=0; i&lt;3; i++) {
e[i] -= s*n[i];

}
}

Then in the display function I compute the a[] point by adding e[] to n[], and I update gluLookAt():

for (i = 0; i &lt; 4; i++) {
a[i] = e[i] + n[i];
}
gluLookAt(e[0],e[1],e[2],a[0],a[1],a[2],v[0],v[1],v[2]);

That looks correct at first sight.

I notice that you call glPushMatrix before translating your cylinder. What is the matrix state before pushing it? (<s>It should be equal to identity</s>).

So after I load the identity I call gluLookAt() with updated values:

gluLookAt(e[0],e[1],e[2],a[0],a[1],a[2],v[0],v[1],v[2]);

Then, I draw a rectangular box that I need (it’s in a display list), then I draw the particles generated by particleDisplay,
and after that, I draw the cylinder with its translation property; it’s the cylinder that I need to have in front of me as I fly around the world:

//rectangular box.
glPushMatrix();
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, none);
glCallList(BOX);
glPopMatrix();

//Particles...
glPushMatrix();
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS,  mat_shininess1);
particleDisplay();
glPopMatrix();

//Cylinder
glPushMatrix();
glTranslatef(a[0], a[1], a[2]);