Example 8-1 : Polygon Offset Example Program
/********************************************************************** * Uses PolygonOffset to draw hidden-line images. PolygonOffset * shifts z values of polygons by an amount proportional to their slope * in screen z. This keeps the lines, which are drawn without * displacement, from interacting with their respective polygons, and * and thus eliminates line dropouts. */ #include <GL/glx.h> #include <GL/glu.h> #include <X11/keysym.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #define MAXQUAD 6 typedef float Vertex[3]; typedef Vertex Quad[4]; Quad quads[MAXQUAD] = { /*data to define six faces of a unit cube */ 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1, 0,0,0, 1,0,0, 1,0,1, 0,0,1, 0,1,0, 1,1,0, 1,1,1, 0,1,1, 0,0,0, 0,0,1, 0,1,1, 0,1,0, 1,0,0, 1,0,1, 1,1,1, 1,1,0 }; #define WIREFRAME 0 #define HIDDEN_LINE 1 /*** function prototypes go here ***/ static int dimension = 3; main(int argc, char** argv) { Display *dpy; XVisualInfo *vi; XSetWindowAttributes swa; Window win; GLXContext cx; /*** X Window System setup goes here ***/ /* check for the polygon offset extension */ if (!query_extension("GL_EXT_polygon_offset")) error(argv[0], "polygon_offset extension is not available"); /* set up viewing parameters */ glMatrixMode(GL_PROJECTION); gluPerspective(20, 1, 0.1, 20); glMatrixMode(GL_MODELVIEW); glTranslatef(0, 0, -15); /* set other relevant state information */ glEnable(GL_DEPTH_TEST); glPolygonOffsetEXT(1.5, 0.000001); /* process events until the user presses ESC */ while (1) process_input(dpy, win); } static void draw_scene(int mx, int my) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(-1.7, 0.0, 0.0); cubes(mx, my, WIREFRAME); glPopMatrix(); glPushMatrix(); cubes(mx, my, HIDDEN_LINE); glPopMatrix(); glPushMatrix(); glTranslatef(1.7, 0.0, 0.0); glEnable(GL_POLYGON_OFFSET_EXT); cubes(mx, my, HIDDEN_LINE); glDisable(GL_POLYGON_OFFSET_EXT); glPopMatrix(); } static void cubes(int mx, int my, int mode) { int x, y, z, i; /* track the mouse */ glRotatef(mx / 2.0, 0, 1, 0); glRotatef(my / 2.0, 1, 0, 0); /* draw the lines as hidden polygons */ glTranslatef(-0.5, -0.5, -0.5); glScalef(1.0/dimension, 1.0/dimension, 1.0/dimension); for (z = 0; z < dimension; z++) { for (y = 0; y < dimension; y++) { for (x = 0; x < dimension; x++) { glPushMatrix(); glTranslatef(x, y, z); glScalef(0.8, 0.8, 0.8); for (i = 0; i < MAXQUAD; i++) draw_hidden(quads[i], mode); glPopMatrix(); } } } } static void fill(Quad quad) { glBegin(GL_QUADS); glVertex3fv(quad[0]); glVertex3fv(quad[1]); glVertex3fv(quad[2]); glVertex3fv(quad[3]); glEnd(); } static void outline(Quad quad) { /* draw an outlined polygon */ glBegin(GL_LINE_LOOP); glVertex3fv(quad[0]); glVertex3fv(quad[1]); glVertex3fv(quad[2]); glVertex3fv(quad[3]); glEnd(); } static void draw_hidden(Quad quad, int mode) { /* draw outline using white, optionally fill interior with black */ glColor3f(1, 1, 1); outline(quad); if (mode == HIDDEN_LINE) { glColor3f(0, 0, 0); fill(quad); } } static void process_input(Display *dpy, Window win) { XEvent event; static int prevx, prevy; static int deltax = 90, deltay = 40; do { char buf[31]; KeySym keysym; XNextEvent(dpy, &event); switch(event.type) { case Expose: break; case ConfigureNotify: glViewport(0, 0, e+vent.xconfigurewidth, event.xconfigureheigth); break; case ButtonPress: prevx = event.xbutton.x; prevy = event.xbutton.y; break; case MotionNotify: deltax += (event.xbutton.x - prevx); prevx = event.xbutton.x; deltay += (event.xbutton.y - prevy); prevy = event.xbutton.y; break; default: break; } } while (XPending(dpy)); draw_scene(deltax, deltay); glXSwapBuffers(dpy, win); }
Figure 8-1 : Polygon Offset Extension Example