I am using GLFW to render some things in OpenGL. I created a Camera class that allows movement and looking around with the camera. These work fine when being done alone, but when they are used together, the following things happen:
When moving the camera forward, the rotation becomes slow and rotation resets the camera to the original position.
When moving the camera backwards, left, or right, the rotation causes everything to go out of the picture. The only things that I am rendering right now are two triangles directly in front of the camera, so I don't know what the camera ends up looking at. It will also occasionally reset the camera position like above, but only after moving forward first.
The code is relatively simple and the entire source is here, mainly in the Camera, Entity, and main source and header files, but I will also include the relevant bits below.
This is the function that I'm setting for GLFW's key callback and deals with movement:
void keyCallback(GLFWwindow * window, int key, int scancode, int action, int mods)
{
switch(key)
{
case GLFW_KEY_W:
cam->move(glm::vec3(0.0, 0.0, -0.05));
break;
case GLFW_KEY_S:
cam->move(glm::vec3(0.0, 0.0, 0.05));
break;
case GLFW_KEY_A:
cam->move(glm::vec3(-0.05, 0.0, 0.0));
break;
case GLFW_KEY_D:
cam->move(glm::vec3(0.05, 0.0, 0.0));
break;
case GLFW_KEY_ESCAPE:
glfwSetWindowShouldClose(window, GL_TRUE);
break;
default:
break;
}
}
This is the function dealing with mouse movement and looking around with the camera:
void cursorMoveCallback(GLFWwindow * window, double xpos, double ypos)
{
printf("Mouse Moved to (%f, %f)\n", xpos, ypos);
// Change camera angle
glm::vec3 cameraMovement;
// Change in x (rotation about y axis)
if(xpos > 0)
cameraMovement.x = -0.0005;
else if (xpos < 0)
cameraMovement.x = 0.0005;
// Change in y (rotation about x axis)
if(ypos > 0)
cameraMovement.y = 0.0005;
else if(ypos < 0)
cameraMovement.y = -0.0005;
// Reset Cursor position
glfwSetCursorPos(window, 0, 0);
// Change Position of Camera
cameraMovement += Camera::getCurrentCamera()->getDirection();
Camera::getCurrentCamera()->setDirection(cameraMovement);
}
Moving Camera:
glm::vec3 Camera::move(glm::vec3 translation)
{
int dims = viewMatrix.length() - 1;
// Apply translation
for (int i = 0; i < dims; i++)
viewMatrix[dims][i] -= translation[i];
// Update viewMatrix
Program::updateViewMatrix(viewMatrix);
return Entity::move(translation);
}
glm::vec3 Entity::move(glm::vec3 translation)
{
// Move by amount
position += translation;
// Return new position
return position;
}
Looking with camera:
glm::vec3 Camera::setDirection(glm::vec3 newDirection)
{
viewMatrix = glm::lookAt(newDirection, position, glm::vec3(0.0, 1.0, 0.0));
Program::updateViewMatrix(viewMatrix);
return Entity::setDirection(newDirection);
}
glm::vec3 Entity::setDirection(glm::vec3 newDirection)
{
// Set direction of entity
direction = newDirection;
// Return new direction of entity
return direction;
}
The Program::updateViewMatrix()
call just goes through all active OpenGL programs and sets uniforms for the view matrix. Please let me know if there could be any other relevant code that would make a difference.
My guess would be that I'm running into some sort of threading issue due to the callbacks or there's an issue with trying to both move and look around at the same time.
UPDATE 1: I have fixed the order of arguments to glm::lookAt()
. This fixes the disappearing issue, but after moving any, the rotation seems to be slower than it should.
The problem is that glm::lookAt(eye, center, up) expects other parameters than you supply:
For more details one might find this post very useful.