ghelms@hellfire.csd.sgi.com (Gretchen Helms) (09/29/90)
The following is my implementation of Kurt Akeley's article in the IRIS Universe regarding hollow polygons. Object is a cube rather than a sphere as it takes less code to implement. Read the comments. -----------------------mangle here----------------------- /* hollocube.c Sample code for creating an object made up of hollow polygons, as referenced in Kurt Akeley's article "The Hidden Charms of Z-Buffer", IRIS Universe issue number 11. Implemented by G. "Murdock" Helms, SGI, 8/2/90. Final revision 9/28/90. Compile with cc hollocube.c -o hollocube -lgl_s DOES NOT RUN ON NON-GT/GTXS AS PER ARTICLE. */ /* include the usual libs */ #include "math.h" #include "gl.h" #include "device.h" main() { short attached; /* usual queue stuff */ short value; int dev,val; float box[8][3]; /* this is needed for building the walls of the cube */ float width; /* shamelessly stolen from Intro to Graphics */ foreground(); /* you can run Edge on this if you like */ initialize(box, &width); /* set up the vertices of the walls */ drawscene(box, &width); /* do drawing things */ while (TRUE) /* loop until program is killed */ { while (qtest()||!attached) /* do the usual queue stuff */ { dev=qread(&value); if (dev==ESCKEY) { exit(0); /* can kill with esc key */ } if (dev==REDRAW) { reshapeviewport(); drawscene(box, &width); /* yes, you can move the window around */ } else if (dev==INPUTCHANGE) attached=value; } /* end while qtest */ } /* end while true */ } /* end main */ drawscene(box, width) /* simple draw routine */ float box[8][3]; float width; { czclear(0,0); drawbeam(box); swapbuffers(); rot(10,'x'); /* need to rotate to show off qualities */ czclear(0,0); /* wasn't apparent if viewed straight-on */ drawbeam(box); swapbuffers(); rot(20,'y'); czclear(0,0); drawbeam(box); swapbuffers(); } /* end drawscene */ initbeam (x, y, z, point) /* define the values for the vertices */ register float x, y, z, point[][3]; { point[0][0] = point[3][0] = point[4][0] = point[5][0] = -x/2.0; point[1][0] = point[2][0] = point[6][0] = point[7][0] = x/2.0; point[4][1] = point[5][1] = point[6][1] = point[7][1] = -y/2.0; point[0][1] = point[1][1] = point[2][1] = point[3][1] = y/2.0; point[2][2] = point[3][2] = point[5][2] = point[7][2] = -z/2.0; point[0][2] = point[1][2] = point[4][2] = point[6][2] = z/2.0; } /* What follows are a set of small functions that * follow the descriptions in the zbuffer article, * in the order they appear and are used. */ setzbuff() /* set up Zbuffer with reverse mapping */ { zbuffer(TRUE); lsetdepth(0x7fffff,0x000000); zfunction(ZF_GEQUAL); } /* end setzbuff */ disablp() /* disable polygon pixels */ { zbuffer(FALSE); backbuffer(FALSE); zdraw(TRUE); wmpack(0x800000); cpack(0x800000); } /* end disablep */ enablep() /* enable pixels on perimeter */ { cpack(0x000000); linewidth(2); } /* end enablep */ fillperim() /* fill poly (which actually only fills perim)*/ { zbuffer(TRUE); backbuffer(TRUE); zdraw(FALSE); wmpack(0xffffffff); cpack(0x000000FF); } /* end fill perim */ clearhollow() /* clear things up so no munging takes place */ { zbuffer(FALSE); backbuffer(FALSE); zdraw(TRUE); wmpack(0x800000); cpack(0x000000); } /* end clearhollow */ resethollow() /* reset states */ { zbuffer(TRUE); backbuffer(TRUE); zdraw(FALSE); wmpack(0xffffffff); } /* end resethollow */ drawbeam (point) /* now let's draw. */ register float point[][3]; { /* draw bottom facing polygon */ disablp(); bgnpolygon(); v3f( point[4] ); v3f( point[6] ); v3f( point[7] ); v3f( point[5] ); endpolygon(); enablep(); bgnclosedline(); v3f( point[4] ); v3f( point[6] ); v3f( point[7] ); v3f( point[5] ); endclosedline(); fillperim(); bgnpolygon(); v3f( point[4] ); v3f( point[6] ); v3f( point[7] ); v3f( point[5] ); endpolygon(); clearhollow(); bgnpolygon(); v3f( point[4] ); v3f( point[6] ); v3f( point[7] ); v3f( point[5] ); endpolygon(); resethollow(); /* draw left facing polygon */ disablp(); bgnpolygon(); v3f( point[3] ); v3f( point[0] ); v3f( point[4] ); v3f( point[5] ); endpolygon(); enablep(); bgnclosedline(); v3f( point[3] ); v3f( point[0] ); v3f( point[4] ); v3f( point[5] ); endclosedline(); fillperim(); bgnpolygon(); v3f( point[3] ); v3f( point[0] ); v3f( point[4] ); v3f( point[5] ); endpolygon(); clearhollow(); bgnpolygon(); v3f( point[3] ); v3f( point[0] ); v3f( point[4] ); v3f( point[5] ); endpolygon(); resethollow(); /* draw right facing polygon */ disablp(); bgnpolygon(); v3f( point[2] ); v3f( point[1] ); v3f( point[6] ); v3f( point[7] ); endpolygon(); enablep(); bgnclosedline(); v3f( point[2] ); v3f( point[1] ); v3f( point[6] ); v3f( point[7] ); endclosedline(); fillperim(); bgnpolygon(); v3f( point[2] ); v3f( point[1] ); v3f( point[6] ); v3f( point[7] ); endpolygon(); clearhollow(); bgnpolygon(); v3f( point[2] ); v3f( point[1] ); v3f( point[6] ); v3f( point[7] ); endpolygon(); resethollow(); /* draw top facing polygon */ disablp(); bgnpolygon(); v3f( point[0] ); v3f( point[1] ); v3f( point[2] ); v3f( point[3] ); endpolygon(); enablep(); bgnclosedline(); v3f( point[0] ); v3f( point[1] ); v3f( point[2] ); v3f( point[3] ); endclosedline(); fillperim(); bgnpolygon(); v3f( point[0] ); v3f( point[1] ); v3f( point[2] ); v3f( point[3] ); endpolygon(); clearhollow(); bgnpolygon(); v3f( point[0] ); v3f( point[1] ); v3f( point[2] ); v3f( point[3] ); endpolygon(); resethollow(); /* draw front facing polygon */ disablp(); bgnpolygon(); v3f( point[3] ); v3f( point[2] ); v3f( point[7] ); v3f( point[5] ); endpolygon(); enablep(); bgnclosedline(); v3f( point[3] ); v3f( point[2] ); v3f( point[7] ); v3f( point[5] ); endclosedline(); fillperim(); bgnpolygon(); v3f( point[3] ); v3f( point[2] ); v3f( point[7] ); v3f( point[5] ); endpolygon(); clearhollow(); bgnpolygon(); v3f( point[2] ); v3f( point[7] ); v3f( point[5] ); endpolygon(); resethollow(); /* draw back facing polygon */ disablp(); bgnpolygon(); v3f( point[0] ); v3f( point[1] ); v3f( point[6] ); v3f( point[4] ); endpolygon(); enablep(); bgnclosedline(); v3f( point[0] ); v3f( point[1] ); v3f( point[6] ); v3f( point[4] ); endclosedline(); fillperim(); bgnpolygon(); v3f( point[0] ); v3f( point[1] ); v3f( point[6] ); v3f( point[4] ); endpolygon(); clearhollow(); bgnpolygon(); v3f( point[0] ); v3f( point[1] ); v3f( point[6] ); v3f( point[4] ); endpolygon(); resethollow(); /* now we have to draw the cube solid inside all this stuff */ /* cuz if we don't it looks just like a normal wireframe! */ zfunction (ZF_GREATER); cpack(0x00000000); bgnpolygon(); v3f( point[4] ); v3f( point[6] ); v3f( point[7] ); v3f( point[5] ); endpolygon(); bgnpolygon(); v3f( point[3] ); v3f( point[0] ); v3f( point[4] ); v3f( point[5] ); endpolygon(); bgnpolygon(); v3f( point[2] ); v3f( point[1] ); v3f( point[6] ); v3f( point[7] ); endpolygon(); bgnpolygon(); v3f( point[0] ); v3f( point[1] ); v3f( point[2] ); v3f( point[3] ); endpolygon(); bgnpolygon(); v3f( point[3] ); v3f( point[2] ); v3f( point[7] ); v3f( point[5] ); endpolygon(); bgnpolygon(); v3f( point[0] ); v3f( point[1] ); v3f( point[6] ); v3f( point[4] ); endpolygon(); } initialize(box, width) /* stuff the startup stuff here */ register float box[8][3]; /* The eight vertices of the beam */ register float *width; { float aspect,x,y; /* variables to perspective function */ int gid; register float height, length; /* needed for square initialization */ prefposition(0, XMAXSCREEN/3, 0, YMAXSCREEN/3); gid = winopen ("Hollow Polygons"); /* get the window id and name it */ RGBmode(); /* I like c3i calls, no map dependencies */ lsetdepth(0,0x7fffff); /* initialize zbuffer near and far planes */ overlay(2); doublebuffer(); gconfig(); /* configure the hardware */ shademodel (FLAT); qdevice (ESCKEY); /* queue all these items */ qdevice (REDRAW); qdevice (INPUTCHANGE); qenter (REDRAW, gid); x = (float) XMAXSCREEN; /* set variables to perspective */ y = (float) YMAXSCREEN; aspect = x/y; perspective (450,aspect, 0.1,100.0); /* one viewing method */ polarview (5.0, 0, 0, 0); /* another viewing method */ *width = 2.0; height = 2.0; length = 2.0; /* static info for size of sqr */ initbeam (*width, height, length, box); /* init square */ setzbuff(); } -----------------------mangle here----------------------- -- G. "Murdock" Helms Is it so frightening Silicon Graphics to have me at your shoulder? Product Support Engineer Thunder and lightning ghelms@sgi.sgi.com couldn't be bolder.