Here is the code I use; may not do everything you want for example its not flight sim type of movement but it does allow you to move around on a horizontal plane, you change elevation with pageup/pagedown keys - sort works like an elevator.
The first part is the function itself, the second part is the code that is in my rendering thread. This stuff comes from OpenGL Superbible. Have fun!
void UpdatePosition(struct CAMERA *pCamera)
{
float fLinearVelocity = 0.0f;
float fAngularVelocityY = 0.0f;
float fAngularVelocityX = 0.0f;
float fAngularVelocityZ = 0.0f;
float fTime=0;
float fXDelta=0;
float fAngle=0;
float fZDelta= 0;
double fSeconds=0;
float elevation = 0.0f;
LARGE_INTEGER currentTime;
// Keyboard Input
// Check for forward or backwards Motion
if(GetAsyncKeyState(VK_UP))
fLinearVelocity = 6.0f;
if(GetAsyncKeyState(VK_DOWN))
fLinearVelocity = -6.0f;
// check for elevation
if(GetAsyncKeyState(VK_NEXT))
elevation = 0.25f;
if(GetAsyncKeyState(VK_PRIOR))
elevation = -0.25f;
// Check for spin left/right (Y Axis rotation)
if(GetAsyncKeyState(VK_LEFT))
fAngularVelocityY = -45.0f;
if(GetAsyncKeyState(VK_RIGHT))
fAngularVelocityY = 45.0f;
// Check for looking up and down
if(GetAsyncKeyState(0x41)) // A key
fAngularVelocityX = -9.50f;
if(GetAsyncKeyState(0x5a)) // Z key
fAngularVelocityX = 9.50f;
// Adjust position and orientation. Get the time since the last
// check. If the velocity = 0 (no keypress or mouse movement)
// then the motion will be nil...
// D = vt
QueryPerformanceCounter(¤tTime);
fTime = (float)(currentTime.QuadPart - lastTime.QuadPart)/
(float)timerFrequency.QuadPart;
lastTime = currentTime;
fSeconds = (double)(currentTime.QuadPart - globeTime.QuadPart)/
(double)timerFrequency.QuadPart;
// Update Rotation angles (clamp the X rotation)
fAngle = fTime * fAngularVelocityX;
fAngle += pCamera->orientation[0];
if((fAngle < 90.0f) && (fAngle > -90.0f))
pCamera->orientation[0] = fAngle;
pCamera->orientation[1] += fTime * fAngularVelocityY;
// Update linear position
fTime = fTime * fLinearVelocity;
fXDelta = fTime * (float)(sin(DEGTORAD(pCamera->orientation[1])));
fXDelta += pCamera->position[0];
fZDelta = fTime * (float)(cos(DEGTORAD(pCamera->orientation[1])));
fZDelta += pCamera->position[2];
pCamera->position[1] += elevation;
pCamera->position[0] = fXDelta;
pCamera->position[2] = fZDelta;
// Halt the camera at the boundaries of the Virtual World.
if(pCamera->position[1] > 40.0f)
pCamera->position[1] = 40.0f;
if(pCamera->position[0] > 100.0f)
pCamera->position[0] = 100.0f;
if(pCamera->position[0] < -100.0f)
pCamera->position[0] = -100.0f;
if(pCamera->position[2] > 100.0f)
pCamera->position[2] = 100.0f;
if(pCamera->position[2] < -100.0f)
pCamera->position[2] = -100.0f;
}
// end of updatecamerpostition
** rendering thread code
UpdatePosition(&cameraData);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(cameraData.orientation[0], 1.0f, 0.0f, 0.0f); // look up, down
glRotatef(cameraData.orientation[1], 0.0f, 1.0f, 0.0f); // turn
glRotatef(cameraData.orientation[2], 0.0f, 0.0f, 1.0f); // advance/retreat
glTranslatef(-cameraData.position[0],cameraData.position[1], cameraData.position[2]);
RenderScene();