So I've been having trouble with a camera I've implemented in OpenGL and C++ using the GLM library. The type of camera I'm aiming for is a fly around camera which will allow easy exploration of a 3D world. I have managed to get the camera pretty much working, it's nice and smooth, looks around and the movement seems to be nice and correct.

The only problem I seem to have is that the rotation along the camera's X and Y axis (looking up and down) introduces some rotation about it's Z axis. This has the result of causing the world to slightly roll whilst travelling about.

As an example... if I have a square quad in front of the camera and move the camera in a circular motion, so as if looking around in a circle with your head, once the motion is complete the quad will have rolled slightly as if you've tilted your head.

My camera is currently a component which I can attach to an object/entity in my scene. Each entity has a "Frame" which is basically the model matrix for that entity. The Frame contains the following attributes:

glm::mat4 m_Matrix; glm::vec3 m_Position; glm::vec3 m_Up; glm::vec3 m_Forward;

These are then used by the camera to create the appropriate viewMatrix like this:

const glm::mat4& CameraComponent::GetViewMatrix() { //Get the transform of the object const Frame& transform = GetOwnerGO()->GetTransform(); //Update the viewMatrix m_ViewMatrix = glm::lookAt(transform.GetPosition(), //position of camera transform.GetPosition() + transform.GetForward(), //position to look at transform.GetUp()); //up vector //return reference to the view matrix return m_ViewMatrix; }

And now... here are my rotate X and Y methods within the Frame object, which I'm guessing is the place of the problem:

void Frame::RotateX( float delta ) { glm::vec3 cross = glm::normalize(glm::cross(m_Up, m_Forward)); //calculate x axis glm::mat4 Rotation = glm::rotate(glm::mat4(1.0f), delta, cross); m_Forward = glm::normalize(glm::vec3(Rotation * glm::vec4(m_Forward, 0.0f))); //Rotate forward vector by new rotation m_Up = glm::normalize(glm::vec3(Rotation * glm::vec4(m_Up, 0.0f))); //Rotate up vector by new rotation } void Frame::RotateY( float delta ) { glm::mat4 Rotation = glm::rotate(glm::mat4(1.0f), delta, m_Up); //Rotate forward vector by new rotation m_Forward = glm::normalize(glm::vec3(Rotation * glm::vec4(m_Forward, 0.0f))); }

So somewhere in there, there's a problem which I've been searching around trying to fix. I've been messing with it for a few days now, trying random things but I either get the same result, or the z axis rotation is fixed but other bugs appear such as incorrect X, Y rotation and camera movement.

I had a look at gimbal lock but from what I understood of it, this problem didn't seem quite like gimbal lock to me. But I may be wrong.