Search code examples
c++openglvisual-studio-2019glfwglm-math

OpenGL, GLFW, GLM: Camera Translates x Units to the Right, but Everything also Moves x Units to the Right with It


I am developing a game engine. Currently I am working on the camera system. When I translate it Time::getMainLoopDeltaTime() units to the right, everything in the scene moves to the right along with it when everything should look like it is moving left. I cannot figure out what I am doing wrong. These are the technologies that I am using:

  • GLFW
  • OpenGL
  • GLM

Note: I am using the game object's transform as the camera's transformation matrix that also serves as the view matrix. The x position outputs positively increasing values and the game objects in the scene are stationary (their x y z position values are not changing).

Camera game object intialization

    GameObject* gameObject = GameObject::create("Main Camera", 100);
    gameObject->addComponent(ComponentType::CAMERA_2D);
    Transform* transform = gameObject->getTransform();
    transform->scale(glm::vec3(0.1f, 0.1f, 0.1f)); // Zoom out camera 10x and gameObject's transform

Projection matrix initialization:

    glm::mat4 projectionMatrix = glm::ortho(-500.0f, 500.0f, -500.0f, 500.0f, -1.0f, 1.0f);

I have a logic component that runs every main loop update/cycle and translates the camera/game object:

    Transform* cameraTransform = Camera2D::getMainCamera()->getGameObject()->getTransform();
    cameraTransform->translate(glm::vec3(Time::getMainLoopDeltaTimeF() * 10, 0, 0));
    cout << cameraTransform->getPosition().x << endl;

Then the rendering engine does the following:

    projectionViewMatrix = projectionMatrix * Camera2D::getMainCamera()->getViewMatrix();
    spirVProgram->setProjectionViewMatrix(projectionViewMatrix);

Note: I am multiplying these matrices in this order because I am using GLM.

Here is my vertex shader for additional information:

#version 450 core

layout(location = 0) in vec2 position;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 textureCoordinates;
layout(location = 3) in float textureSlot;
layout(location = 4) in float ssboIndex;
layout(std430, binding = 2) buffer myBuffer {
    mat4 transform[];
};


layout(location = 0) uniform mat4 uProjectionView;

out vec4 vColor;
out vec2 vTextureCoordinates;
out float vTextureSlot;

void main() {
    vColor = color;
    vTextureCoordinates = textureCoordinates;
    vTextureSlot = textureSlot;

    gl_Position = uProjectionView * transform[int(ssboIndex)] * vec4(position, 1.0, 1.0);
}

I hope someone can spot what I am doing wrong. If not, can someone explain to me how this is supposed to be done? Is this even supposed to be the expected behavior?

This is how everything looks like: enter image description here enter image description here

It is like the game object is moving to the right but the camera moving to the left...

IMPORTANT EDIT

From my research, it appears this is the expected behavior, but I am not sure. If this is the correct behavior, should I just negate the position? And, should I do the same with rotation?

EDIT: is this an acceptable solution?

glm::mat4 Camera2D::getViewMatrix() {
    Transform* transform = gameObject->getTransform();
    glm::mat4 cameraMatrix = transform->getTransformationMatrix();
    cameraMatrix[3][0] *= -1;
    cameraMatrix[3][1] *= -1;
    cameraMatrix[3][2] *= -1;
    return cameraMatrix;
}

The game object's transform would keep it original transform but every time I get it I negate it. This gave the expected result/behavior.


Solution

  • Apparently, what I thought was wrong was actually right, but and incomplete implementation of the camera system. Translating the camera/gameObject matrix to the right will also move everything to the right. To solve this, we can negate the position of a copy of the transformation matrix every time we need to use it to render things. This will allow to keep the original data while getting the expected behavior when rendering.