PDA

View Full Version : Drawing a Cube



GosuDrew
06-16-2005, 05:08 PM
Hi,

I'm trying to determine why my code below does not correctly draw a rotating cube. I specified normals for each of the vertices and enabled GL_CULL_FACE followed by a call to glCullFace(GL_BACK), however I can still see through some polygons. I was thinking that the normal vectors would have to be changed after every rotation, but I don't know. Although I can get a rotating cube to draw correctly by enabling GL_DEPTH_TEST, I can't seem to figure out why this way does not work.

Any help would be appreciated.


#include <GL/glut.h>
#include <stdlib.h>

GLdouble spin = 0.0;

static GLfloat vertices[] = {1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,
1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0,
1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,
-1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0,
-1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0,
-1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0};

static GLfloat colors[] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0,
1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0,
0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0,
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0};

static GLfloat normals[] = {0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0,
1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0};


void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glNormalPointer(GL_FLOAT, 0, normals);
glColorPointer(3, GL_FLOAT, 0, colors);

glTranslatef(0.0, 0.0, -100.0);
glRotatef(spin, 1.0, 0.5, 0.8);
glScalef(25.0, 25.0, 25.0);

glBegin(GL_QUADS);
for (int i = 0; i < 24; i = i + 4)
{
glArrayElement(i);
glArrayElement(i+1);
glArrayElement(i+2);
glArrayElement(i+3);
}
glEnd();

glutSwapBuffers();
glFlush();
}

void spin_display()
{
spin = spin + .5;
if (spin > 360.0)
spin = spin - 360;
glutPostRedisplay();
}

void init (void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}

void reshape (int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50, 50, -50, 50, 5, 1000);
glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(spin_display);
glutMainLoop();
return 0;
}

plasmonster
06-16-2005, 07:28 PM
Check the winding direction of your quads carefully. I'll bet you have an inconsistency somewhere in your vertices ;-)

Normals are not used for the front/back facing test, so don't worry about that. OpenGL uses the signed polygon area in screen-space to make this determination.

Have a peek at section 3.5.1 in the spec for a complete description:
http://www.opengl.org/documentation/spec.html

GosuDrew
06-16-2005, 09:15 PM
Thanks, I rearranged my vertices and it works now. I drew opposite sides of the cube in different directions. One side counterclockwise and the opposite one, clockwise. Is this what you need to do all the time for drawing some closed surface, make sure the polygon on the other side is drawn in different direction? If so, wouldn't it be impossible to determine how to draw all the polygons for some non-symmetrical closed surface?

T101
06-16-2005, 09:57 PM
Yes, that _is_ the way backfaces and frontfaces are kept apart.

Vertex normals are only used for lighting.

In practice it's not really a problem, because you either use some code to generate the surfaces, or you load them from a file from a modeling package - and those tend to use the winding order themselves. (It's possible of course that the winding order is the exact opposite of OGL's , but that's pretty simple to compensate for).

plasmonster
06-17-2005, 08:36 AM
I'll just add the GL_SPHERE_MAP, GL_REFLECTION_MAP, and GL_NORMAL_MAP texgen modes to the lighting. I think that about does it, for the fixed-function pipeline, anyway.