I'm trying to implement a camera all by myself in OpenGL (I use glfw and gml). As for now, I don't have any class for it. I will create it later. So here is my try on coding the camera movements; it works fine with simple mouse movements, but otherwise, the camera tilts sideways. I'm still new to OpenGL so I don't have a lot to show but here is illustrated my problem: http://imgur.com/a/p9xXQ
I have a few (global as for now) variables :
float lastX = 0.0f, lastY = 0.0f, yaw = 0.0f, pitch = 0.0f;
glm::vec3 cameraPos(0.0f, 0.0f, 3.0f);
glm::vec3 cameraUp(0.0f, 1.0f, 0.0f); // As a reminder, x points to the right, y points upwards and z points towards you
glm::vec3 cameraFront(0.0f, 0.0f, -1.0f);
With these, I can create a view matrix this way :
glm::mat4 view;
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
I want to be able to move my camera perpendicularly (yaw) and laterally (pitch), i.e. up, down, right, left on my screen. For this, it is enough to rotate the cameraFront vector and the cameraUp vector appropriately and then update the view matrix with the updated vectors.
My Cursor Position Callback looks like this :
glm::vec3 rotateAroundAxis(glm::vec3 toRotate, float angle, glm::vec3 axisDirection, glm::vec3 axisPoint) { // angle in radians
toRotate -= axisPoint;
glm::mat4 rotationMatrix(1.0f);
rotationMatrix = glm::rotate(rotationMatrix, angle, axisDirection);
glm::vec4 result = rotationMatrix*glm::vec4(toRotate, 1.0f);
toRotate = glm::vec3(result.x, result.y, result.z);
toRotate += axisPoint;
return toRotate;
}
void mouseCallback(GLFWwindow* window, double xpos, double ypos) {
const float maxPitch = float(M_PI) - float(M_PI) / 180.0f;
glm::vec3 cameraRight = -glm::cross(cameraUp, cameraFront);
float xOffset = xpos - lastX;
float yOffset = ypos - lastY;
lastX = xpos;
lastY = ypos;
float sensitivity = 0.0005f;
xOffset *= sensitivity;
yOffset *= sensitivity;
yaw += xOffset; // useless here
pitch += yOffset;
if (pitch > maxPitch) {
yOffset = 0.0f;
}
if (pitch < -maxPitch) {
yOffset = 0.0f;
}
cameraFront = rotateAroundAxis(cameraFront, -xOffset, cameraUp, cameraPos);
cameraFront = rotateAroundAxis(cameraFront, -yOffset, cameraRight, cameraPos);
cameraUp = rotateAroundAxis(cameraUp, -yOffset, cameraRight, cameraPos);
}
As I said, it works fine for simple up-down, left-right camera movements, but when I start to move my mouse in circles or like a madman, the camera starts to rotate longitudinally (roll).
I've tried to force cameraRight.y = cameraPos.y so that the cameraRight vector doesn't tilt upwards/downwards due to numerical errors but it doesn't solve the problem. I've also tried to add a (global) cameraRight vector to keep track of it instead of computing it every time so the end of the function looks like this :
cameraFront = rotateAroundAxis(cameraFront, -xOffset, cameraUp, cameraPos);
cameraRight = rotateAroundAxis(cameraRight, -xOffset, cameraUp, cameraPos);
cameraFront = rotateAroundAxis(cameraFront, -yOffset, cameraRight, cameraPos);
cameraUp = rotateAroundAxis(cameraUp, -yOffset, cameraRight, cameraPos);
but it doesn't solve the problem. Any pieces of advice ?