Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL renders boxes inside-out

Tags:

opengl

glut

I'm trying to create 2 boxes in OpenGL, but they appear inside-out and sometimes they do not overlap correctly. Video http://www.youtube.com/watch?v=IVJu4zJFp7Q

I'm guessing it is a depth issue but I haven't been able to figure out what I'm doing wrong.

Here is the code I'm using to initialize:

glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

glDisable(GL_CULL_FACE); 
glEnable(GL_DEPTH_TEST);

Here is my distplay function glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );

drawYellowBox();
drawBlueBox();

And the code I'm using to draw the shapes:

glPushMatrix();
    glBegin(GL_QUADS);

        glColor3f(0.15, 0.15, 0.0);
        // draw front
        glVertex3f(-1.0, -1.5, 1.0);
        glVertex3f( 1.0, -1.5, 1.0);
        glVertex3f( 0.75,  1.5, 0.75);
        glVertex3f(-0.75,  1.5, 0.75);

        glColor3f(0.3, 0.3, 0.0);
        // draw back
        glVertex3f( 1.0, -1.5, -1.0);
        glVertex3f(-1.0, -1.5, -1.0);
        glVertex3f(-0.75,  1.5, -0.75);
        glVertex3f( 0.75,  1.5, -0.75);

        glColor3f(0.45, 0.45, 0.0);
        // draw left
        glVertex3f(-1.0, -1.5, -1.0);
        glVertex3f(-1.0, -1.5,  1.0);
        glVertex3f(-0.75,  1.5,  0.75);
        glVertex3f(-0.75,  1.5, -0.75);

        glColor3f(0.6, 0.6, 0.0);
        // draw right
        glVertex3f( 1.0, -1.5,  1.0);
        glVertex3f( 1.0, -1.5, -1.0);
        glVertex3f( 0.75,  1.5, -0.75);
        glVertex3f( 0.75,  1.5,  0.75);

        glColor3f(0.75, 0.75, 0.0);
        // draw top
        glVertex3f(-0.75,  1.5,  0.75);
        glVertex3f( 0.75,  1.5,  0.75);
        glVertex3f( 0.75,  1.5, -0.75);
        glVertex3f(-0.75,  1.5, -0.75);

        glColor3f(0.9, 0.9, 0.0);
        // draw bottom
        glVertex3f(-1.0, -1.5, -1.0);
        glVertex3f( 1.0, -1.5, -1.0);
        glVertex3f( 1.0, -1.5,  1.0);
        glVertex3f(-1.0, -1.5,  1.0);
    glEnd();

glPopMatrix();

glPushMatrix();
    glTranslatef(0.0,2.5,0.0);
    glRotatef(joint_ui_data->getDOF(Keyframe::HEAD), 0.0, 1.0, 0.0);


    glBegin(GL_QUADS);

        glColor3f(0.0, 0.15, 0.15);
        // draw front face
        glVertex3f(-0.8, -0.45, 0.8);
        glVertex3f( 0.8, -0.45, 0.8);
        glVertex3f( 0.75,  0.45, 0.75);
        glVertex3f(-0.75,  0.45, 0.75);

        glColor3f(0.0, 0.3, 0.3);
        // draw back face
        glVertex3f( 0.8, -0.45, -0.8);
        glVertex3f(-0.8, -0.45, -0.8);
        glVertex3f(-0.75,  0.45, -0.75);
        glVertex3f( 0.75,  0.45, -0.75);

        glColor3f(0.0, 0.45, 0.45);
        // draw left face
        glVertex3f(-0.8, -0.45, -0.8);
        glVertex3f(-0.8, -0.45,  0.8);
        glVertex3f(-0.75,  0.45,  0.75);
        glVertex3f(-0.75,  0.45, -0.75);

        glColor3f(0.0, 0.6, 0.6);
        // draw right face
        glVertex3f( 0.8, -0.45,  0.8);
        glVertex3f( 0.8, -0.45, -0.8);
        glVertex3f( 0.75,  0.45, -0.75);
        glVertex3f( 0.75,  0.45,  0.75);

        glColor3f(0.0, 0.75, 0.75);
        // draw top
        glVertex3f(-0.75,  0.45,  0.75);
        glVertex3f( 0.75,  0.45,  0.75);
        glVertex3f( 0.75,  0.45, -0.75);
        glVertex3f(-0.75,  0.45, -0.75);

        glColor3f(0.0, 0.9, 0.9);
        // draw bottom
        glVertex3f(-0.8, -0.45, -0.8);
        glVertex3f(-0.8, -0.45,  0.8);
        glVertex3f( 0.8, -0.45,  0.8);
        glVertex3f( 0.8, -0.45, -0.8);
    glEnd();
glPopMatrix();

Thank you.

like image 263
Ares Avatar asked Nov 02 '13 15:11

Ares


2 Answers

The problem lies in the order you're sending your vertices.

As we can see in your code the vertex order of your front side is.

// Front
glVertex3f(-1.0, -1.5, 1.0);   // Left   Top
glVertex3f( 1.0, -1.5, 1.0);   // Right  Top
glVertex3f( 0.75,  1.5, 0.75); // Right  Bottom
glVertex3f(-0.75,  1.5, 0.75); // Left   Bottom

As we can see in that piece of code your sending the vertices clockwise. OpenGL by default reads all polygons counterclockwise. That is why all the opposite faces are removed/hidden (Culled away).

To fix this you can do 1 of 2 things.

  1. Change the mode of glFrontFace() so it becomes GL_CW, instead of GL_CCW. Though remember that the change will effect everything that comes after you call glFrontFace(GL_CW) so remember to call glFrontFace(GL_CCW) again if there at any other point you render something which have counterclockwise winding again.

  2. Change the order you're sending the vertices in.

From

// Front
glVertex3f(-1.0, -1.5, 1.0);   // Left   Top
glVertex3f( 1.0, -1.5, 1.0);   // Right  Top
glVertex3f( 0.75,  1.5, 0.75); // Right  Bottom
glVertex3f(-0.75,  1.5, 0.75); // Left   Bottom

To

// Front
glVertex3f(-1.0, -1.5, 1.0);   // Left   Top
glVertex3f(-0.75,  1.5, 0.75); // Left   Bottom
glVertex3f( 0.75,  1.5, 0.75); // Right  Bottom
glVertex3f( 1.0, -1.5, 1.0);   // Right  Top

Though if you already have tons of meshes it would probably be much easier simply to change the glFrontFace mode to GL_CW.

Extra

Also if you want to change which faces are being culled, you can also change the mode of glCullFace, to either GL_FRONT, GL_BACK or GL_FRONT_AND_BACK the initial value is GL_BACK.

Remember you need to call glEnable(GL_CULL_FACE) to enable culling of polygons based on their vertex winding.

Edit

If it's not a vertex winding problem, the it might (though it would be very weird), be a depth testing problem.

Add this code to your initialization code.

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
like image 180
vallentin Avatar answered Oct 20 '22 00:10

vallentin


To fix this problem you will need to flip your faces around on your object or check you normals of the object at hand...

If you create a plane you will notice you can see through one side of it unless you invert normals to the view side or add a double sided solution...

I usually use away3d or three.js for 3D content...the principles are the same

like image 33
Careen Avatar answered Oct 19 '22 23:10

Careen