/* split_tetra.c Rotating split_tetra with color sections */ /* 8 tetrahedrons build a tetrahedron */ /* color of faces must be shaded to see edges */ /* tetrahedrons must be offset to see "split" */ /* does wireframe make it better or worse? */ /* give command line "x" to start worse case */ /* Mouse buttons control direction of rotation */ /* "s" to get first split and color */ /* "O" and "o" make offset bigger and smaller */ /* "C" and "c" make color distinct or closer */ /* "F" and "f" make rotation faster or slower */ /* "W" and "w" make wireframe or solid */ /* "p" toggle center point */ #include #include #include #include static GLfloat vert[8193][3] = {{0.0, 0.0, 0.0}, /* unused, start with [1] */ {-1.0,-1.0,-1.0}, {-1.0, 1.0, -1.0}, /* 1,2 */ { 0.7, 0.7,-1.0}, { 0.5, 0.5, 1.0}}; /* 3,4 */ static int nvert = 4; /* increment before inserting, count not including zero*/ static int ivert[8193][4] = {{1,2,3,4}}; static int npoly = 1; /* number of 4 vertex tetrahedrons */ static int overt[8193] = {1}; /* offset toward this point */ static GLfloat xs[8193], ys[8193], zs[8193]; static int nv; static GLfloat colors[][3] = { {1.0,0.0,0.0}, {1.0,1.0,0.0}, {0.0,1.0,0.0}, {0.0,0.0,1.0}, {1.0,0.0,1.0}, {0.0,1.0,1.0}, {0.7,0.5,0.5}, {0.5,0.7,0.5}, {0.5,0.5,0.7}}; static GLfloat theta[] = {0.0,0.0,0.0}; static GLint axis = 2; static double colorset = 0.1; /* 'C' or 'c' */ static double offset = 0.2; /* 'O' or 'o' */ static double rotation = 0.5; /* 'F' or 'f' */ static int wireframe = 0; /* 'W' or 'w' */ static int hide = 0; static int pcenter = 0; static GLfloat dcenter = 16.0; /* no function prototypes used here because the functions are defined */ /* before they are used */ static void next_tetra() { int tvert[8193][4]; int tpoly; int ipoly, j, k; int p1, p2, p3, p4, p12, p13, p14, p23, p24, p34; tpoly = npoly; for(ipoly=0; ipoly 360.0) theta[axis] = theta[axis] - 360.0; /* display(); */ glutPostRedisplay(); } /* end spinSplit_tetra */ static void mouse(int btn, int state, int x, int y) { /* mouse callback, selects an axis about which to rotate */ if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0; if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1; if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2; } /* end mouse */ static void keyboard(unsigned char key, int x, int y) { switch (key) { case 'O': offset=offset+0.05; if(offset>0.5) offset=0.5; break; case 'o': offset=offset-0.05; if(offset<0.0) offset=0.0; break; case 'C': colorset=colorset+0.02; if(colorset>0.5) colorset=0.5; break; case 'c': colorset=colorset-0.02; if(colorset<0.0) colorset=0.0; break; case 'F': rotation=rotation+0.25; if(rotation>5.0) rotation=5.0; break; case 'f': rotation=rotation-0.25; if(rotation<0.0) rotation=0.0; break; case 'W': wireframe=1; break; case 'w': wireframe=0; break; case 's': /* sorry, can not undo split */ next_tetra(); /* split each into 8 */ dcenter = dcenter/2.0; break; case 'p': pcenter=1-pcenter; break; } } /* end keyboard */ static void special(int k, int x, int y) { switch(k) { case GLUT_KEY_LEFT: axis = 1; break; case GLUT_KEY_RIGHT: axis = 2; break; case GLUT_KEY_DOWN: axis = 0; break; case GLUT_KEY_UP: wireframe = 1-wireframe; break; } } static void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w <= h) /* 2.0 -> 2.5 makes objects smaller */ glOrtho(-2.5, 2.5, -2.5 * (GLfloat)h / (GLfloat)w, 2.5 * (GLfloat)h / (GLfloat)w, -10.0, 10.0); else glOrtho(-2.5 * (GLfloat)w / (GLfloat)h, 2.5 * (GLfloat)w / (GLfloat)h, -2.5, 2.5, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); } /* end myReshape */ int main(int argc, char *argv[]) { glutInit(&argc, argv); if(argc>1) { if(argv[1][0]=='x' || argv[1][1]=='x') /* start with worse recognition */ { /* for graphics class demo */ colorset = 0.0; offset = 0.0; rotation = 5.0; hide = 1; } } /* need both double buffering and z buffer */ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(500, 500); glutCreateWindow(argv[0]); glutReshapeFunc(myReshape); /* enable resize/reshape */ glutDisplayFunc(display); /* enable display */ glutIdleFunc(spinSplit_tetra); /* enable idle function */ glutMouseFunc(mouse); /* enable mouse */ glutKeyboardFunc(keyboard); /* enable keyboard */ glutSpecialFunc(special); /* enable arrow keys */ glEnable(GL_DEPTH_TEST); /* enable hidden surface removal */ glutMainLoop(); return 0; } /* end split_tetra.c */