/* Tutor intended to teach the fundamentals of using textures. Based on lightmaterial tutorial by Nate Robins. Written by Caroline Geiersbach and Scott D. Anderson scott.anderson@acm.org Summer 2003 */ #include #include #include #include #include #include #define GAP 25 //gap between subwindows int cWinWidth = 537; //command window width int cWinHeight = 537; //command window height int mWinWidth = GAP*4+256*3; //main window width int mWinHeight = GAP*3+256*2; //main window height //colors used in program twTriple white = {1,1,1}; twTriple cyan = {0,1,1}; //menu of objects typedef enum { SQUARE, CUBE, TORUS, SPHERE, ICOSAHEDRON, TEAPOT } options; void myMenu(); int rMenu; int menuNum=0; //draws object based on selected item from menu void drawObject() { switch(menuNum) { case(SQUARE): glBegin(GL_POLYGON); glTexCoord2f(0,0); glVertex2f(-1.7,1.7); glTexCoord2f(0,1); glVertex2f(-1.7,-1.7); glTexCoord2f(1,1); glVertex2f(1.7,-1.7); glTexCoord2f(1,0); glVertex2f(1.7,1.7); glEnd(); break; case(CUBE): glutSolidCube(2); break; case(TORUS): glutSolidTorus(0.4,1,20,20); break; case(SPHERE): glutSolidSphere(1.5,20,20); break; case(ICOSAHEDRON): glPushMatrix(); glScalef(1.5,1.5,1.5); glutSolidIcosahedron(); glPopMatrix(); break; case(TEAPOT): glPushMatrix(); glutSolidTeapot(1); glPopMatrix(); break; } } //cells are used in the command window; each cell has an id; a //raster location at x,y; min and max values; a current value; the //step for adjusting values; info on what the cell specifies; and //finally the format of the printed values. typedef struct _cell { int id; int x, y; GLfloat min, max; GLfloat value; GLfloat step; char* info; char* format; } cell; //1st dimension for OpenGL-generated texture mapping cell texGenx[4] = { { 26, 150, 60, -10, 10, 1, 0.1, "x", "%.1f" }, { 27, 210, 60, -10, 10, 0, 0.1, "y", "%.1f" }, { 28, 270, 60, -10, 10, 0, 0.1, "z", "%.1f" }, { 29, 350, 60, 0, 1, 0, 1.0, "", "%.1f" }, }; //2nd dimension for OpenGL-generated texture mapping cell texGeny[4] = { { 30, 150, 100, -10, 10, 0, 0.1, "x", "%.1f" }, { 31, 210, 100, -10, 10, 1, 0.1, "y", "%.1f" }, { 32, 270, 100, -10, 10, 0, 0.1, "z", "%.1f" }, { 33, 350, 100, 0, 1, 0, 1.0, "", "%.1f" }, }; cell lightPosition[4] = { { 1, 225, 140, -5.0, 5.0, 0, 0.05, "Specifies X coordinate of light vector.", "%.2f" }, { 2, 285, 140, -5.0, 5.0, 0, 0.05, "Specifies Y coordinate of light vector.", "%.2f" }, { 3, 345, 140, -5.0, 5.0, 2.0, 0.05, "Specifies Z coordinate of light vector.", "%.2f" }, { 4, 405, 140, 0.0, 1.0, 1.0, 1.0, "Specifies directional (0) or positional (1) light.", "%.2f" }, }; cell lightAmbient[4] = { { 5, 225, 180, 0.0, 1.0, 0.0, 0.01, "Specifies red ambient component of the light.", "%.2f" }, { 6, 285, 180, 0.0, 1.0, 0.0, 0.01, "Specifies green ambient component of the light.", "%.2f" }, { 7, 345, 180, 0.0, 1.0, 0.0, 0.01, "Specifies blue ambient component of the light.", "%.2f" }, { 8, 405, 180, 0.0, 1.0, 1.0, 0.01, "Specifies ambient alpha intensity of the light.", "%.2f" }, }; cell lightDiffuse[4] = { { 9, 220, 220, 0.0, 1.0, 1.0, 0.01, "Specifies red diffuse component of the light.", "%.2f" }, { 10, 280, 220, 0.0, 1.0, 1.0, 0.01, "Specifies green diffuse component of the light.", "%.2f" }, { 11, 340, 220, 0.0, 1.0, 1.0, 0.01, "Specifies blue diffuse component of the light.", "%.2f" }, { 12, 400, 220, 0.0, 1.0, 1.0, 0.01, "Specifies diffuse alpha intensity of the light.", "%.2f" }, }; cell lightSpecular[4] = { { 13, 230, 260, 0.0, 1.0, 1.0, 0.01, "Specifies red specular component of the light.", "%.2f" }, { 14, 290, 260, 0.0, 1.0, 1.0, 0.01, "Specifies green specular component of the light.", "%.2f" }, { 15, 350, 260, 0.0, 1.0, 1.0, 0.01, "Specifies blue specular component of the light.", "%.2f" }, { 16, 410, 260, 0.0, 1.0, 1.0, 0.01, "Specifies specular alpha intensity of the light.", "%.2f" }, }; cell gAmbient[1] = { { 17, 115, 300, 0.0, 1.0, 0.7, 0.01, "Specifies global ambient light value.", "%.2f" }, }; cell material[5] = { { 21, 200, 340, 0.0, 1.0, 0.5, 0.01, "Specifies red component of the material.", "%.2f" }, { 22, 280, 340, 0.0, 1.0, 0.7, 0.01, "Specifies green component of the material.", "%.2f" }, { 23, 360, 340, 0.0, 1.0, 0.5, 0.01, "Specifies blue component of the material.", "%.2f" }, { 24, 180, 380, 0.0, 1.0, 0.7, 0.01, "Specifies specularity of the material.", "%.2f" }, { 25, 260, 380, 0.0, 128, 30.0, 1.0, "Specifies shininess of the material.", "%.2f" }, }; GLboolean savedDraw = GL_TRUE; GLint selection = 0; int old_y; //for command mouse //temp values for lighting and material GLfloat posTemp[4], lATemp[4], lDTemp[4], lSTemp[4], twCTemp[5]; GLfloat lGATemp = gAmbient[0].value; //temp values for texture mapping GLfloat texTempx[4]; GLfloat texTempy[4]; void redisplayAll(void); GLdouble projection[16], modelview[16], inverse[16]; GLuint window, adjustable, saved, command; void cellDraw(cell* cell) { twColor(white,0,0); //color of unselected numbers if (selection == cell->id) { twColor(cyan,0,0); //color of info text twDrawString(10, 20, cell->info); } twDrawString(cell->x, cell->y, cell->format, cell->value); } //returns cell id if cell has been clicked on; 0 otherwise int cellHit(cell* cell, int x, int y) { if (x > cell->x && x < cell->x+55 && y > cell->y-15 && y < cell->y+15){ return cell->id; } return 0; } //updates the cell's value void cellUpdate(cell* cell, int update) { if (selection != cell->id) return; cell->value += update * cell->step; //tests for min and max values of the points if (cell->value < cell->min) cell->value = cell->min; else if (cell->value > cell->max) cell->value = cell->max; } //converts values from cell to a destination vector void cellVector(GLfloat* dst, cell* cell, int num) { while (--num >= 0) dst[num] = cell[num].value; } void mainDisplay() { //set up camera to allow for window labeling glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0,mWinWidth,mWinHeight,0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0.7, 0.7, 1.0, 0.0); //light blue background glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); twColorName(TW_BLACK); twSetFont("helvetica", 12); twDrawString(GAP,20, "Saved"); twDrawString(GAP,GAP+256+20, "Adjustable"); glutSwapBuffers(); } void adjustableLighting() { GLfloat pos[4], lA[4], lD[4], lS[4]; GLfloat twC[3], lGA[4]; //convert vals from cells to vectors cellVector(pos, lightPosition, 4); cellVector(lA, lightAmbient, 4); cellVector(lD, lightDiffuse, 4); cellVector(lS, lightSpecular, 4); //lighting glShadeModel(GL_SMOOTH); twAmbient(gAmbient[0].value); glLightfv(GL_LIGHT0, GL_POSITION, pos); glLightfv(GL_LIGHT0, GL_AMBIENT, lA); glLightfv(GL_LIGHT0, GL_DIFFUSE, lD); glLightfv(GL_LIGHT0, GL_SPECULAR, lS); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); } //display in the lower left (adjustable-space view) void adjustableDisplay() { twCamera(); glClearColor(0.7,0.7,0.7,1); //clear sub-window to black glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); adjustableLighting(); //texture GLfloat tex[4] = {texGenx[0].value,texGenx[1].value, texGenx[2].value,texGenx[3].value}; GLfloat tex1[4] = {texGeny[0].value,texGeny[1].value, texGeny[2].value,texGeny[3].value}; glBindTexture(GL_TEXTURE_2D, 1); twTriple colorVal = {material[0].value, material[1].value, material[2].value}; twColor(colorVal, material[3].value,material[4].value); glEnable(GL_TEXTURE_2D); if(menuNum==0) drawObject();//square else { glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S,GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S,GL_OBJECT_PLANE,tex); glTexGenfv(GL_T,GL_OBJECT_PLANE,tex1); drawObject(); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); } glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); //draw line from light source to center of object glPushMatrix(); twColor(white,0,0); glLineWidth(2); glBegin(GL_LINE_STRIP); glVertex3f(0, 0, 0); glVertex3f(lightPosition[0].value, lightPosition[1].value, lightPosition[2].value); glEnd(); glPopMatrix(); glFlush(); glutSwapBuffers(); } void savedLighting() { //convert vals from cells to vectors if(savedDraw) { //get new values cellVector(posTemp, lightPosition, 4); cellVector(lATemp, lightAmbient, 4); cellVector(lDTemp, lightDiffuse, 4); cellVector(lSTemp, lightSpecular, 4); cellVector(twCTemp, material,5); cellVector(texTempx, texGenx,4); cellVector(texTempy, texGeny,4); lGATemp = gAmbient[0].value; } savedDraw = GL_FALSE; //lighting glShadeModel(GL_SMOOTH); twAmbient(lGATemp); glLightfv(GL_LIGHT1, GL_POSITION, posTemp); glLightfv(GL_LIGHT1, GL_AMBIENT, lATemp); glLightfv(GL_LIGHT1, GL_DIFFUSE, lDTemp); glLightfv(GL_LIGHT1, GL_SPECULAR, lSTemp); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); } //display in the upper left (saved) void savedDisplay() { twCamera(); glClearColor(0.7,0.7,0.7,1); //clear sub-window to black glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); savedLighting(); glBindTexture(GL_TEXTURE_2D, 1); twTriple colorVal2 = {twCTemp[0],twCTemp[1],twCTemp[2]}; twColor(colorVal2, twCTemp[3],twCTemp[4]); glEnable(GL_TEXTURE_2D); if(menuNum==0) drawObject(); else { glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S,GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S,GL_OBJECT_PLANE,texTempx); glTexGenfv(GL_T,GL_OBJECT_PLANE,texTempy); drawObject(); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); } glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); //draw line from light source to center of object glPushMatrix(); twColor(white,0,0); glLineWidth(2); glBegin(GL_LINE_STRIP); glVertex3f(0, 0, 0); glVertex3f(posTemp[0],posTemp[1],posTemp[2]); glEnd(); glPopMatrix(); glFlush(); glutSwapBuffers(); } //display on right side; where user can adjust values void commandDisplay() { //set up camera glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, cWinWidth, cWinHeight, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0.0, 0.0, 0.0, 1.0); //clear to black glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); twSetFont("helvetica", 18); if(menuNum>0) { //does not apply to square twDrawString(10, texGenx[0].y, "texGenx[ ] = {"); twDrawString(texGenx[0].x +50, texGenx[0].y, ","); twDrawString(texGenx[1].x +50, texGenx[1].y, ","); twDrawString(texGenx[2].x +50, texGenx[2].y, ","); twDrawString(texGenx[3].x +50, texGenx[3].y, "};"); cellDraw(&texGenx[0]); cellDraw(&texGenx[1]); cellDraw(&texGenx[2]); cellDraw(&texGenx[3]); twDrawString(10, texGeny[0].y, "texGeny[ ] = {"); twDrawString(texGeny[0].x +50, texGeny[0].y, ","); twDrawString(texGeny[1].x +50, texGeny[1].y, ","); twDrawString(texGeny[2].x +50, texGeny[2].y, ","); twDrawString(texGeny[3].x +50, texGeny[3].y, "};"); cellDraw(&texGeny[0]); cellDraw(&texGeny[1]); cellDraw(&texGeny[2]); cellDraw(&texGeny[3]); } twDrawString(10, lightPosition[0].y, "GLfloat lightPosition[ ] = {"); twDrawString(10, lightAmbient[0].y, "GLfloat lightAmbient[ ] = {"); twDrawString(10, lightDiffuse[0].y, "GLfloat lightDiffuse[ ] = {"); twDrawString(10, lightSpecular[0].y, "GLfloat lightSpecular[ ] = {"); twDrawString(10, gAmbient[0].y, "twAmbient ("); twDrawString(10, material[0].y, "twTriple colorVals = ("); twDrawString(10, material[3].y, "twColor(colorVals,"); twDrawString(lightPosition[0].x+50, lightPosition[0].y, ","); twDrawString(lightPosition[1].x+50, lightPosition[1].y, ","); twDrawString(lightPosition[2].x+50, lightPosition[2].y, ","); twDrawString(lightPosition[3].x+50, lightPosition[3].y, "};"); twDrawString(lightAmbient[0].x+50, lightAmbient[0].y, ","); twDrawString(lightAmbient[1].x+50, lightAmbient[1].y, ","); twDrawString(lightAmbient[2].x+50, lightAmbient[2].y, ","); twDrawString(lightAmbient[3].x+50, lightAmbient[3].y, "};"); twDrawString(lightDiffuse[0].x+50, lightDiffuse[0].y, ","); twDrawString(lightDiffuse[1].x+50, lightDiffuse[1].y, ","); twDrawString(lightDiffuse[2].x+50, lightDiffuse[2].y, ","); twDrawString(lightDiffuse[3].x+50, lightDiffuse[3].y, "};"); twDrawString(lightSpecular[0].x+50, lightSpecular[0].y, ","); twDrawString(lightSpecular[1].x+50, lightSpecular[1].y, ","); twDrawString(lightSpecular[2].x+50, lightSpecular[2].y, ","); twDrawString(lightSpecular[3].x+50, lightSpecular[3].y, "};"); twDrawString(gAmbient[0].x+50, gAmbient[0].y, ");"); twDrawString(material[0].x+50, material[0].y, ","); twDrawString(material[1].x+50, material[1].y, ","); twDrawString(material[2].x+50, material[2].y, ");"); twDrawString(material[3].x+50, material[3].y, ","); twDrawString(material[4].x+60, material[4].y, ");"); //draw values of each cell cellDraw(&lightPosition[0]); cellDraw(&lightPosition[1]); cellDraw(&lightPosition[2]); cellDraw(&lightPosition[3]); cellDraw(&lightAmbient[0]); cellDraw(&lightAmbient[1]); cellDraw(&lightAmbient[2]); cellDraw(&lightAmbient[3]); cellDraw(&lightDiffuse[0]); cellDraw(&lightDiffuse[1]); cellDraw(&lightDiffuse[2]); cellDraw(&lightDiffuse[3]); cellDraw(&lightSpecular[0]); cellDraw(&lightSpecular[1]); cellDraw(&lightSpecular[2]); cellDraw(&lightSpecular[3]); cellDraw(&gAmbient[0]); cellDraw(&material[0]); cellDraw(&material[1]); cellDraw(&material[2]); cellDraw(&material[3]); cellDraw(&material[4]); if (!selection) { twColor(cyan,0,0); twDrawString(10, 20, "Click on the arguments and move the mouse to modify values."); } //directions at bottom of saved twDrawString(10,420,"Hit to save values,

to print saved values."); twDrawString(10,460,"Hit to reset adjustable to original values."); twDrawString(10,500,"Hit to reset adjustable to original view."); twColor(white,0,0); glutSwapBuffers(); } void commandMouse(int button, int state, int x, int y) { selection = 0; if(state == GLUT_DOWN) { /* mouse should only hit _one_ of the cells, so adding up all the hits just propagates a single hit. */ //lighting selection += cellHit(&texGenx[0], x, y); selection += cellHit(&texGenx[1], x, y); selection += cellHit(&texGenx[2], x, y); selection += cellHit(&texGenx[3], x, y); selection += cellHit(&texGeny[0], x, y); selection += cellHit(&texGeny[1], x, y); selection += cellHit(&texGeny[2], x, y); selection += cellHit(&texGeny[3], x, y); selection += cellHit(&lightPosition[0], x, y); selection += cellHit(&lightPosition[1], x, y); selection += cellHit(&lightPosition[2], x, y); selection += cellHit(&lightPosition[3], x, y); selection += cellHit(&lightAmbient[0], x, y); selection += cellHit(&lightAmbient[1], x, y); selection += cellHit(&lightAmbient[2], x, y); selection += cellHit(&lightAmbient[3], x, y); selection += cellHit(&lightDiffuse[0], x, y); selection += cellHit(&lightDiffuse[1], x, y); selection += cellHit(&lightDiffuse[2], x, y); selection += cellHit(&lightDiffuse[3], x, y); selection += cellHit(&lightSpecular[0], x, y); selection += cellHit(&lightSpecular[1], x, y); selection += cellHit(&lightSpecular[2], x, y); selection += cellHit(&lightSpecular[3], x, y); selection += cellHit(&gAmbient[0], x, y); selection += cellHit(&material[0], x, y); selection += cellHit(&material[1], x, y); selection += cellHit(&material[2], x, y); selection += cellHit(&material[3], x, y); selection += cellHit(&material[4], x, y); } old_y = y; redisplayAll(); } //allows for click and drag void commandMotion(int x, int y) { cellUpdate(&texGenx[0], old_y-y); cellUpdate(&texGenx[1], old_y-y); cellUpdate(&texGenx[2], old_y-y); cellUpdate(&texGenx[3], old_y-y); cellUpdate(&texGeny[0], old_y-y); cellUpdate(&texGeny[1], old_y-y); cellUpdate(&texGeny[2], old_y-y); cellUpdate(&texGeny[3], old_y-y); cellUpdate(&lightPosition[0], old_y-y); cellUpdate(&lightPosition[1], old_y-y); cellUpdate(&lightPosition[2], old_y-y); cellUpdate(&lightPosition[3], old_y-y); cellUpdate(&lightAmbient[0], old_y-y); cellUpdate(&lightAmbient[1], old_y-y); cellUpdate(&lightAmbient[2], old_y-y); cellUpdate(&lightAmbient[3], old_y-y); cellUpdate(&lightDiffuse[0], old_y-y); cellUpdate(&lightDiffuse[1], old_y-y); cellUpdate(&lightDiffuse[2], old_y-y); cellUpdate(&lightDiffuse[3], old_y-y); cellUpdate(&lightSpecular[0], old_y-y); cellUpdate(&lightSpecular[1], old_y-y); cellUpdate(&lightSpecular[2], old_y-y); cellUpdate(&lightSpecular[3], old_y-y); cellUpdate(&gAmbient[0], old_y-y); cellUpdate(&material[0], old_y-y); cellUpdate(&material[1], old_y-y); cellUpdate(&material[2], old_y-y); cellUpdate(&material[3], old_y-y); cellUpdate(&material[4], old_y-y); old_y = y; redisplayAll(); } void reset(unsigned char key, int x, int y) { switch(key) { case'R': texGenx[0].value = 1; texGenx[1].value = 0; texGenx[2].value = 0; texGenx[3].value = 0; texGeny[0].value = 0; texGeny[1].value = 1; texGeny[2].value = 0; texGeny[3].value = 0; lightPosition[0].value = 0; lightPosition[1].value = 0; lightPosition[2].value = 2; lightPosition[3].value = 1; lightAmbient[0].value = 0; lightAmbient[1].value = 0; lightAmbient[2].value = 0; lightAmbient[3].value = 1; lightDiffuse[0].value = 1; lightDiffuse[1].value = 1; lightDiffuse[2].value = 1; lightDiffuse[3].value = 1; lightSpecular[0].value = 1; lightSpecular[1].value = 1; lightSpecular[2].value = 1; lightSpecular[3].value = 1; gAmbient[0].value = 0.7; material[0].value = 0.5; material[1].value = 0.7; material[2].value = 0.5; material[3].value = 0.7; material[4].value = 30.0; break; case'r': glutSetWindow(adjustable); twZview(); glutSetWindow(saved); twZview(); break; } redisplayAll(); } void myKeyboard(unsigned char key, int x, int y) { switch(key) { case 'P': printf("your saved light and material values: \n"); printf("texGenx[] = {%.2f,%.2f,%.2f,%.2f}\n", texTempx[0], texTempx[1],texTempx[2],texTempx[3]); printf("texGeny[] = {%.2f,%.2f,%.2f,%.2f}\n", texTempy[0], texTempy[1],texTempy[2],texTempy[3]); printf("lightPosition[] = {%.2f,%.2f,%.2f,%.2f}\n", posTemp[0],posTemp[1],posTemp[2],posTemp[3]); printf("lightAmbient[] = {%.2f,%.2f,%.2f,%.2f}\n", lATemp[0],lATemp[1],lATemp[2],lATemp[3]); printf("lightDiffuse[] = {%.2f,%.2f,%.2f,%.2f}\n", lDTemp[0],lDTemp[1],lDTemp[2],lDTemp[3]); printf("lightSpecular[] = {%.2f,%.2f,%.2f,%.2f}\n", lSTemp[0],lSTemp[1],lSTemp[2],lSTemp[3]); printf("twAmbient(%.2f)\n",lGATemp); printf("colorVals = {%.2f,%.2f,%.2f}\n",twCTemp[0], twCTemp[1],twCTemp[2]); printf("twColor=(colorVals,%.2f,%.2f)\n", twCTemp[3],twCTemp[4]); break; case 'S': savedDraw = GL_TRUE; break; } redisplayAll(); } void keyInit() { twKeyCallback('R',reset,"resets back to original settings"); twKeyCallback('r',reset,"resets back to original view"); twKeyCallback('P',myKeyboard,"prints saved values"); twKeyCallback('S',myKeyboard,"saves current values"); } void menuCallback(int id) { glutDestroyMenu(rMenu); myMenu(); redisplayAll(); menuNum = id; } void myMenu() { rMenu = glutCreateMenu(menuCallback); glutAddMenuEntry("Square", SQUARE); glutAddMenuEntry("Cube", CUBE); glutAddMenuEntry("Torus", TORUS); glutAddMenuEntry("Sphere", SPHERE); glutAddMenuEntry("Icosahedron", ICOSAHEDRON); glutAddMenuEntry("Teapot", TEAPOT); glutAttachMenu(GLUT_RIGHT_BUTTON); } void redisplayAll(void) { glutSetWindow(saved); glutPostRedisplay(); glutSetWindow(command); glutPostRedisplay(); glutSetWindow(adjustable); glutPostRedisplay(); } //these are things that should work with any window void myInit() { twMainInit(); keyInit(); myMenu(); } void chomp(char* s) { int len = strlen(s); if( s[len-1] == '\n' ) s[len-1] = '\0'; } int main(int argc, char** argv) { if( argc < 2 ) { printf("Usage: %s PPMfile\n",argv[0]); exit(0); } glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); twInitWindowSize(mWinWidth,mWinHeight); glutInitWindowPosition(0, 0); glutInit(&argc, argv); //parent window window = glutCreateWindow("Light & Material Tutor"); glutDisplayFunc(mainDisplay); myInit(); //upper left sub-window saved = glutCreateSubWindow(window, GAP, GAP, 256, 256); twBoundingBox(-1,1,-1,1,-1,1); glutDisplayFunc(savedDisplay); twLoadTexture(1,argv[1]); myInit(); //right sub-window command = glutCreateSubWindow(window, GAP*2+256, GAP, cWinWidth,cWinHeight); glutDisplayFunc(commandDisplay); myInit(); glutMotionFunc(commandMotion); glutMouseFunc(commandMouse); //lower left sub-window adjustable = glutCreateSubWindow(window, GAP, GAP*2+256, 256, 256); twBoundingBox(-1,1,-1,1,-1,1); glutDisplayFunc(adjustableDisplay); twLoadTexture(1,argv[1]); myInit(); redisplayAll(); glutMainLoop(); return 0; }