user14063792468
user14063792468

Reputation: 956

glm::lookAt - image is visually flipped both x and y axis

To better understand OpenGL pipeline, I wrote simple two dimensional demo with a "camera".

The program displays a quad in the left half of a screen with "camera" at the center. After that I change parameters to see the visual outcome.

The setup is typical OpenGL setup.

The quad setup use "pixel coordinates", because later I do an orthographic projection.

/* quad setup */
static    GLfloat vdata[] = {
    //  X     Y     Z                        U  V     
        0.0f,              0.0f,   0.0f,     0, 0, // vertex 0
        SCREEN_SIZE.x / 2, 0.0f,   0.0f,     1, 0, // vertex 1
        0.0f,              100.0f, 0.0f,     1, 0, // vertex 2
        SCREEN_SIZE.x / 2, 100.0f, 0.0f,     1, 1, // vertex 3 
    }; // 4 vertices with 5 components (floats) each

static    GLuint vindex[] = {
        0,1,2, // first triangle
        1,3,2, // second triangle
    };

With a help of great glm library, here is my model x view x projection matrix.

glm::mat4 p = glm::ortho(-(float)SCREEN_SIZE.x / 2, (float)SCREEN_SIZE.x / 2, -(float)SCREEN_SIZE.y / 2, (float)SCREEN_SIZE.y / 2, -1.0f, 1.0f);
glm::mat4 v = glm::lookAt(
    glm::vec3(0.0f, 0.0f, -1.0f), // position
    glm::vec3(0.0f, 0.0f,  0.0f), // looks at
    glm::vec3(0.0f, 1.0f,  0.0f)  // direction
);
glm::mat4 m = glm::mat4(1.0f);
glm::mat4 mvp =   glm::translate(m, {0.5f, 0.f, 0.f}) /* model */
                  * glm::translate(v, {0.5f, 0.0f, 0.0f})  /* view */
                  * p; /* projection */

The visual follows. For those who have small screens, I'll describe it, The white block in the left part of the screen. As expected. The nuance is that I translated model space by a half and, the same time, translated view space. So that, model shall move right with a view moving right also. Visually the quad shall be at the same position, as defined originally.

quad at the left

Now, silly me, I continue to play with a arguments to LookAt. My thought is that if I change "eye position", and "looks at" position, I will see a different visual than what I'd got.

glm::mat4 v = glm::lookAt(
    glm::vec3(0.5f, 0.0f, -1.0f), // position <= move to right direction
    glm::vec3(0.5f, 0.0f,  0.0f), // looks at <= point at same
    glm::vec3(0.0f, 1.0f,  0.0f)  // direction
);

The outcome follows. What I see this time, is that quad moved to the right. But I expect it to move further left, because "camera" now is at 0.5 to the right.

The question: Naturally, the pictures on the internet, related to OpenGL, picture camera with all the axes and all labeled, and I clearly think that moving camera position to the right, places objects to the left. I definitely confused by the outcome.

What part of OpenGL pipeline I do not get into accout?

quad at the center, but I thought different outcome

Update

The shader for vertex processing is a standard:

#version 460
layout(location = 0) in vec4 vposition;
layout(location = 1) in vec2 vtexcoord;
uniform mat4      mvp;
out vec2 ftexcoord;
void main() {
   ftexcoord = vtexcoord;
   gl_Position = mvp * vposition;
};

Update

I've mapped a texture to the quad and with the initial setup I see that both axes are flipped.

flipped axes with the initial setup

Changing the eye position from glm::vec3(0.0f, 0.0f, -1.0f) to glm::vec3(0.0f, 0.0f, 1.0f) fixes the flip. But I really do not get the math behind that.

Update

Took me some time to gather visuals and see OpenGL glu documentation for the explanation. The image I've taken from internets:

lookAt illustration

Notice the forward label. Now see gluLookAt documentation.

gluLookAt creates a viewing matrix derived from an eye point, a reference point indicating the center of the scene, and an UP vector.The matrix maps the reference point to the negative z axis and the eye point to the origin.

So we looking at the reference point from the eye point. The wording about "..maps to negative axis.." was confusing. But notice the forward label and see the forward vector math.

         centerX - eyeX
    F =  centerY - eyeY
         centerZ - eyeZ

If the center is at vec4(0, 0, -1), as I originally wrote, "camera" is positioned past the "forward" point. This situation kinda ruined the math for me.

But still... I understand that "right" vector is calculated and could be flipped(I not that good at the math to prove). Why is y axis is flipped too?

Update

Sorry community, the post was long and I did a mistake interpreting the original picture of a textured quad. If the x axis is flipped than the x,y coordinates are flipped too. So me did a mistake looking at the image. The y axis is not flipped, it is only the x axis is.

Still be great if someone will point out with explanation of how this right vector is calculated. Too hard for me.

BTW if I do glm::translate by vec3(1., 1., 0.) of the model and view matrices, everything is displaying as expected.

correct display

Upvotes: 0

Views: 244

Answers (0)

Related Questions