/* Duy Dao Rain Effect Cmps 161 */ #include #include #include #include #include int stoprainning = 0; int surfacewater = 0; float checktime; int reset = 0; int life[600]; ///////WIND WIND WIND////////////// float height[600]; float windvelocityx[600]; float windvelocityy[600]; float windvelocityz[600]; float timex = 0.0; float timey = 0.0; float windx = 0.0; float windy = 0.0; int windxy = 0; int elastic = 0; int reflection = 0; float particlexx = 0.0; float particlexy = 0.0; ///////////////// ////////Euler///////////// float acceleration[600]; float oldV = 1; float newV = 1; float oldD = 1; float newD = 1; float utime = 0.0; float gravity = 20.0; //////////////////////////// ////////mouse rotate/////////////////// int xrotate = 0; int yrotate = 0; int zrotate = 0; ///////////particles//////////////// static GLuint sphereList, cubeList; float particlepositionx[600]; float particlepositiony[600]; float particlepositionz[600]; float particlepositionx1[4000]; float particlepositiony1[4000]; float particlepositionz1[4000]; float mass[600]; int particlex; int particley; int particlez; int lifespan; int maxx = 115; int maxy = 115; int maxz = 20; float sizex[600]; float sizey[600]; float sizez[600]; float sizex1[2000]; float sizey1[2000]; float sizez1[2000]; /////////////////////end particles////////////////// /////////////////lighting////////////////////////////// GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 }; GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 }; GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0}; GLfloat mat_shininess[] = { 10.0 }; //////////////////////////////////////////////////////// /////////////////wave////////////////////////////// #define wsize 250 #define DAMP 100 float water[2][wsize][wsize]; float new_water[wsize][wsize]; float old_water[wsize][wsize]; int translatez = -500; int previousx, previousy, move_z; int i, j; //////////////rotate keyboard////////////////// GLint rotX = 0; // Rotate screen on x axis GLint rotY = 0; // Rotate screen on y axis GLint rotZ = 0; // Rotate screen on z axis /////////////////////////////////////////////// unsigned *teximage; int old = 0, new = 1; void calcwater() { int x, y; float n; for(y = 1; y < wsize-1; y++) { for(x = 1; x < wsize-1; x++) { n = ( water[old][x-1][y] + water[old][x+1][y] + water[old][x][y-1] + water[old][x][y+1] ) /2; n -= water[new][x][y]; n = n - (n / DAMP); water[new][x][y] = n; } } // y = 0; /* for(x = 1; x < wsize-1; x++) { n = ( water[old][x-1][y] + water[old][x+1][y] + water[old][x][y+1] ) /2; n -= water[new][x][y]; n = n - (n / DAMP); water[new][x][y] = n; } */ // x = 0; /* for(y = 1; y < wsize-1; y++) { n = ( water[old][x+1][y] + water[old][x][y-1] + water[old][x][y+1] ) /2; n -= water[new][x][y]; n = n - (n / DAMP); water[new][x][y] = n; } */ x = wsize-1; for(y = 1; y < wsize-1; y++) { n = ( water[old][x-1][y] + water[old][x][y-1] + water[old][x][y+1] ) /2; n -= water[new][x][y]; n = n - (n / DAMP); water[new][x][y] = n; } y = wsize-1; for(x = 1; x < wsize-1; x++) { n = ( water[old][x-1][y] + water[old][x+1][y] + water[old][x][y-1] ) /2; n -= water[new][x][y]; n = n - (n / DAMP); water[new][x][y] = n; } } GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 }; GLfloat norm[3]; // this is for the lighting void normals(float x1, float y1,float z1, float x2,float y2,float z2, float x3,float y3,float z3) { /* normals(j-w, i-w, new_water[j][i], j+1-w, i-w, new_water[j+1][i], j+1-w, i+1-w, new_water[j+1][i+1]);*/ //calculate [1 - 2]x[2 - 3] the normal of triangle float v1[3], v2[3]; float dist; // vector1 - vector2 v1[0] = x1 - x2; v1[1] = y1 - y2; v1[2] = z1 - z2; // vector2 - vector3 v2[0] = x2 - x3; v2[1] = y2 - y3; v2[2] = z2 - z3; // cross product norm[0] = v1[1]*v2[2] - v1[2]*v2[1]; norm[1] = v1[2]*v2[0] - v1[0]*v2[2]; norm[2] = v1[0]*v2[1] - v1[1]*v2[0]; // get the length of cross product dist = sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]); // get the normalize of cross product norm[0] /= dist; norm[1] /= dist; norm[2] /= dist; } void Euler(int translating2) { newV = oldV + utime*acceleration[translating2]; newD = oldD + utime*oldV+ 0.5*utime*utime*acceleration[translating2]; oldV = newV; oldD = newD; if( windx != 1.0) { particlexx = 10*timex*windvelocityx[translating2]; } if( windx != 1.0) { particlexy = 10*timex*windvelocityy[translating2]; } } void Euler1(int translating2) { newV = oldV - (utime*acceleration[translating2]); newD = oldD + utime*oldV+ 0.5*utime*utime*acceleration[translating2]; oldV = newV; oldD = newD; if( windx != 1.0) { particlexx = 10*timex*windvelocityx[translating2]; } if( windy != 1.0) particlexy = 10*timex*windvelocityy[translating2]; } void drawsphere(int translating) { // glColor3f (1.0, 0.14, 0.6667); glColor3f (1.0, 1.0, 1.0); Euler(translating); int particlezz; // if( reflection == 0 ) //{ height[translating] = particlepositionz[translating]/8.0; particlezz = particlepositionz[translating]- oldD; particlexx = particlepositionx[translating] + particlexx; particlexy = particlepositiony[translating] + particlexy; //} // if ( reflection == 1 && particlezz ) // { // particlezz = // } //////////check colision w/out boucing/ if ( (particlezz <= sizez[translating]) && (elastic == 0)) { // water[new][rand()%wsize][rand()%wsize] = -rand()%50+10; particlezz = sizez[translating]; } //////////check colision w boucing/ if ( (particlezz <= sizez[translating]) && (elastic == 1)) { //water[new][rand()%wsize][rand()%wsize] = -rand()%50+10; particlezz = sizez[translating]+5; reflection = 1 ; oldD = 0.0; oldV = oldV/2.0; // utime = 0.0; } ////////// boucing up/ if( reflection == 1) { Euler1(translating); particlezz = oldD; if( oldD >= height[translating] ) { if( surfacewater = 1) // water[new][rand()%wsize][rand()%wsize] = -rand()%50+10; sizex[translating] = 0.0; sizey[translating] = 0.0; sizez[translating] = 0.0; } /* if( oldD >= height[translating] ) { oldV = 0.0; reflection = 0; oldD = 0.0; //utime = 0.0; Euler(translating); particlezz = particlepositionz[translating]- oldD; } */ } ///////destroying particle that on this earth if ( particlexx > 115) { sizex[translating] = 0.0; sizey[translating] = 0.0; sizez[translating] = 0.0; } /* if ( particlexy > 115) { sizex[translating] = 0.0; sizey[translating] = 0.0; sizez[translating] = 0.0; } */ /////////// boucing down// // if( windx == 1) // { // particlexx = particlepositionx[translating] + particlexx; // } glPushMatrix(); glTranslatef ( particlexx , particlexy, particlezz); glutSolidSphere (sizex[translating], sizey[translating], sizez[translating]); glPopMatrix(); } void drawsphere1(int translating2) { glPushMatrix(); glTranslatef ( particlepositionx1[translating2] , particlepositiony1[translating2] , particlepositionz1[translating2]); glutSolidSphere (sizex1[translating2], sizey1[translating2], sizez1[translating2]); glPopMatrix(); } void display(void) { int i, j, tmp; float w = wsize/2; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLightfv (GL_LIGHT0, GL_POSITION, position); glPushMatrix(); glDisable (GL_LIGHTING); glColor3f (0.0, 1.0, 1.0); glEnable (GL_LIGHTING); glPopMatrix(); // glPushMatrix(); // // glPopMatrix(); int translating; glPushMatrix(); // glTranslatef (100, -3.0, 0.0); //glTranslatef (1, -3.0, 0.0); // glutSolidSphere (1.0, 20, 16); glRotated(yrotate,0,1,0); glRotated(zrotate,0,0,1); glRotated(xrotate,1,0,0); glTranslatef(0, 0, translatez); glRotatef(rotX-10, 0, 1, 0); glRotatef(rotY-70, 1, 0, 0); // glDisable (GL_LIGHTING); for(translating =0 ; translating <= 500; translating++) { drawsphere(translating); } for(translating =0 ; translating <= 1900; translating++) { drawsphere1(translating); } glEnable (GL_LIGHTING); /* glBegin(GL_LINES); glColor3f (0.0, 1.0, 0.0); // Green for x axis glVertex3f(0.0,0,0); glVertex3f(1000.0,0,0); glColor3f(1.0,0.0,0.0); // Red for y axis glVertex3f(0,0.0,0); glVertex3f(0,1000.0,0); glColor3f(0.0,0.0,1.0); // Blue for z axis glVertex3f(0,0,0.0); glVertex3f(0,0,1000.0); glEnd(); */ calcwater(); int testj; int testi; glColor3f(0.0, 1, 1); glBegin(GL_TRIANGLES); for(i = 0; i < wsize-1; i++) { for(j = 0; j < wsize-1; j++) { normals(j-w, i-w, water[new][j][i], j+1-w, i-w, water[new][j+1][i], j+1-w, i+1-w, water[new][j+1][i+1]); glNormal3fv(norm); glVertex3f(j-wsize/2, i-wsize/2, water[new][j][i]); glVertex3f(j+1-wsize/2, i-wsize/2, water[new][j+1][i]); glVertex3f(j+1-wsize/2, i+1-wsize/2, water[new][j+1][i+1]); glVertex3f(j-wsize/2, i+1-wsize/2, water[new][j][i+1]); glVertex3f(j-wsize/2, i-wsize/2, water[new][j][i]); glVertex3f(j+1-wsize/2, i+1-wsize/2, water[new][j+1][i+1]); } } glEnd(); tmp = old; old = new; new = tmp; glPopMatrix(); glutSwapBuffers(); } int num = 0; int delay = 50; void idle(void) { if(stoprainning == 0) { if(!(++num %delay)) { water[new][rand()%wsize][rand()%wsize] = -rand()%50+10; new_water[rand()%wsize][rand()%wsize] = -rand()%100+100; delay = rand()%100 ; } } glutPostRedisplay(); } void reshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(45.0,(GLfloat)w/(GLfloat)h,1.0f, 1000.0f); glMatrixMode(GL_MODELVIEW); } void Rotating(int x, int y){ if(!move_z) { rotX = x - previousx; rotY = y - previousy; } else { translatez = y - previousy; } glutPostRedisplay(); } void selectObjects(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON ) { previousx = x - rotX; previousy = y - rotY; rotX -= 1.5f; rotY += 1.5f; rotZ -= 1.5f; } else { previousy = y - translatez; move_z = (move_z ? 0 : 1); } //Rotating(x, y); glutPostRedisplay(); } void specialKey( int key, int x, int y ) { switch (key) { case GLUT_KEY_UP: xrotate -= 1; xrotate %= 360; //printf("x: xrotate = %d\n", xrotate); break; case GLUT_KEY_DOWN: xrotate += 1; xrotate %= 360; //printf("x: xrotate = %d\n", xrotate); break; case GLUT_KEY_LEFT: yrotate -= 1; yrotate %= 360; //printf("y: yrotate = %d\n", yrotate); break; case GLUT_KEY_RIGHT: yrotate += 1; yrotate %= 360; //printf("y: yrotate = %d\n", yrotate); break; } glutPostRedisplay(); } void createsphere() { int PosOrNeg; //this part give us the position x, y, z of each particles and // give us the MASS as well // (2, 2, 10); rainning // (3, 3, 10); small snow // (3, 3, 10); medium snow // (5, 5, 10); big snow for( i = 0; i<= 500; i++) { PosOrNeg = rand()%4; if( PosOrNeg == 0) { particlepositionx[i] = rand()%115; particlepositiony[i] = rand()%115; } else if ( PosOrNeg == 1) { particlepositionx[i] = -(rand()%115); particlepositiony[i] = -(rand()%115); } else if ( PosOrNeg == 2) { particlepositionx[i] = (rand()%115); particlepositiony[i] = -(rand()%115); } else if ( PosOrNeg == 3) { particlepositionx[i] = -(rand()%115); particlepositiony[i] = (rand()%115); } particlepositionz[i] = rand()%30+ 100; sizex[i]= rand()%5+2.0; sizey[i]= rand()%5+2.0; sizez[i]= rand()%10+5.0; mass[i] = 10.0*sizex[i]*sizey[i]*sizez[i]; acceleration[i] = gravity* mass[i]; //printf(" particlepositionx = %d", particlepositionx[i]); windvelocityx[i] = 10.0; // windvelocityy[i] = 5; } for( i = 0; i<= 1900; i++) { PosOrNeg = rand()%4; if( PosOrNeg == 0) { particlepositionx1[i] = rand()%115; particlepositiony1[i] = rand()%115; } else if ( PosOrNeg == 1) { particlepositionx1[i] = -(rand()%115); particlepositiony1[i] = -(rand()%115); } else if ( PosOrNeg == 2) { particlepositionx1[i] = (rand()%115); particlepositiony1[i] = -(rand()%115); } else if ( PosOrNeg == 3) { particlepositionx1[i] = -(rand()%115); particlepositiony1[i] = (rand()%115); } particlepositionz1[i] = rand()%40+ 90; sizex1[i]= rand()%5+2.0; sizey1[i]= rand()%5+2.0; sizez1[i]= rand()%10+5.0; // mass1[i] = 10.0*sizex[i]*sizey[i]*sizez[i]; // acceleration[i] = gravity* mass[i]; //printf(" particlepositionx = %d", particlepositionx[i]); // windvelocityx[i] = 10.0; // windvelocityy[i] = 5; } } void updatetime() { if( windx != 1) { timex = timex + 0.001; } if( windx != 1) { timey = timey + 0.001; } utime = utime + 0.00000001; } void keyboard(unsigned char key, int x, int y) { switch (key) { case 'd': stoprainning = 1; updatetime(); ////Time for dropping snows... break; case 'c' : // create different cloud or snow... createsphere(); break; case 'r': //reset elastic = 0.0; timex = 0.0; reset = 1; oldV = 0.0; newV = 0.0; oldD = 0.0; newD = 0.0; utime = 0.0; windx = 0.0; windy = 0.0; reflection = 0; stoprainning = 0; surfacewater = 0; for(i = 0; i <600; i++) { life[i] = 1; } createsphere(); break; /* case 's': //snow or rain */ case 'e': elastic = 1; break; case 27: exit(0); break; case 'x': //disappear cloud windx = 1.0; break; case 'y': windy = 1.0; break; case 'X': windx = 0.0; break; case 'Y': windy = 0.0; break; case 'w': surfacewater = 1; break; } glutPostRedisplay(); } void init(void) { GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 }; GLfloat local_view[] = { 0.0 }; glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_ambient_color); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emission); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glShadeModel (GL_SMOOTH); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); } int main(int argc, char** argv) { createsphere(); glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500,500); glutInitWindowPosition (0, 0); glutCreateWindow("Rain and snow effect"); init(); glutReshapeFunc(reshape); glutMouseFunc(selectObjects); glutMotionFunc(Rotating); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutSpecialFunc(specialKey); glutIdleFunc(idle); glutMainLoop(); return 0; }