/* Using fog in a scene. Written by Caroline Geiersbach and Scott D. Anderson scott.anderson@acm.org Summer 2003 */ #include #include #include #include #define barnWidth 30 #define barnHeight 40 #define barnLength 50 void sun() { GLfloat lightPosition [] = {1,0.3,0,1}; GLfloat ambient [] = {0.6,0.6,0.6,1}; GLfloat diffuse [] = {0.6,0.6,0.6,1}; GLfloat specular [] = {0.8,0.8,0.8,1}; glLightfv(GL_LIGHT1, GL_POSITION, lightPosition); glLightfv(GL_LIGHT1, GL_AMBIENT, ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, specular); glShadeModel(GL_SMOOTH); glEnable(GL_LIGHT1); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); glEnable(GL_LIGHTING); } int FogOption = 1; void fog() { glEnable(GL_FOG); GLfloat fogColor[4]={0.7,0.7,0.7,1}; glFogfv(GL_FOG_COLOR,fogColor); glHint(GL_FOG_HINT,GL_NICEST); switch(FogOption) { case 0: printf("Linear Fog\n"); glFogi(GL_FOG_MODE, GL_LINEAR); glFogf(GL_FOG_START, 6); glFogf(GL_FOG_END, 10); break; case 1: printf("Exponential Decay Fog\n"); glFogi(GL_FOG_MODE, GL_EXP); glFogf(GL_FOG_DENSITY, 0.25); break; case 2: printf("Gaussian Decay Fog\n"); glFogi(GL_FOG_MODE, GL_EXP2); glFogf(GL_FOG_DENSITY, 0.35); break; } } //colors used twTriple tireColor = {0.1,0.1,0.1}; twTriple frameColor = {0.9,0,0}; //draws one tire and its spokes void drawTire() { int i; glPushMatrix(); twColor(tireColor,0.9,50.0); glutSolidTorus(0.3,3.0,30,30); for(i=0;i<12;i++) { //spokes glRotatef(30,0,0,1); twSolidCylinder(0.03,0.03,3.0,10,10); } glPopMatrix(); } //draws handlebars void drawHandlebar() { glPushMatrix(); twSolidCylinder(0.2,0.2,3,20,20); glRotatef(90,1,0,0); glTranslatef(0,3,0); twSolidCylinder(0.2,0.2,6,20,20); glPopMatrix(); } //draws seat void drawSeat() { glPushMatrix(); twSolidCylinder(0.2,0.2,2,20,20); //post glRotatef(90,0,0,1); glScalef(0.5,1,1); //flatten seat (y-direction) twSolidCylinder(1,0.2,2.5,20,20); //seat glPopMatrix(); } //used three times in the bicycle, oriented downwards (y-direction) void parallelBars(GLfloat length) { glPushMatrix(); glTranslatef(0,0,0.5); twSolidCylinder(0.1,0.1,length,20,20); glTranslatef(0,0,-1); twSolidCylinder(0.1,0.1,length,20,20); //connect the bars glRotatef(-90,1,0,0); twSolidCylinder(0.1,0.1,1,20,20); glTranslatef(0,0,-length); twSolidCylinder(0.1,0.1,1,20,20); glPopMatrix(); } void frame() { twColor(frameColor,0.9,100); //draw center bar glPushMatrix(); glTranslatef(-5,0,0); glRotatef(90,0,0,1); twSolidCylinder(0.2,0.2,10,20,20); glPopMatrix(); //draw back frame glPushMatrix(); glTranslatef(-5,0,0); GLfloat angle = atan(2.0/5.0)*180/M_PI; glRotatef(-angle,0,0,1); parallelBars(sqrt(29)); glRotatef(angle*2,0,0,1); twSolidCylinder(0.2,0.2,sqrt(29),20,20); glPopMatrix(); //draw front frame glPushMatrix(); glTranslatef(5,0,0); glRotatef(angle,0,0,1); parallelBars(sqrt(29)); GLfloat angle2 = atan(8.0/5.0)*180/M_PI; glRotatef(-angle2-angle,0,0,1); twSolidCylinder(0.2,0.2,sqrt(89),20,20); glPopMatrix(); } void drawBicycle() { //draw back tire glPushMatrix(); glTranslatef(-7,-5,0); drawTire(); twColor(frameColor,0.9,100); //return to frame color glRotatef(90,0,0,1); parallelBars(4); glPopMatrix(); //draw front tire glPushMatrix(); glTranslatef(6,-5,0); drawTire(); glPopMatrix(); //draw frame frame(); //draw handlebars glPushMatrix(); glTranslatef(5,3,0); drawHandlebar(); glPopMatrix(); //draw seat glPushMatrix(); glTranslatef(-5,2,0); drawSeat(); glPopMatrix(); } twTriple rail [] = { {0,0,0}, {0.25,0,0}, {0.25,0.2,0}, {0,0.2,0} }; void drawRail () { glBegin(GL_POLYGON); { glVertex3fv(rail[0]); glVertex3fv(rail[1]); glVertex3fv(rail[2]); glVertex3fv(rail[3]); } glEnd(); } // Arbitrary numeric identifier for this call list. #define PICKET 100 twTriple maroon = {0.5, 0, 0}; void drawInit() { /* Create a call list for one picket of the fence */ glNewList(PICKET, GL_COMPILE); glPushMatrix(); glScalef(0.225,1.3,0.1); twSolidBarn(maroon, maroon, maroon); glPopMatrix(); glPushMatrix(); twColorName(TW_OLIVE); glTranslatef(-0.025,0.2,-0.05); drawRail(); glTranslatef(0,0.5,0); drawRail(); glPopMatrix(); glEndList(); } void display(void) { int i; twDisplayInit(); glLineWidth(2); twCamera(); sun(); fog(); // draw ground twTriple grassGreen = {0,0.3,0}; twColor(grassGreen,0,0); // twGround(); glBegin(GL_POLYGON); glVertex3f(-6,0,-15); glVertex3f(-6,0,0); glVertex3f(6,0,0); glVertex3f(6,0,-15); glEnd(); // draw front fence glPushMatrix(); glTranslatef(-4,0,0); for(i=0;i<40;i++) { glCallList(PICKET); glTranslatef(0.25,0,0); } glPopMatrix(); // draw right side fence glPushMatrix(); glTranslatef(6,0,0); glRotatef(90,0,1,0); for(i=0;i<55;i++) { glCallList(PICKET); glTranslatef(0.25,0,0); } glPopMatrix(); // draw left side fence glPushMatrix(); glTranslatef(-4,0,0); glRotatef(90,0,1,0); for(i=0;i<55;i++) { glCallList(PICKET); glTranslatef(0.25,0,0); } glPopMatrix(); // draw barn glPushMatrix(); glTranslatef(-2,0,-6); // glRotatef(-90,0,1,0); glScalef(3,4,5); twTriple darkBlue = {0,0,0.8}; twTriple gray = {0.2,0.2,0.2}; twSolidBarn(darkBlue, darkBlue, gray); glPopMatrix(); //draw bicycle glPushMatrix(); glTranslatef(0, 0.85, -11.2); //glRotatef(90,0,1,0); glScalef(0.1,0.1,0.1); drawBicycle(); glPopMatrix(); glFlush(); glutSwapBuffers(); } void fogToggle(unsigned char k, int, int) { FogOption = (FogOption+1)%3; glutPostRedisplay(); } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); twInitWindowSize(500,500); glutCreateWindow(argv[0]); drawInit(); glutDisplayFunc(display); // the real are is -40,60 and -125,5 twBoundingBox(-3,7,0,3,-9.5,0);//-45,65,0,65,-130,5); twMainInit(); twKeyCallback('f',fogToggle,"switch among fog options"); glutMainLoop(); return 0; }