Search code examples
c++openglcameraglm-mathdirection

OpenGL camera target issue


I'm implementing a 3D maze game in C++, using OpenGL where the camera is at a fixed position exactly above the middle of the maze looking at the middle too. It works and looks just as I've wanted but the my code is not so nice because I needed to put a + 0.01f into the position to work well. If I miss it out, the labirynth doesn't show up, it seems like the camera points into the opposite direction.. How can I fix it elegantly?

glm::vec3 FrontDirection = glm::vec3(((GLfloat)MazeSize / 2) + 0.01f, 0.0f, ((GLfloat)MazeSize / 2)

The (0,0,0) origo location is the left corner of the maze (start position) so this is the reason I set the position like this:

glm::vec3 CameraPosition = glm::vec3(((GLfloat)MazeSize / 2), ((GLfloat)MazeSize + 5.0f), ((GLfloat)MazeSize / 2))

The UpDirection is (0.0f, 1.0f, 0.0f) lookAt function looks like this:

Matrix = glm::lookAt(CameraPosition, FrontDirection, UpDirection);

I know that by convention, in OpenGL the camera points towards the negative z-axis so the FrontDirection is basically pointing in the reverse direction of what it is targeting. For me it would be completely clear to set the positions like I did above but it still is not working as I've expected. (unless I put that + 0.01f)

Thank you for your answer in advance!


Solution

  • I know that by convention, in OpenGL the camera points towards the negative z-axis

    In viewspace the z-axis points out of the viewport, but that is completely irrelevant. You define the view matrix, the position and the orientation of the camera. The camera position is the first argument of glm::lookAt. The camera looks in the direction of the target, the 2nd argument of glm::lookAt.

    The 2nd parameter of glm::lookAt is not a direction vector, it is a point on the line of sight. Compute a point on the line of sight by CameraPosition+FrontDirection:

    Matrix = glm::lookAt(CameraPosition, CameraPosition+FrontDirection, UpDirection);
    

    Your upwards-vector has the same direction as the line of sight. The upwards should be orthogonal to the line of sight. The up-vector defines the roll:

    glm::vec3 CameraPosition = glm::vec3(
        ((GLfloat)MazeSize / 2), ((GLfloat)MazeSize + 5.0f), ((GLfloat)MazeSize / 2));
    glm::vec3 CameraTarget = glm::vec3(
        ((GLfloat)MazeSize / 2), 0.0f, ((GLfloat)MazeSize / 2));
    glm::vec3 UpDirection = glm::vec3(0.0f, 0.0f, 1.0f); 
    
    Matrix = glm::lookAt(CameraPosition, CameraTarget, UpDirection);