Hollow Polygon implementation (C source for same)

Gretchen Helms ghelms at hellfire.csd.sgi.com
Sat Sep 29 05:34:26 AEST 1990


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 at sgi.sgi.com				couldn't be bolder.



More information about the Comp.sys.sgi mailing list