#define MENU_ID_QUIT 666 #define SUB_MENU_LIGHT_RIGHT 111 #define SUB_MENU_LIGHT_LEFT 112 #define SUB_MENU_LIGHT_ABOVE 113 #define SUB_MENU_LIGHT_BELOW 114 #define SUB_MENU_LIGHT_ALL 115 //#define SUB_MENU_LIGHT_ANIMATION 120 #define SUB_MENU_SHAKE 116 #define SUB_MENU_ROTATE 117 #include #include #include #include /* for sqrt,pow */ #include typedef enum { RESERVED, BODY_SIDE, BODY_EDGE, BODY_WHOLE, EAR_SIDE, EAR_EDGE, EAR_WHOLE, TUCH_SIDE, TUCH_EDGE, TUCH_WHOLE, LEG_SIDE, LEG_EDGE, LEG_WHOLE, LEG2_SIDE, LEG2_EDGE, LEG2_WHOLE,EYE_SIDE, EYE_EDGE, EYE_WHOLE, Dalmatiner //, Sphere } displayLists; GLfloat angle = -150; /*for rotate*/ GLfloat ytrans = 0; /*for shake*/ GLfloat xloc = 0, yloc = 0, zloc = 0; GLfloat xsphere = 4.5, ysphere = 3, zsphere = 1; /*Middle od Sphere*/ GLfloat xsnow[] = { (0),(1),(2),(3),(4),(5),(6),(7),(4),(5),(6),(7),(8),(9),(2),(0),(4),(2),(1),(7),(6),(7),(6),(5),(4),(8),(7)}; GLfloat ysnow[] = {(0),(1),(2),(1),(0),(-1),(2),(0),(0),(1),(2),(-2),(3),(0),(1),(-1),(2),(2),(-2),(3),(2),(1),(-2),(-2),(3),(1),(1)}; GLfloat zsnow[] = {(0),(1),(2),(3)}; GLdouble bodyWidth = 2.0; GLfloat ShakeSwitch = 1; /*Selection rotate or shake*/ GLboolean lightAllSwitch = GL_FALSE,lightRightSwitch = GL_FALSE, lightLeftSwitch = GL_FALSE,lightAboveSwitch = GL_FALSE, lightBelowSwitch = GL_FALSE; //GLboolean AnimateLights = GL_FALSE, lightAnimateSwitch = GL_FALSE; /*Lights ON*/ int moving, begin; /*for Mousefunction*/ //int W = 300, H = 300; int newModel = 1; /*Selection rotate or shake for draw*/ int i,j; double vx = 4.5,vy; /*"Speed" for Snow*/ double vZeit=1.0; /*Time to sink (Snow)*/ int RunAnimation= GL_FALSE; int anzBaelle=25; /********************************************************************/ /* Points for Dalmatiner */ /********************************************************************/ GLfloat body[][2] = { {0, 6}, {1.2,4.7}, {1.5,3.9}, {2,2.5},{4,2.3},{6.5,2.2},{7,2.5},{7,3.4},{8.5,4}, {9.5,5.5},{8,4.4},{4.5,4.5},{2.7,4.8},{3.4,5.3},{3.5,6},{3.2,7},{2.4,7.5}, {1.8,7.5},{1.3,6.5},{0.6,6.7}}; GLfloat ears[][2] = { {3,7},{3,5.5},{3.7,4.7},{4,5},{4.5,6.4},{3.5,7}}; GLfloat tuch[][2] = { {1.2,4.7},{1.4,4.3},{3.2,5.0},{3.4,5.3}}; GLfloat leg[][2] = { {5.9,3.1},{4.7,3.1},{4.5,1.8},{4.8,1.3},{4.5,1},{4.3,0.5},{4.7,0},{5.7,0},{5.85,0},{6.5,1.5}}; GLfloat leg2[][2] = { {3.3,3},{2.3,2.8},{2,1.8},{1.5,1.3},{1.5,0.6},{2.0,0.35},{2.8,0.2},{3.3,0.9},{3.5,2.5}}; GLfloat eye[][2] = { {1.5,6.4},{1.8,6.2},{1.9,6.5},{1.6,6.6} }; /********************************************************************/ /* Lightspositions */ /********************************************************************/ GLfloat lightRightPosition[] = {10.0, 4, 10.0, 1.0}; /*Position im Raum*/ GLfloat lightRightColor[] = {1, 0, 0.5, 0.5}; GLfloat lightLeftPosition[] = {-1.0, -2, 1.0, 0.0}; /*gerichtete Lichtquelle*/ GLfloat lightLeftColor[] = {0, 1, 1, 0.5}; GLfloat lightAbovePosition[] = {0.0, 8, 10.0, 1.0}; /*Position im Raum*/ GLfloat lightAboveColor[] = {0, 0, 1, 1.0}; GLfloat lightBelowPosition[] = {0.0, -8, 1.0, 0.0}; /*gerichtete Lichtquelle*/ GLfloat lightBelowColor[] = {1, 0, 1, 0.8}; GLfloat lightAnimatePosition[] = {6.0, -2, 10.0, 1.0}; /*Position im Raum*/ GLfloat lightAnimateColor[] = {1, 0, 0.5, 0.5}; /********************************************************************/ /* Colors for ... */ /********************************************************************/ GLfloat skinColor[] = {1, 1.0, 1, 1.0}; GLfloat eyeColor[] = {0.0, 0.0, 0.0, 1.0}; GLfloat earColor[] = {0.01, 0.01 ,0.01 ,1.0}; GLfloat TuchColor[] = {1.0, 0. ,0. ,1.0}; GLfloat SphereColor[] = {0.7, 0.7 ,1.0 ,0.5}; GLfloat SphereColor2[] = {0.7, 0.7 ,1.0 ,0.2}; GLfloat SphereColor3[] = {0.7, 0.7 ,1.0 ,0.15}; GLfloat FOURSphereColor[] = {0.9, 0.1 ,0.5 ,0.7}; GLfloat SnowColor[] = {0.9, 0.9 ,0.9 ,0.8}; /********************************************************************/ /* */ /********************************************************************/ void extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, GLdouble thickness, GLuint side, GLuint edge, GLuint whole) { static GLUtriangulatorObj *tobj = NULL; GLdouble vertex[3], dx, dy, len; int i; int count = dataSize / (int) (2 * sizeof(GLfloat)); if (tobj == NULL) { tobj = gluNewTess(); /* create and initialize a GLU polygon tesselation object */ gluTessCallback(tobj, GLU_BEGIN, glBegin); gluTessCallback(tobj, GLU_VERTEX, glVertex2fv); /* definition vertices */ gluTessCallback(tobj, GLU_END, glEnd); } glNewList(side, GL_COMPILE); /* side calculation*/ glShadeModel(GL_SMOOTH); /* smooth minimizes seeing tessellation */ gluBeginPolygon(tobj); /* calculate polygon front*/ for (i = 0; i < count; i++) { vertex[0] = data[i][0]; vertex[1] = data[i][1]; vertex[2] = 0; gluTessVertex(tobj, vertex, data[i]); } gluEndPolygon(tobj); glEndList(); glNewList(edge, GL_COMPILE); /* edge calculation */ glShadeModel(GL_FLAT); /* flat shade keeps angular hands from being "smoothed" */ glBegin(GL_QUAD_STRIP); for (i = 0; i <= count; i++) { /* mod function handles closing the edge */ glVertex3f(data[i % count][0], data[i % count][1], 0.0); glVertex3f(data[i % count][0], data[i % count][1], thickness); /* Calculate a unit normal by dividing by Euclidean distance.*/ dx = data[(i + 1) % count][1] - data[i % count][1]; dy = data[i % count][0] - data[(i + 1) % count][0]; len = sqrt(dx * dx + dy * dy); glNormal3f(dx / len, dy / len, 0.0); } glEnd(); glEndList(); glNewList(whole, GL_COMPILE); glFrontFace(GL_CW); /*clockwise culling polygon for normals*/ glCallList(edge); glNormal3f(0.0, 0.0, -1.0); /* constant normal for side */ glCallList(side); glPushMatrix(); glTranslatef(0.0, 0.0, thickness); glFrontFace(GL_CCW); glNormal3f(0.0, 0.0, 1.0); /* opposite normal for other side */ glCallList(side); glPopMatrix(); glEndList(); } /********************************************************************/ /* Call for Lists */ /********************************************************************/ void makeDalmatiner(void) { extrudeSolidFromPolygon(body, sizeof(body), bodyWidth, BODY_SIDE, BODY_EDGE, BODY_WHOLE); extrudeSolidFromPolygon(ears, sizeof(ears), bodyWidth / 4, EAR_SIDE, EAR_EDGE, EAR_WHOLE); extrudeSolidFromPolygon(tuch, sizeof(tuch), bodyWidth / 4, TUCH_SIDE, TUCH_EDGE, TUCH_WHOLE); extrudeSolidFromPolygon(leg, sizeof(leg), bodyWidth / 3, LEG_SIDE, LEG_EDGE, LEG_WHOLE); extrudeSolidFromPolygon(leg2, sizeof(leg2), bodyWidth / 3, LEG2_SIDE, LEG2_EDGE, LEG2_WHOLE); extrudeSolidFromPolygon(eye, sizeof(eye), bodyWidth + 0.2, EYE_SIDE, EYE_EDGE, EYE_WHOLE); glNewList(Dalmatiner, GL_COMPILE); /*calculate scene*/ glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor); glCallList(BODY_WHOLE); glPushMatrix(); glTranslatef(0.0, 0.0, bodyWidth); glCallList(EAR_WHOLE); glCallList(LEG_WHOLE); glCallList(LEG2_WHOLE); glMaterialfv(GL_FRONT, GL_DIFFUSE, TuchColor); glCallList(TUCH_WHOLE); glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor); glTranslatef(0.0, 0.0, -bodyWidth - bodyWidth / 4); glMaterialfv(GL_FRONT, GL_DIFFUSE, earColor); glCallList(EAR_WHOLE); glMaterialfv(GL_FRONT, GL_DIFFUSE, skinColor); glCallList(LEG_WHOLE); glCallList(LEG2_WHOLE); glMaterialfv(GL_FRONT, GL_DIFFUSE, TuchColor); glCallList(TUCH_WHOLE); glMaterialfv(GL_FRONT, GL_DIFFUSE, eyeColor); glCallList(EYE_WHOLE); glTranslatef(0.0, 0.0, bodyWidth / 2 - 0.1); glCallList(EYE_WHOLE); glPopMatrix(); glEndList(); } /********************************************************************/ /* Draw Sphere around dog (3;alpha--) */ /********************************************************************/ void makeSphere(void) { // glNewList(Sphere, GL_COMPILE); glMaterialfv(GL_FRONT, GL_DIFFUSE, SphereColor); glPushMatrix(); glTranslatef(xsphere,ysphere,zsphere); /* "middlepoint" 4.5, 3, 1 */ glutSolidSphere(6.5, 25, 40); glPopMatrix(); // glEndList(); } void makeSphere2(void) { glMaterialfv(GL_FRONT, GL_DIFFUSE, SphereColor2); glPushMatrix(); glTranslatef(4.5,3,1); /* "middlepoint" 4.5, 3, 1 */ glutSolidSphere(8.5, 25, 40); glPopMatrix(); } void makeSphere3(void) { glMaterialfv(GL_FRONT, GL_DIFFUSE, SphereColor3); glPushMatrix(); glTranslatef(4.5,3,1); /* "middlepoint" 4.5, 3, 1 */ glutSolidSphere(10.5, 25, 40); glPopMatrix(); } /********************************************************************/ /* Animation for Snow */ /********************************************************************/ void Animate(void) { for(i=0;i<=anzBaelle;i++){ xsnow[i]+= vx*0.05; if((vy<30) && (ysnow[i]>-3) ) ysnow[i]+= vy*0.05; if( ( (sqrt( pow((xsnow[i]),2) + pow((ysnow[i]),2))) >2.) ){ //114.5){ xsnow[i] = xsnow[i]-1; vx=vx*-1; } if(xsnow[i]-4.5<-4.5){ xsnow[i] = xsnow[i]+1; vx=vx*-1; } if(ysnow[i]-2>4.5){ ysnow[i] = ysnow[i]-1; vy=vy*-1; } if(ysnow[i]-2<-4.5){ ysnow[i] = ysnow[i]+1; vy=vy*-1; } } if (vx>0) vx=vx-0.001; else vx=vx+0.001; if (vy>0) vy=vy-0.01; else vy=vy+0.01; if(ysnow[i]>-0.5) ysnow[i]=ysnow[i]-0.01; /*"earth gravitation"*/ if((vZeit<=0) ) { /*snow is fallen*/ RunAnimation= GL_FALSE; vx= 4.5; // vy= 1.5; vZeit=1.0; } } vZeit=vZeit-0.0025; glutPostRedisplay(); } /********************************************************************/ /* Snow */ /********************************************************************/ void makeSnow(void) { glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, SnowColor); glPushMatrix(); if(RunAnimation) Animate(); glEnable(GL_POINT_SMOOTH); glPointSize(3); glBegin(GL_POINTS); for(j=0;j<=3;j++){ for(i=0;i<=anzBaelle;i++){ glNormal3d(xsnow[i],ysnow[i],zsnow[j]); glVertex3d(xsnow[i],ysnow[i],zsnow[j]); } } glEnd(); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, FOURSphereColor); /*Spheres around the big sphere*/ glTranslatef(18,0,0); glNormal3d(1,1,1); glutSolidSphere(0.5, 25, 40); glTranslatef(-28.5,0,0); glutSolidSphere(0.5, 25, 40); glTranslatef(15,15,1); glutSolidSphere(0.5, 25, 40); glTranslatef(0,-25,0); glutSolidSphere(0.5, 25, 40); glPopMatrix(); } /********************************************************************/ /* Selection Rotate or Shake */ /********************************************************************/ void recalcModelView(int achse) { glPopMatrix(); glPushMatrix(); glTranslatef(xloc, yloc, zloc); if(achse==1){ glRotatef(angle, 0.0, 1.0, 0.0); glTranslatef(-8, -8, -bodyWidth / 2); } if(achse==2){ if(ytrans<-3) ytrans=-3; /*Limits for Sphere with dog in window*/ if(ytrans>12) ytrans=12; glRotatef(angle, 0, 1.0, 0.0); glTranslatef(0, ytrans, 0); glTranslatef(-8, -8, -bodyWidth / 2); } newModel = 0; } /********************************************************************/ /* Redraw Scene */ /********************************************************************/ void redraw(void) { if (newModel==1) recalcModelView(1); if (newModel==2) recalcModelView(2); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); /*Alpha-Channel ON*/ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); makeSnow(); glCallList(Dalmatiner); //glCallList(Sphere); makeSphere(); makeSphere2(); makeSphere3(); glDisable(GL_BLEND); glutSwapBuffers(); /*swap Buffers*/ } /********************************************************************/ /* Mousefunction */ /********************************************************************/ void mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && (state == GLUT_DOWN || state == GLUT_UP ) ) { if(ShakeSwitch==1){ moving = 2; begin = y; // if(!RunAnimation) vZeit=1.0; RunAnimation= GL_TRUE; } else{ moving = 1; begin=x; } } // if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) { // moving = 0; // } } /********************************************************************/ /* If Selection Rotate then.. else .. */ /********************************************************************/ void motion(int x, int y) { if (moving==1) { angle = angle + (x - begin); begin = x; newModel = 1; glutPostRedisplay(); } if (moving==2) { ytrans = ytrans + (y - begin); vy=y-begin; /*Balls up<->down*/ if(vy<0) vy=vy*-1; /*other sign*/ vZeit=1.0; begin = y; newModel = 2; // RunAnimation= GL_TRUE; glutPostRedisplay(); } } /********************************************************************/ /* Lights around the Ball (left,right,above,below,all) */ /********************************************************************/ void controlLights(int value) { switch (value) { case SUB_MENU_LIGHT_RIGHT: lightRightSwitch = !lightRightSwitch; if (lightRightSwitch) { glEnable(GL_LIGHT0); } else { glDisable(GL_LIGHT0); } break; case SUB_MENU_LIGHT_LEFT: lightLeftSwitch = !lightLeftSwitch; if (lightLeftSwitch) { glEnable(GL_LIGHT1); } else { glDisable(GL_LIGHT1); } break; case SUB_MENU_LIGHT_ABOVE: lightAboveSwitch = !lightAboveSwitch; if (lightAboveSwitch) { glEnable(GL_LIGHT2); } else { glDisable(GL_LIGHT2); } break; case SUB_MENU_LIGHT_BELOW: lightBelowSwitch = !lightBelowSwitch; if (lightBelowSwitch) { glEnable(GL_LIGHT3); } else { glDisable(GL_LIGHT3); } break; case SUB_MENU_LIGHT_ALL: if( (lightRightSwitch == GL_TRUE) && (lightLeftSwitch == GL_TRUE) &&(lightAboveSwitch == GL_TRUE) &&(lightBelowSwitch == GL_TRUE) ) lightAllSwitch = GL_FALSE; else lightAllSwitch = GL_TRUE; //lightAllSwitch = !lightAllSwitch; if (lightAllSwitch) { glEnable(GL_LIGHT0); lightRightSwitch = GL_TRUE; glEnable(GL_LIGHT1); lightLeftSwitch = GL_TRUE; glEnable(GL_LIGHT2); lightAboveSwitch = GL_TRUE; glEnable(GL_LIGHT3); lightBelowSwitch = GL_TRUE; } else { glDisable(GL_LIGHT0); lightRightSwitch = GL_FALSE; glDisable(GL_LIGHT1); lightLeftSwitch = GL_FALSE; glDisable(GL_LIGHT2); lightAboveSwitch = GL_FALSE; glDisable(GL_LIGHT3); lightBelowSwitch = GL_FALSE; } break; /* case SUB_MENU_LIGHT_ANIMATION: lightAnimateSwitch = !lightAnimateSwitch; if (lightAnimateSwitch) { AnimateLights=GL_TRUE; glEnable(GL_LIGHT4); } else { AnimateLights=GL_FALSE; glDisable(GL_LIGHT4); } break; */ } glutPostRedisplay(); } void rotateBall(int value) { switch (value) { case SUB_MENU_SHAKE: ShakeSwitch = 1; break; case SUB_MENU_ROTATE: ShakeSwitch = 2; break; } glutPostRedisplay(); } void DoMainMenu(int id) { if(MENU_ID_QUIT==id){ exit(0); } } /********************************************************************/ /* Main */ /********************************************************************/ int main(int argc, char **argv) { int mainMenu,lightMenu,rotateMenu; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE); glutCreateWindow("Dalmatiner"); glutDisplayFunc(redraw); glutMouseFunc(mouse); glutMotionFunc(motion); lightMenu=glutCreateMenu(controlLights); glutAddMenuEntry("Toggle right light",SUB_MENU_LIGHT_RIGHT); glutAddMenuEntry("Toggle left light",SUB_MENU_LIGHT_LEFT); glutAddMenuEntry("Toggle above light",SUB_MENU_LIGHT_ABOVE); glutAddMenuEntry("Toggle below light",SUB_MENU_LIGHT_BELOW); glutAddMenuEntry("Toggle all lights",SUB_MENU_LIGHT_ALL); // glutAddMenuEntry("LightAnimation",SUB_MENU_LIGHT_ANIMATION); rotateMenu=glutCreateMenu(rotateBall); glutAddMenuEntry("Shake",SUB_MENU_SHAKE); glutAddMenuEntry("Rotate",SUB_MENU_ROTATE); mainMenu= glutCreateMenu(DoMainMenu); glutAddSubMenu("ShakeOrRotate",rotateMenu); glutAddSubMenu("Lights",lightMenu); glutAddMenuEntry("Quit",MENU_ID_QUIT); glutAttachMenu(GLUT_RIGHT_BUTTON); glEnable(GL_CULL_FACE); /*first behind than in front*/ glEnable(GL_DEPTH_TEST); makeDalmatiner(); makeSphere(); makeSnow(); makeSphere2(); makeSphere3(); glEnable(GL_LIGHTING); glMatrixMode(GL_PROJECTION); gluPerspective( /* field of view in degree */ 50.0, /* aspect ratio */ 1.0,/* Z near */ 1.0, /* Z far */ 100.0); glMatrixMode(GL_MODELVIEW); gluLookAt(0.0, 0.0, 30.0, /* eye is at (0,0,30) */ 0.0, 0.0, 0.0, /* center is at (0,0,0) */ 0.0, 1.0, 0.); /* up is in positive Y direction */ glPushMatrix(); /* dummy push so we can pop on modelrecalc */ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); /*local Viewer, direction (point<->scene) is changing*/ glLightfv(GL_LIGHT0, GL_POSITION, lightRightPosition); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightRightColor); glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.1); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.05); /*lights with distance */ glLightfv(GL_LIGHT1, GL_POSITION, lightLeftPosition); glLightfv(GL_LIGHT1, GL_DIFFUSE, lightLeftColor); glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 0.1); glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.05); glLightfv(GL_LIGHT2, GL_POSITION, lightAbovePosition); glLightfv(GL_LIGHT2, GL_DIFFUSE, lightAboveColor); glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, 0.1); glLightf(GL_LIGHT2, GL_LINEAR_ATTENUATION, 0.05); glLightfv(GL_LIGHT3, GL_POSITION, lightBelowPosition); glLightfv(GL_LIGHT3, GL_DIFFUSE, lightBelowColor); glLightf(GL_LIGHT3, GL_CONSTANT_ATTENUATION, 0.1); glLightf(GL_LIGHT3, GL_LINEAR_ATTENUATION, 0.05); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2); glEnable(GL_LIGHT3); glutMainLoop(); return 0; }