#include #include #include #include #define MAXSEGMENT 100 #define MAXLINE 1000 #define WALLHEIGHT 100 #define SCALEFACTOR 0.3 #define PI 3.14159 // these are the windowparameters int width; int height; // this is for mousekeeping information int oldx,oldy,oldz,status; float oldangle,oldhangle; // initial position float angle = 190.0; float headangle = 0.0; float posx = -102.0; float posy = 183.0; float posz = 0.0; // this is named a bit incorrectly... z is the height! // debugging variables char s[12]; float r = 0.5; float g = 0.5; float b = 0.5; int myvar = 0; // texture stuff GLuint GrassTexture,WallTexture; GLubyte* grassimage; GLubyte* wallimage; int grassimagewidth,wallimagewidth; int grassimageheight,wallimageheight; typedef struct vertex { float x; float y; float z; } Vertex; typedef int Triangle [3]; // These define the rough steps the snowman is doing. Vertex SnowManFrames[] ={{12.9,0.5,-0.2},{11.4,4.2,-0.2},{10.2,7.6,-0.2}, {8.7,11.6,-0.2},{7.5,15.0,-0.2},{5.5,18.2,-0.2},{2.6,20.0,-0.2},{-29.9,20.1,-0.2}, {-44.5,-0.4,0.5},{-27.4,-0.4,-17.9},{-2.9,-0.4,-23.9},{17.5,-0.4,-13.4},{20.3,-0.4,0.2}}; int numSnowManFrames = sizeof (SnowManFrames) / sizeof (Vertex); // interesting place to include this, but hey, it works... // this is basically to make this file somewhat smaller! #include "./water.h" #include "./Creaturesb.h" // Here comes stuff for the updated Creatures SNOWMAN* SnowMan; FLOWERCAR* FlowerCar; OFFCREATURE* Tower; PAPERBIRD* Bird; SurfaceClass* Water; // Code for loading PPM files void readimage (char* FileName,GLubyte* &image, int &imagewidth, int &imageheight) { FILE * ppmfile = fopen (FileName, "r"); fscanf (ppmfile, "P6\n%d %d\n255\n", &imagewidth, &imageheight); image = new GLubyte [imagewidth * imageheight * 3]; fread (image, imagewidth * 3, imageheight, ppmfile); fclose (ppmfile); } void display () { static int time = 0; static int snowmanframe = 0; static float flowercarframe = 0; int i; int j; time++; glClearColor (0.0, 0.0, 1.0, 0.0); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glFrustum (-1.0, 1.0, -1.0, 1.0, 1.0, 5000.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glRotatef (angle, 0.0, 1.0, 0.0); glRotatef (headangle, cos(angle/180.0*PI),0.0,sin(angle/180.0*PI)); glTranslatef (posx, posz, posy); { static float lightangle = 0.0; GLfloat position [] = { 0.0, 0.0, 0.0, 1.0 }; glPushMatrix (); glRotatef (lightangle*5.0, 0.3, 0.5, 0.2); glTranslatef (200.0,10.0, 0.0); glColor3f(1.0,1.0,0.0); glutSolidSphere (10.0,20.0,20.0); glTranslatef (20.0,10.0, 0.0); glLightfv (GL_LIGHT0, GL_POSITION, position); glPopMatrix (); lightangle += 3.0; } // draw the Grass and the poolsides here. glPushMatrix(); glTranslatef (-488, -100.0, -284); // glScalef(r*20.0,10.0,r*10.0); glScalef(540.0,10.0,270.0); // glColor3f(1.0,0.0,0.0); // Draw sides of Pool // glColor3f(1.0,0.0,0.0); glEnable (GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, WallTexture); float hor_tiling=3.0; float ver_tiling=1.2; glColor3f(0.02,0.87,0.2); glBegin (GL_QUADS); // east face glTexCoord2f(0.0,0.0); glVertex3f(0.0,0.0,0.0); glTexCoord2f(hor_tiling,0.0); glVertex3f(1.0,0.0,0.0); glTexCoord2f(hor_tiling,ver_tiling); glVertex3f(1.0,-5.0,0.0); glTexCoord2f(0.0,ver_tiling); glVertex3f(0.0,-5.0,0.0); //south face glTexCoord2f(0.0,0.0); glVertex3f(1.0,0.0,0.0); glTexCoord2f(hor_tiling,0.0); glVertex3f(1.0,0.0,1.0); glTexCoord2f(hor_tiling,ver_tiling); glVertex3f(1.0,-5.0,1.0); glTexCoord2f(0.0,ver_tiling); glVertex3f(1.0,-5.0,0.0); // west face glTexCoord2f(0.0,0.0); glVertex3f(1.0,0.0,1.0); glTexCoord2f(hor_tiling,0.0); glVertex3f(0.0,0.0,1.0); glTexCoord2f(hor_tiling,ver_tiling); glVertex3f(0.0,-5.0,1.0); glTexCoord2f(0.0,ver_tiling); glVertex3f(1.0,-5.0,1.0); // north face glTexCoord2f(0.0,0.0); glVertex3f(0.0,0.0,0.0); glTexCoord2f(hor_tiling,0.0); glVertex3f(0.0,0.0,1.0); glTexCoord2f(hor_tiling,ver_tiling); glVertex3f(0.0,-5.0,1.0); glTexCoord2f(0.0,ver_tiling); glVertex3f(0.0,-5.0,0.0); glEnd(); glDisable(GL_TEXTURE_2D); // Draw the Stencil glEnable(GL_STENCIL_TEST); glClear(GL_STENCIL_BUFFER_BIT); glStencilFunc(GL_ALWAYS,0x1,0x1); glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE); glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); glDepthMask(GL_FALSE); glBegin (GL_QUADS); glVertex3f(0.0,0.0,0.0); glVertex3f(1.0,0.0,0.0); glVertex3f(1.0,0.0,1.0); glVertex3f(0.0,0.0,1.0); glEnd(); // Draw the Grass glStencilFunc(GL_NOTEQUAL,0x1,0x1); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); glDepthMask(GL_TRUE); glColor3f(1.0,1.0,1.0); glEnable (GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, GrassTexture); glBegin (GL_QUADS); glTexCoord2f(0.0,0.0); glVertex3f(-10.0,0.0,-10.0); glTexCoord2f(80.0,0.0); glVertex3f(10.0,0.0,-10.0); glTexCoord2f(80.0,80.0); glVertex3f(10.0,0.0,10.0); glTexCoord2f(0.0,80.0); glVertex3f(-10.0,0.0,10.0); glEnd(); glDisable (GL_TEXTURE_2D); glDisable(GL_STENCIL_TEST); glPopMatrix(); // do the Flower glPushMatrix (); glTranslatef (FlowerCar->X(), FlowerCar->Y(), FlowerCar->Z()); glRotatef (90.0+FlowerCar->Angle(), 0.0, 1.0, 0.0); glScalef (10.0, 10.0, 10.0); switch (FlowerCar->Animate()) { case 0 : // waiting for new instructions when FINISHED (=0) { FlowerCar->SetMove(-144.0+600.0*cos(flowercarframe),-101.0,-170.0+600.0*sin(flowercarframe),1); // set new instruction flowercarframe+=30*PI/180.0; // in gradients } // of case 0 break; case 1 : // he's boucing in the air now! { FlowerCar->Move(); } // of case 0 break; } // of switch FlowerCar->Draw (); glPopMatrix (); // Do the SnowMan glPushMatrix (); glTranslatef (SnowMan->X(), SnowMan->Y(), SnowMan->Z()); // glTranslatef (170.0+r*10.0, -50.0+g*10.0, -160.0+b*10.0); //initial Bugger offset glRotatef (90.0+SnowMan->Angle(), 0.0, 1.0, 0.0); glScalef (20.0, 20.0, 20.0); switch (SnowMan->Animate()) { case 0 : // waiting for new instructions when FINISHED (=0) { SnowMan->SetMove(170.0+10.0*SnowManFrames[snowmanframe%numSnowManFrames].x, -50.0+10.0*SnowManFrames[snowmanframe%numSnowManFrames].y, -160.0+10.0*SnowManFrames[snowmanframe%numSnowManFrames].z,1); // set new instruction snowmanframe++; } // of case 0 break; case 2 : // he's boucing in the air now! { SnowMan->Move(); } // of case 0 break; } // of switch SnowMan->Draw (); glPopMatrix (); // Do the Paperbird // let him fly to the position halfway between the flowercar and the snowman glPushMatrix (); glTranslatef (Bird->X(), Bird->Y(), Bird->Z()); glRotatef (-90.0-Bird->Angle(), 0.0, 1.0, 0.0); // glTranslatef (170.0+r*10.0, -50.0+g*10.0, -160.0+b*10.0); //initial Bugger offset glScalef (10.0, 10.0, 10.0); switch (Bird->Animate()) { case 0 : // waiting for new instructions when FINISHED (=0) { Bird->SetMove((SnowMan->X()+FlowerCar->X())/2.0, (SnowMan->Y()+FlowerCar->Y())/2.0, (SnowMan->Z()+FlowerCar->Z())/2.0,1); // set new instruction } // of case 0 break; default : // flying high!! { Bird->Move(); } // of case 0 break; } // of switch Bird->Draw (); glPopMatrix (); // Do the Objects glPushMatrix (); glTranslatef (140.0, -100.0, -160.0); //initial Bugger offset glScalef (50.0, 50.0, 50.0); Tower->Draw(); glPopMatrix (); // Do the Water glPushMatrix (); glTranslatef (-488.0, -124.0, -284.0); //initial Bugger offset glScalef (600.0, 10.0, 300.0); if (!(time%5)) // slow down water by a factor 5 Water->Animate(); Water->Draw(); glPopMatrix (); glFlush (); glutSwapBuffers (); } // of Display void SetShape (GLsizei w, GLsizei h) { width = w; height = h; glViewport (0, 0, w, h); } void Motion (int x, int y) { switch (status) { case 0: { float grangle=angle/180.0*PI; x=x-(width/2.0); y=y-(height/2.0); posx += -cos(grangle)*(x-oldx)+sin(grangle)*(y-oldy); posy -= sin(grangle)*(x-oldx)+cos(grangle)*(y-oldy); // (y-oldy) oldx=x; oldy=y; } break; case 1: { posz += (y-oldz); oldz = y; float grangle=angle/180.0*PI; x=x-(width/2.0); posx += -cos(grangle)*(x-oldx); posy -= sin(grangle)*(x-oldx); oldx=x; } break; case 2: { angle += (x-oldangle); headangle -= (y-oldhangle); oldhangle = y; oldangle = x; } break; } // of switch } // of Motion void Mouse (int button, int state, int X, int Y) { status = button; oldx=X-(width/2.0); oldangle = X; oldhangle = Y; oldz=Y; oldy=Y-(height/2.0); } // of Mouse void Key (unsigned char key, int x, int y) { switch (key) { case 'w' : r += 0.1; break; case 's' : r -= 0.1; break; case 'e' : g += 0.1; break; case 'd' : g -= 0.1; break; case 'r' : b += 0.1; break; case 'f' : b -= 0.1; break; case 't' : myvar += 10; break; case 'g' : myvar -= 10; break; case 'y' : myvar += 1; break; case 'h' : myvar -= 1; break; case '1' : glEnable (GL_LIGHTING); break; case '2' : glDisable (GL_LIGHTING); break; } printf("r:%f g:%f b:%f \n", r,g,b); } int main (int argc, char * argv []) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowPosition (10, 10); glutInitWindowSize (512, 512); glutCreateWindow (argv[0]); // new way of creating creatures!! SnowMan = new SNOWMAN ("snowface.off"); FlowerCar = new FLOWERCAR ("flowercar.off"); Tower = new OFFCREATURE ("tower.off"); Bird = new PAPERBIRD; Water = new SurfaceClass (); { GLfloat light_ambient[] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat light_diffuse [] = { 0.4, 0.7, 0.4, 1.0 }; GLfloat light_specular [] = { 0.3, 0.3, 0.5, 1.0 }; GLfloat position [] = { 0.0, 0.0, 0.0, 1.0 }; /* place a spotlight */ glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv (GL_LIGHT0, GL_POSITION, position); glEnable (GL_LIGHT0); glEnable (GL_LIGHTING); glLightModeli (GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); // stencil glClearStencil(0x0); // glEnable(GL_STENCIL_TEST); } { GLfloat material_ambient[] = { 0.3, 0.3, 0.3, 1.0 }; GLfloat material_diffuse [] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat material_specular [] = { 0.3, 0.3, 0.3, 1.0 }; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, material_ambient); glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, material_diffuse); glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, material_specular); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 40.0); glColorMaterial (GL_FRONT_AND_BACK, GL_AMBIENT); } // load initialise and set the textures readimage("./grass.ppm",grassimage,grassimagewidth,grassimageheight); glGenTextures(1,&GrassTexture); glBindTexture(GL_TEXTURE_2D, GrassTexture); glTexImage2D(GL_TEXTURE_2D, 0, 3, grassimagewidth, grassimageheight, 0, GL_RGB, GL_UNSIGNED_BYTE, grassimage); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); readimage("./tile.ppm",wallimage,wallimagewidth,wallimageheight); glGenTextures(2,&WallTexture); glBindTexture(GL_TEXTURE_2D, WallTexture); glTexImage2D(GL_TEXTURE_2D, 0, 3, wallimagewidth, wallimageheight, 0, GL_RGB, GL_UNSIGNED_BYTE, wallimage); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glShadeModel (GL_SMOOTH); glEnable (GL_DEPTH_TEST); glEnable (GL_NORMALIZE); glEnable (GL_COLOR_MATERIAL); glutReshapeFunc (SetShape); glutDisplayFunc (display); glutIdleFunc (display); glutKeyboardFunc (Key); glutMotionFunc (Motion); glutMouseFunc (Mouse); glutMainLoop (); }