Search code examples
c++rotationtransformglm-math

OpenGL Camera Rotation with glm


I'm trying to rotate camera but instead it rotates and changes position.

float m_CameraRotation = 30.0f;

TShader.Bind();

glm::mat4 proj = glm::ortho(0.0f, 1000.0f, 0.0f, 1000.0f, -1.0f, 1.0f);
glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 0));

glm::mat4 vp = proj * view;

glm::mat4 transform = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)) *
                      glm::rotate(glm::mat4(1.0f), glm::radians(m_CameraRotation), glm::vec3(0, 0, 1));
TShader.UniformSetMat4f("u_ViewProjection", vp);
TShader.UniformSetMat4f("u_Transform", transform);

Shader

gl_Position = u_ViewProjection * u_Transform * vec4(aPos, 1.0);

And my triangle coordinates

float TriangleVertices[] =
{
    // positions          // colors
     500.0f,  700.0f, 0.0f,   1.0f, 0.0f, 0.0f, // top
     250.0f,  300.0f, 0.0f,   0.0f, 1.0f, 0.0f, // bottom left
     750.0f,  300.0f, 0.0f,   0.0f, 0.0f, 1.0f // bottom right
};
unsigned int TriangleIndices[] = {
    0, 1, 2
};

This is my triangle without rotation.

enter image description here

And this is my triangle with m_CameraRotation = 30.0f;

enter image description here

What's causing this?


Solution

  • Since your translations don't do anything, the only transformations applied to the triangle's vertices are the rotation first and the orthographic projection second. The rotation axis being +z, it will rotate everything in the xy plane around the origin by m_CameraRotation degrees counterclockwise.

    Your triangle isn't really translated, it's rotated around the origin. The green vertex for example is at (250, 300) before rotation, and approximately (66.5, 384.8) after. Looking back at your screenshots, this is exactly where I would expect the triangle to be.

    To rotate the triangle around its center, or around the center of the screen, or around any point P, you need to translate it first by -P, then rotate it, then translate it back by +P.

    Something like:

    glm::vec3 center(500.f, 500.f, 0.f);
    glm::mat4 rotation = glm::rotate(glm::radians(m_CameraRotation), glm::vec3(0, 0, 1));
    glm::mat4 transform = glm::translate(center) * rotation * glm::translate(-center);
    

    You could also try doing the orthographic projection first and the rotation second.

    Side note: you don't need the identity matrix as first argument to glm::translate and glm::rotate every time.