Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused About Triangle Winding And Transformations

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.

like image 672
Armen Tsirunyan Avatar asked Aug 29 '11 14:08

Armen Tsirunyan


1 Answers

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).

like image 186
datenwolf Avatar answered Oct 17 '22 08:10

datenwolf