/* mytex.c * Ray S. Babcock, CS425, F'02 * * This program demonstrates the use of the GL lighting * system with a texture mapped cube. * * Draw a cube, then map a different image to each of * two faces. * * Slow fly-around the entire scene */ #include #include #include #include #include "targa.h" /* DELTA_DEG is the increment for rotation, useful for * different speed computers. Set lower to slow down rotation. */ #define DELTA_DEG 3.0 #define DELTA_FLY_RAD 0.02 static double rot_deg = 0.0; static double fly_rad = 0.0; static double flyx=0.0, flyy=0.0, flyz=0.0; static int n,m; static float s; static int n2,m2; static float s2; /* LIGHT0 position vector */ static GLfloat light0_position[]={1.0, 0.0, 1.0, 0.0}; static TGAFILE *myTGA; static TGAFILE *myTGA2; void draw_scene(); void display(void); void rotate_objects(void); void mainMenu(int); int LoadTGAFile(char *filename, TGAFILE *tgaFile) { FILE *filePtr; unsigned char ucharBad; short int sintBad; long imageSize; int colorMode; long imageIdx; unsigned char colorSwap; // open the TGA file filePtr = fopen(filename, "rb"); if(!filePtr) return 0; // read first two bytes of data we don't need fread(&ucharBad, sizeof(unsigned char), 1, filePtr); fread(&ucharBad, sizeof(unsigned char), 1, filePtr); // read in the image type fread(&tgaFile->imageTypeCode, sizeof(unsigned char), 1, filePtr); // for our purposes, the image type should be either a 2 or a 3 if((tgaFile->imageTypeCode != 2) && (tgaFile->imageTypeCode != 3)) { fclose(filePtr); return 0; } // read 9 bytes of data we don't need fread(&sintBad, sizeof(short int), 1, filePtr); fread(&sintBad, sizeof(short int), 1, filePtr); fread(&ucharBad, sizeof(unsigned char), 1, filePtr); fread(&sintBad, sizeof(short int), 1, filePtr); fread(&sintBad, sizeof(short int), 1, filePtr); // read image dimensions fread(&tgaFile->imageWidth, sizeof(short int), 1, filePtr); fread(&tgaFile->imageHeight, sizeof(short int), 1, filePtr); // read image bit depth fread(&tgaFile->bitCount, sizeof(unsigned char), 1, filePtr); // read 1 byte of data we don't need fread(&ucharBad, sizeof(unsigned char), 1, filePtr); // colorMode -> 3 = BGF, 4 = BGRA colorMode = tgaFile->bitCount / 8; imageSize = tgaFile->imageWidth * tgaFile->imageHeight * colorMode; // allocate memory for image data tgaFile->imageData = (unsigned char *)malloc(sizeof(unsigned char)*imageSize); // read in image data fread(tgaFile->imageData, sizeof(unsigned char), imageSize, filePtr); // change BGR to RGB so OpenGL can read the image data for (imageIdx = 0; imageIdx < imageSize; imageIdx += colorMode) { colorSwap = tgaFile->imageData[imageIdx]; tgaFile->imageData[imageIdx] = tgaFile->imageData[imageIdx + 2]; tgaFile->imageData[imageIdx+2] = colorSwap; } // close the file fclose(filePtr); return 1; } void mycube(void) { GLfloat vertices[][3] = { {-1.0, -1.0, -1.0}, { 1.0, -1.0, -1.0}, { 1.0, 1.0, -1.0}, {-1.0, 1.0, -1.0}, {-1.0, -1.0, 1.0}, { 1.0, -1.0, 1.0}, { 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0}}; GLubyte frontIndices[] = { 4, 5, 6, 7 }; GLubyte rightIndices[] = { 5, 1, 2, 6 }; GLubyte bottomIndices[] = { 0, 1, 5, 4 }; GLubyte backIndices[] = { 1, 0, 3, 2 }; GLubyte leftIndices[] = { 0, 4, 7, 3 }; GLubyte topIndices[] = { 7, 6, 2, 3 }; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vertices); /* front face */ glNormal3f(0.0, 0.0, 1.0); /* map the first image to this face */ glTexImage2D(GL_TEXTURE_2D,0,3, myTGA->imageWidth, myTGA->imageHeight, 0,GL_RGB,GL_UNSIGNED_BYTE, myTGA->imageData); glPixelStorei(GL_UNPACK_SWAP_BYTES,GL_TRUE); glPixelStorei(GL_UNPACK_ALIGNMENT,4); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBegin(GL_QUADS); glTexCoord2f(0.4, 0.6); glVertex3fv(vertices[frontIndices[0]]); glTexCoord2f(0.6, 0.6); glVertex3fv(vertices[frontIndices[1]]); glTexCoord2f(0.6,0.4); glVertex3fv(vertices[frontIndices[2]]); glTexCoord2f(0.4, 0.4); glVertex3fv(vertices[frontIndices[3]]); glEnd(); /* right face */ glNormal3f(1.0, 0.0, 0.0); /* map the second image to the right face */ glTexImage2D(GL_TEXTURE_2D,0,3, myTGA2->imageWidth, myTGA2->imageHeight, 0,GL_RGB,GL_UNSIGNED_BYTE, myTGA2->imageData); glPixelStorei(GL_UNPACK_SWAP_BYTES,GL_TRUE); glPixelStorei(GL_UNPACK_ALIGNMENT,4); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBegin(GL_QUADS); glTexCoord2f(0.0,1.0); glVertex3fv(vertices[rightIndices[0]]); glTexCoord2f(1.0,1.0); glVertex3fv(vertices[rightIndices[1]]); glTexCoord2f(1.0,0.0); glVertex3fv(vertices[rightIndices[2]]); glTexCoord2f(0.0,0.0); glVertex3fv(vertices[rightIndices[3]]); glEnd(); /* bottom face */ glNormal3f(0.0, -1.0, 0.0); glDrawElements(GL_POLYGON, 4, GL_UNSIGNED_BYTE, bottomIndices); /* back face */ glNormal3f(0.0, 0.0, -1.0); glDrawElements(GL_POLYGON, 4, GL_UNSIGNED_BYTE, backIndices); /* left face */ glNormal3f(-1.0, 0.0, 0.0); glDrawElements(GL_POLYGON, 4, GL_UNSIGNED_BYTE, leftIndices); /* top face */ glNormal3f(0.0, 1.0, 0.0); glDrawElements(GL_POLYGON, 4, GL_UNSIGNED_BYTE, topIndices); glDisableClientState(GL_VERTEX_ARRAY); } void myinit (void) { /* define global light vectors */ GLfloat global_light_ambient[]={0.3, 0.0, 0.0, 1.0}; /* define light0 vectors */ GLfloat light0_ambient[]={0.0, 0.0, 0.0, 1.0}; GLfloat light0_diffuse[]={1.0, 1.0, 1.0, 1.0}; GLfloat light0_specular[]={1.0, 1.0, 1.0, 1.0}; /* define material vectors */ GLfloat mat_ambient[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat_diffuse[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat_specular[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat_shiny[]={100.0}; GLfloat mat2_ambient[]={0.2, 0.2, 0.2, 1.0}; GLfloat mat2_diffuse[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat2_specular[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat2_shiny[]={100.0}; glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(20.0, 1.0, 1.0, 200.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity(); /* initial lookat call */ gluLookAt(20.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_light_ambient); /* define LIGHT0 */ glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.0); /* Turn on lighting */ //glEnable(GL_LIGHTING); /* Turn on LIGHT0 */ glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glShadeModel (GL_SMOOTH); glEnable(GL_TEXTURE_2D); } void rotate_objects() { /* rotate degrees for object */ /* currently this is unused */ rot_deg += DELTA_DEG; if(rot_deg>=360.0) rot_deg=0.0; /* rotate radians for fly around */ /* this one is used for the cube */ fly_rad += DELTA_FLY_RAD; if(fly_rad>=6.2831) fly_rad=0.0; flyz = cos(fly_rad); flyx = sin(fly_rad); glutPostRedisplay(); } void draw_scene() { GLfloat mat2_ambient[]={0.2, 0.2, 0.2, 1.0}; GLfloat mat2_diffuse[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat2_specular[]={1.0, 1.0, 1.0, 1.0}; GLfloat mat2_shiny[]={100.0}; glMaterialfv(GL_FRONT, GL_AMBIENT, mat2_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat2_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat2_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat2_shiny); glLoadIdentity(); /* position light before lookat call to keep it with view */ glLightfv(GL_LIGHT0, GL_POSITION, light0_position); gluLookAt(flyx*20.0, 6.0, flyz*20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); mycube(); } void display (void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); draw_scene(); glFlush(); glutSwapBuffers(); } void myReshape(int w, int h) { /* minimal reshape support */ glViewport (0, 0, w, h); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: /* escape key */ exit(0); break; } } /* Left in for menu support */ void mainMenu(int value) { switch(value) { case 1: { } break; case 2: { } break; case 3: { } break; case 4: { } break; case 5: { } break; case 6: { exit(0); } break; case 7: { } break; case 8: { } break; case 9: { } break; }; } void makeMenu(void) { int menu_id; menu_id=glutCreateMenu(mainMenu); glutAddMenuEntry("wire frame",1); glutAddMenuEntry("solid flat",2); glutAddMenuEntry("solid smooth",3); glutAddMenuEntry("Show Normals",4); glutAddMenuEntry("Hide Normale",5); glutAddMenuEntry("exit program",6); glutAddMenuEntry("cube",7); glutAddMenuEntry("teapot",8); glutAddMenuEntry("torus",9); glutAttachMenu(GLUT_RIGHT_BUTTON); } /* Main Loop * Open window with initial window size, title bar, * RGB display mode, and handle input events. */ int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (400, 400); glutCreateWindow (argv[0]); myinit (); glutIdleFunc(rotate_objects); glutReshapeFunc (myReshape); glutDisplayFunc(display); glutKeyboardFunc (keyboard); makeMenu(); /* load the image files */ myTGA = (TGAFILE *)malloc(sizeof(TGAFILE)); LoadTGAFile("ray3b.tga", myTGA); myTGA2 = (TGAFILE *)malloc(sizeof(TGAFILE)); LoadTGAFile("cateqa.tga", myTGA2); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }