#include // Header File For Windows #include #include #include // Math Library Header File #include // Header File For Standard Input/Output #include // Header File For The Glut Library #define NUM_PARTICLES 20000 #define GRAVITY 0.00005f // (Gravity) #define FRICTION 0.035f//Air resistance #define SPRING_CONSTANT 0.01f // Particle structure typedef struct { float xPos,yPos,zPos; float xVec,yVec,zVec; bool dead; }Particle; bool keys[256]; // Array Used For The Keyboard Routine Particle Pars[NUM_PARTICLES]; const float piover180 = 0.0174532925f; float heading; float xpos; float ypos=0.0f; float zpos; float xstart=.5; float ystart=0.0; float zstart=1.0; float SPRING_SIZE=0.13; bool teapottoggle=true; GLUquadricObj *quadratic; // Storage For Our Quadratic Objects ( NEW ) GLfloat yangle; // Y Rotation GLfloat lookupdown = 0.0f; GLfloat pointamb[] = {0.0,0.0,1.0,1.0}; GLfloat pointdiff[] = {0.0,0.0,0.8,1.0}; GLfloat pointspec[] = {0.4,0.4,1.0,1.0}; GLfloat slinkyamb[] = {1.0,0.0,0.0,1.0}; GLfloat slinkydiff[] = {0.8,0.0,0.0,1.0}; GLfloat slinkyspec[] = {1.0,0.5,0.5,1.0}; Particle checkbounds(Particle p) { //Check walls, bounce off of them if(2p.xPos) p.xPos=0; if(-2>p.zPos) p.zPos=0; if(0>p.xPos) { p.xPos=p.xPos-2*p.xVec; p.xVec= -1*p.xVec; } if(p.xPos>1) { p.xPos=p.xPos-2*p.xVec; p.xVec= -1*p.xVec; } if((0>p.zPos)) { p.zPos=p.zPos-2*p.zVec; p.zVec= -1*p.zVec; } if(p.zPos>1) { p.zPos=p.zPos-2*p.zVec; p.zVec= -1*p.zVec; } if(p.yPos>2) { p.yVec=0; } return p; } /*Shoots each particle with a random velocity from the nozzle's postion whenever it dies */ Particle Shoot(Particle p) { p.dead=0; p.yVec =(float) ((rand() / (RAND_MAX + 1.0))); while(p.yVec<((float) ((RAND_MAX + 1.0)/2)/(RAND_MAX + 1.0))) p.yVec =(float) ((rand() / (RAND_MAX + 1.0))); p.yVec = p.yVec/25; p.zVec = ((float) (rand() / (RAND_MAX + 1.0))); p.zVec /=10; p.xVec = (float) (rand() / (RAND_MAX + 1.0)); p.xVec /=50; if(rand() / (RAND_MAX + 1.0)<.5) p.xVec*=-1; checkbounds(p); p.xPos=xstart+p.xVec; p.yPos=ystart+p.yVec; p.zPos=zstart+p.zVec; return p; } //Block water from falling through rungs from above. Not below, though Particle checkRungs(Particle p) { if(p.yPos>1.0)//middle rung { if(p.xPos>.4 && p.xPos<.6) if(p.zPos<.25) if((p.yPos+(p.yVec-GRAVITY*10))<1.0) { p.yPos=1.01; p.yVec=0.0; p.xVec=.95*p.xVec; //p.zVec*=.99*p.zVec; } } else if(p.yPos>.75)//middle rung { if(p.xPos>.3 && p.xPos<.7) if(p.zPos<.35) if(p.yPos+p.yVec-GRAVITY*10<.75) { p.yPos=.759; p.yVec=0; p.xVec=.95*p.xVec; } } else if(p.yPos>.5)//bottom rung { if(p.xPos>.2 && p.xPos<.8) { if(p.zPos<.5) { if(p.yPos+p.yVec-GRAVITY*10<.5) { p.yPos=.509; p.yVec=0; p.xVec=.95*p.xVec; } } } } else if(p.yPos>0.0)//floor { if(p.xPos>0.0 && p.xPos<1.0) { if(p.zPos<0.5) { if(p.yPos+p.yVec-GRAVITY*10<0.0) { p.yPos=.001; p.yVec=0; } } } } return p; } void fountain(void)//takes care of physics for all active particles { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pointamb); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pointdiff); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pointspec); for(int i=0; i0)//slows down particles like air resistance Pars[i].xVec-=FRICTION; else Pars[i].xVec+=FRICTION; Pars[i].xPos=Pars[i].xPos+Pars[i].xVec; if(Pars[i].zVec>0) Pars[i].zVec-=FRICTION; else Pars[i].zVec+=FRICTION; Pars[i].zPos=Pars[i].zPos+Pars[i].zVec; } glBegin(GL_POINTS); for(int i=0; i0) ystart -=.01; break; case 'u': if(zstart-.01>0) zstart -=.01; break; case 'o': if(zstart+.01<1) zstart +=.01; break; case 'j': if(xstart-.01>0) xstart -=.01; break; case 'l': if(xstart+.01<1) xstart +=.01; break; case 'w': xpos -= (float)sin(yangle*piover180) * 0.05f; zpos -= (float)cos(yangle*piover180) * 0.05f; break; case 's': xpos += (float)sin(yangle*piover180) * 0.05f; zpos += (float)cos(yangle*piover180) * 0.05f; break; case 't': teapottoggle=!teapottoggle; break; case '1': pointamb[0]=0.0; pointamb[1]=0.0; pointamb[2]=1.0; pointamb[3]=1.0; break; case '2': pointamb[0]=1.0; pointamb[1]=1.0; pointamb[2]=0.0; pointamb[3]=1.0; break; case '3': pointamb[0]=1.0; pointamb[1]=0.0; pointamb[2]=0.0; pointamb[3]=1.0; break; case '4': pointamb[0]=1.0; pointamb[1]=1.0; pointamb[2]=1.0; pointamb[3]=1.0; break; case '5': pointamb[0]=0.0; pointamb[1]=1.0; pointamb[2]=0.0; pointamb[3]=1.0; break; case '6': pointamb[0]=0.2; pointamb[1]=0.2; pointamb[2]=0.2; pointamb[3]=1.0; break; case '-': if(SPRING_SIZE>.01) SPRING_SIZE-=0.01; break; case '=': SPRING_SIZE+=0.01; break; case '.': Pars[0].dead=1; Pars[1].dead=1; break; } } void keyboard2(int key2, int x, int y) { switch (key2) { case GLUT_KEY_RIGHT: yangle -=3; break; case GLUT_KEY_LEFT: yangle +=3; break; case GLUT_KEY_DOWN: xpos += (float)sin(yangle*piover180) * 0.05f; zpos += (float)cos(yangle*piover180) * 0.05f; break; case GLUT_KEY_UP: xpos -= (float)sin(yangle*piover180) * 0.05f; zpos -= (float)cos(yangle*piover180) * 0.05f; break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); InitGL(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutSpecialFunc(keyboard2); glutMainLoop(); return 0; }