Confused About Triangle Winding And Transformations
Asked Answered
S

1

6

First of all, I want to apologize for such a long question. You don't have to read it. You may jump straight to the questions part and then look up for details if needed (I have tried to provide as much information as possible, because in my experience too much code is better than too little). So,...

I am a bit confused about triangle winding and transformations, which I thought I understood. I am trying to draw a cube which is defined as follows:

    const float a = 0.5f; //half of the cube side length
    float positions[nComponents] =
    {
        //front face
        -a, -a, -a,
         a, -a, -a,
         a,  a, -a,

        -a, -a, -a,
         a,  a, -a,
        -a,  a, -a,

        //back face
        -a, -a,  a,
         a,  a,  a,
         a, -a,  a,

        -a, -a,  a,
        -a,  a,  a,
         a,  a,  a,

        //up face
        -a,  a, -a,
         a,  a, -a,
         a,  a,  a,

        -a,  a, -a,
         a,  a,  a,
        -a,  a,  a,

        //down face
        -a, -a, -a,
         a, -a,  a,
         a, -a, -a,

        -a, -a, -a,
        -a, -a,  a,
         a, -a,  a,

         //right face
         a, -a, -a,
         a, -a,  a,
         a,  a,  a,

         a, -a, -a,
         a,  a,  a,
         a,  a, -a,

         //left face
         -a, -a, -a,
         -a,  a,  a,
         -a, -a,  a,

         -a, -a, -a,
         -a,  a, -a,
         -a,  a,  a,
    };

And these are the supposed colors of my faces:

float face_colors[nFaces * dim] =
{
    1,0,0, //front RED
    1,1,1, //back  WHITE
    0,0,1, //up    BLUE
    0,1,1, //down  SKY BLUE
    0,1,0, //right GREEN
    1,1,0, //left  YELLOW
};

As you can see from the comments, I use terms up, down, left, right, etc. These words get their meaning if we suppose that we're looking at the cube from the position, say, (0, 0, -3a) in world coordinates. Now, as I understand, the front faces of my cube are wound conter-clockwise (that is, if we look at the cube from any position outside of it, and enumerate the vertices in the triangles we see, we will get counterclockwise winding).

So, I need to 1. Enable culling. 2. Say that counterclockwise is the front face 3. Cull back face. This is the code for that:

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);

My projection matrix is a perspective projection matrix, and the modelView matrix is just a LookAt matrix. They are fed as uniforms to the vertex shader.

ProjectionMatrix = glm::perspective(45.0f, (float)w/h, 0.1f, 100.0f);
glm::vec3 center(0.0f, 0.0f, 0.0f);
glm::vec3 eye(1.0f, 2.0f, -3.0f);
glm::vec3 up(0.0f, 1.0f, 0.0f);
ModelViewMatrix = glm::lookAt(eye, center, up);
glUniformMatrix4fv(locP, 1, false, glm::value_ptr(ProjectionMatrix));
glUniformMatrix4fv(locMV, 1, false, glm::value_ptr(ModelViewMatrix));

My vertex shader is defined as follows:

#version 400
layout(location = 0) in vec4 vVertex;
layout(location = 1) in vec4 vColor;
uniform mat4 P;
uniform mat4 MV;
out vec4 vFragColor;
void main(void)
{
   vFragColor = vColor;
   gl_Position = P * MV * vVertex;
}

My fragment shader is trivial - it just outputs the interpolated color.

Now... here's the output that I get:

enter image description here

If I change glFrontFace(GL_CCW); to glFrontFace(GL_CW);, or alternatively, change glCullFace(GL_BACK) to glCullFace(GL_FRONT), I get the expected (at least more expected than the previous one, see second and third quesions) rendering:

enter image description here

I see three problems here, each described in a question:

ACTUAL QUESTIONS:

Q1: Why is the winding reverse of what I intended? Haven't I wound the vertices counterclockwise for front faces?
Q2 Why have my "left" face and "right" face switched places? The left face was supposed to be yellow and the right one green, not vice-versa! What's wrong with my transformation?
Q3 There is something wrong with my transformation because the x coordinate of my eye vector is positive, which means I should actually see a bit of the right side, not a bit of the left side!

I have asked these questions together because I think they're all connected, and probably with something very basic that I am missing. Thank you very much for taking time to clarify these things.

Shaving answered 29/8, 2011 at 14:56 Comment(0)
L
11

OpenGL by default assumes a right handed coordinate system, i.e. the positive Z axis pointing OUT of the screen. Your cube vertex positions indicate you're assuming a left handed coordinate system. However if you put those values into a RHS then your LHS-counterclockwise coordinates become clockwise (1), faces on one axis swap places(2) and your assumed eye transformations will go into opposite direction(3).

Lungworm answered 29/8, 2011 at 15:4 Comment(5)
I'm still confused. Am I not free to define my "world" coordinate system however I like? And the LookAt function takes vectors in world coordinates, no? Then what difference does it make the default Z-axis direction?Shaving
Ahhh... I think I'm starting to get it now... I can't change the relative dispositions of the three axes even in world coordinate system. Is that right?Shaving
@Armen Yes that's it. You could scale your modelview matrix by (1,1,-1) and therefore mirror the z-axis to assume your intended left-handed system, but I would not suggest this, as it would be something like a hack around the de-facto standard of a right-handed system.Moy
Thanks, Datenwolf and @Christian. I get it now :)Shaving
@Armen Tsirunyan: That's not how gluLookAt works. gluLookAt set the global world transformation, akin to a camera. And like a camera has not only a position and a target, also the direction that's up is important, and that's what gluLookAt defines. But NOT the coordinate system.Lungworm

© 2022 - 2024 — McMap. All rights reserved.