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<3; i++) {
e[i] += s*n[i];
}
}
if (key == 'W' || key == 'w') {
for (i=0; i<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 < 4; i++) {
a[i] = e[i] + n[i];
}
glLoadIdentity();
gluLookAt(e[0],e[1],e[2],a[0],a[1],a[2],v[0],v[1],v[2]);
```