/* split_tetra2.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 */ /* "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 */ /* "s" split each tetrahedron into 4 tetrahedron */ #include #include #include static GLfloat vertices[1525][3] = {{0.0, 0.0, 0.0}, /* unused, start with [1] */ {-0.500,-0.250,-0.250}, { 0.500, -0.250, -0.250}, /* 1,2 */ { 0.000, 0.616,-0.250}, { 0.000, 0.000, 0.616}}; /* 3,4 */ static int nvert = 4; /* increment before inserting, count not including zero */ static int ivert[1025][4] = {{1,2,3,4}}; static int overt[1025] = {1}; /* offset toward this point */ static int npoly = 1; 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; /* no function prototypes used here because the functions are defined */ /* before they are used */ static void next_tetra() { int tvert[257][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': next_tetra(); 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 */