/* Preprocessor directives */ #if !defined(Linux) #include //Not Linux must be windows #endif #include #include #include #include #include #include #include #include /* Used to seed the random number */ #include /* generator. */ #define X 0 //X axis defined for rotation #define Y 1 //Y axis defined for rotation #define Z 2 //Z axis defined for rotation #define gravity 0.007; //gravity effect on particles #define groundfriction 0.02 //friction effect on particle struct Particle { Particle *prev; //previous particle in the list float x,y,z; //position of the particle in 3D space float permdy; //permenant y-direction of the particle float dx,dy,dz; //direction of the particle int speed; //speed of the particle float scale; //scale of the particle float Rcolor; //red color value of the particle float Gcolor; //green color value of the particle float Bcolor; //blue color value of the particle int age; //age of the particle int number; //number of the particle Particle *next; //next particle in the list }; typedef struct Particle particle; struct glob { float angle[3]; int axis; Particle *current; Particle *list; int numParticle; //keeps a track of number of particles //Flag declerations bool smooth; //solid smooth state flag int wireframe; //wireframed, points or solid particles bool friction; //fiction on or off bool spin; //random spin on or off }; struct glob global = {{0.0,0.0,0.0},Y}; /** Function Declerations */ void drawscene (void); void keyboard(unsigned char key, int x, int y); void mouse(int btn, int state, int x, int y); void mymenu(int value); void userinit(void); float randomcolor(void); void drawParticles (void); void drawcube(Particle *p); void ProcessParticles(void); void ProcessParticle(Particle *p); void explode(Particle *p); float randomScale(void); float randomX(void); float randomY(void); float randomZ(void); int randomSpin(void); int randomAge(void); //Generate a random spinning angle int randomSpin() { int angle; angle = rand() % 90 + 10; return angle; } //Generate random age int randomAge() { int age; age = rand() % 3200 + 800; return age; } //Generates a random X value to move the particle float randomX() { float x1; float x2; float xfinal; x1 = (rand()/(static_cast(RAND_MAX)+1.0))*(0.2) + 0.08; x2 = (rand()/(static_cast(RAND_MAX)+1.0))*(0.2) + 0.08; //subtract the 2 numbers to create negative x-direction everyonce in a while xfinal = x1 - x2; return xfinal; } //Generates a random Y value to move the particle float randomY(){ float y; y = (rand()/(static_cast(RAND_MAX)+1.0))*(0.7) + 0.2; return y; } //Generates a random Z value to move the particle float randomZ() { float z1; float z2; float zfinal; z1 = (rand()/(static_cast(RAND_MAX)+1.0))*(0.2) + 0.08; z2 = (rand()/(static_cast(RAND_MAX)+1.0))*(0.2) + 0.08; //subtract the 2 numbers to get a negative z direction zfinal = z1 - z2; return zfinal; } //Generates a random scale for each particle and returns it float randomScale (void) { float scale; scale = rand()%5 + 4; return scale; } //Generates a random color value for glColor3i() function and returns it float randomcolor (void) { float c1; c1 = (rand()/(static_cast(RAND_MAX)+1.0))*(0.9); return c1; } //Will draw all the particles that are in the list 1 by 1. void drawParticles () { //global.current = global.list; Particle *temp; temp = global.list; while (temp != NULL) { drawcube(temp); temp = temp->next; } } //explosion effect void explode(Particle *part) { sndPlaySound(TEXT("explode.wav"), SND_ASYNC); glPushMatrix(); glTranslatef(part->x,part->y,part->z); glScalef(part->scale/1.20,part->scale/1.20,part->scale/1.20); glColor3f(part->Rcolor,part->Gcolor,part->Bcolor); glBegin(GL_TRIANGLES); glVertex3f(part->x-2.0,part->y+2.0,part->z+2.0); glVertex3f(part->x+2.0,part->y+2.0,part->z-2.0); glVertex3f(part->x+1.0,part->y+4.0,part->z-2.0); glEnd(); glBegin(GL_TRIANGLES); glVertex3f(part->x+2.0,part->y+2.0,part->z-2.0); glVertex3f(part->x+4.0,part->y+2.0,part->z+2.0); glVertex3f(part->x+3.0,part->y+4.0,part->z-2.0); glEnd(); glBegin(GL_TRIANGLES); glVertex3f(part->x-2.0,part->y-2.0,part->z+2.0); glVertex3f(part->x-4.0,part->y-2.0,part->z-2.0); glVertex3f(part->x-3.0,part->y-4.0,part->z-2.0); glEnd(); glutSwapBuffers(); glPopMatrix(); } //draws a cube in the given location void drawcube (Particle *part) { int p[][3] = {{1,1,1}, {1,-1,1}, {-1,-1,1}, {-1,1,1}, {1,1,-1}, {1,-1,-1}, {-1,-1,-1}, {-1,1,-1}}; int e[][4] = {{0,3,2,1},{3,7,6,2},{7,4,5,6},{4,0,1,5}, {0,4,7,3},{1,2,6,5}}; float c[][3] = {{part->Rcolor,part->Gcolor,part->Bcolor}, {part->Rcolor,part->Gcolor,part->Bcolor}, {part->Rcolor,part->Gcolor,part->Bcolor}, {part->Rcolor,part->Gcolor,part->Bcolor}, {part->Rcolor,part->Gcolor,part->Bcolor}, {part->Rcolor,part->Gcolor,part->Bcolor}}; glPushMatrix(); glTranslatef(part->x,part->y,part->z); glScalef(part->scale,part->scale,part->scale); if (global.spin == true) { glRotatef(randomSpin(),1.0,0.0,0.0); glRotatef(randomSpin(),0.0,1.0,0.0); glRotatef(randomSpin(),0.0,0.0,1.0); } if (global.wireframe == 0) { for (int i=0; i < 6; ++i) { glBegin(GL_QUADS); glColor3fv(c[i]); glVertex3iv(p[e[i][0]]); glVertex3iv(p[e[i][1]]); glVertex3iv(p[e[i][2]]); glVertex3iv(p[e[i][3]]); glEnd(); } } else if (global.wireframe == 1) { glColor3f(part->Rcolor,part->Gcolor,part->Bcolor); glBegin(GL_LINES); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glEnd(); } else { glColor3f(part->Rcolor,part->Gcolor,part->Bcolor); glBegin(GL_POINTS); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glEnd(); } glPopMatrix(); } //Calculate the new values of a particle void ProcessParticles () { Particle *temp; temp = global.list; while (temp != NULL){ ProcessParticle(temp); temp = temp->next; } } //process a particle void ProcessParticle (Particle *p) { //explode if (p->age <= 0){ explode(p); p->age--; if (p->age <= 400){ p->Rcolor = randomcolor(); p->Gcolor = randomcolor(); p->Bcolor = randomcolor(); p->age = randomAge(); p->x = 0; p->y = 40; p->z = 0; p->dx = randomX(); p->permdy = randomY(); p->dy = p->permdy; p->dz = randomZ(); p->scale = randomScale(); p->speed = 8; } } //bounce it else if ((p->age > 0) && (p->y <= p->scale/2) && (p->x < 200.0 && p->x > -200.0 && p->z < 200.0 && p->z > -200.0)){ // printf("bounced at X:%f Y:%f Z:%f\n",global.current->x,global.current->y,global.current->z); if (global.friction == true && p->dx > 0.0) p->dx = p->dx - groundfriction; if (global.friction == true && p->dx < 0.0) p->dx = p->dx + groundfriction; if (global.friction == true && p->dz > 0.0) p->dz = p->dz - groundfriction; if (global.friction == true && p->dz < 0.0) p->dz = p->dz + groundfriction; sndPlaySound(TEXT("bounce.wav"), SND_ASYNC); //sndPlaySound(TEXT("C:\\Documents and Settings\\Administrator\\My Documents\\Brock\\COSC3P98\\Assign3\\Volcano\\Debug\\explode.wav"), SND_ASYNC); p->age -= 5; p->permdy = p->permdy/1.25; p->dy = p->permdy; p->y = p->y + p->dy - gravity; p->x = p->x + p->dx; p->z = p->z + p->dz; p->dy = p->dy - 0.0008; } //Particle that falls in the abyss dies and regenerates from the volcano with new variables else if (p->y < -600) { p->Rcolor = randomcolor(); p->Gcolor = randomcolor(); p->Bcolor = randomcolor(); p->age = randomAge(); p->x = 0; p->y = 40; p->z = 0; p->dx = randomX(); p->permdy = randomY(); p->dy = p->permdy; p->dz = randomZ(); p->scale = randomScale(); p->speed = 8; } else { p->y = p->y + p->dy - gravity; p->x = p->x + p->dx; p->z = p->z + p->dz; p->age--; p->dy = p->dy - 0.0008; //global.gravity = global.gravity + 0.0008; } } //initialize some variables and print instructions for user void userinit() { printf("**********************************\n"); printf("Left mouse: Rotate\n"); printf("Right mouse: Rotate opposite-Slow down\n"); printf("Middle mouse: Menu\n"); printf("A: Add a particle to the list\n"); printf("R: Reset the world\n"); printf("X: rotate around X-axis\n"); printf("Y: rotate around Y-axis\n"); printf("Z: rotate around Z-axis\n"); printf("O: toggle flat and smooth shading\n"); printf("W: toggle wireframe, points or solid objects\n"); printf("F: toggle ground friction on-off\n"); printf("M: toggle random spin effect on-off\n"); printf("Q/Esc: Quit\n"); printf("**********************************\n"); global.numParticle = 0; global.smooth = true; global.wireframe = 0; global.friction = true; global.spin = false; } void mymenu (int value) { if (value == 1) {if (global.numParticle < 20) { if (global.list == NULL) { Particle *p; p = new Particle(); global.numParticle++; p->number = global.numParticle; p->Rcolor = randomcolor(); p->Gcolor = randomcolor(); p->Bcolor = randomcolor(); p->age = randomAge(); p->x = 0; p->y = 40; p->z = 0; p->dx = randomX(); p->permdy = randomY(); p->dy = p->permdy; p->dz = randomZ(); p->scale = randomScale(); p->speed = 8; global.list = p; global.current = p; } else { global.current->next = new Particle(); global.numParticle++; global.current = global.current->next; global.current->number = global.numParticle; global.current->Rcolor = randomcolor(); global.current->Gcolor = randomcolor(); global.current->Bcolor = randomcolor(); global.current->age = randomAge(); global.current->dx = randomX(); global.current->permdy = randomY(); global.current->dy = global.current->permdy; global.current->dz = randomZ(); global.current->x = 0; global.current->y = 40; global.current->z = 0; global.current->scale = randomScale(); global.current->speed = 8; } } else printf("Cannot add more than 20 particles\n"); } if (value == 2) { global.smooth = !global.smooth; if (global.smooth){ glShadeModel(GL_SMOOTH); } else { glShadeModel(GL_FLAT); } } if (value == 3) global.spin = !global.spin; if (value == 4) { if (global.wireframe == 2) glPointSize(2.5); if (global.wireframe > 2) global.wireframe = -1; global.wireframe++; } if (value == 5) global.friction = !global.friction; if (value == 6) { userinit(); global.angle[X] = 0.0; global.angle[Y] = 0.0; global.angle[Z] = 0.0; global.axis = Y; glPopMatrix(); glPushMatrix(); global.list = NULL; global.current = NULL; global.numParticle = 0; } if (value == 7) if (global.list == NULL) printf("No particle to switch the camera to\n"); else gluLookAt(global.current->x,global.current->y,global.current->z, global.current->dx,global.current->dy,global.current->dz, global.current->dx,global.current->dy,global.current->dz); if (value == 8) global.axis = X; if (value == 9) global.axis = Y; if (value == 10) global.axis = Z; if (value == 11) exit(0); } void drawscene (void) { //define the ground edges and coordinates int v[][3] = {{200,0,200},{200,-5,200},{-200,-5,200},{-200,0,200}, {200,0,-200},{200,-5,-200},{-200,-5,-200},{-200,0,-200}}; int s[][4] = {{0,3,2,1},{3,7,6,2},{7,4,5,6},{4,0,1,5}, {0,4,7,3},{1,2,6,5}}; //define volcano edges and coordinates in an array int p[][3] = {{20,50,20}, {30,0,30}, {-30,0,30}, {-20,50,20}, {20,50,-20}, {30,0,-30}, {-30,0,-30}, {-20,50,-20}}; int e[][4] = {{0,3,2,1},{3,7,6,2},{7,4,5,6},{4,0,1,5}, {0,4,7,3},{1,2,6,5}}; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glRotatef(global.angle[X],1.0,0.0,0.0); glRotatef(global.angle[Y],0.0,1.0,0.0); glRotatef(global.angle[Z],0.0,0.0,1.0); //Draw the ground glColor3f(0.87,0.3,0.2); for (int i=0; i<6; ++i) { glBegin(GL_QUADS); glVertex3iv(v[s[i][0]]); glColor3f(0.60,0.30,0.10); glVertex3iv(v[s[i][1]]); glColor3f(0.67,0.28,0.08); glVertex3iv(v[s[i][2]]); glColor3f(0.02,0.9,0.08); glVertex3iv(v[s[i][3]]); glEnd(); } //draw the volcano if (global.wireframe == 0) { for (int i=0; i < 4; ++i) { glColor3f(0.60,0.15,0.07); glBegin(GL_QUADS); glVertex3iv(p[e[i][0]]); glColor3f(0.67,0.28,0.08); glVertex3iv(p[e[i][1]]); glColor3f(0.35,0.42,0.10); glVertex3iv(p[e[i][2]]); glColor3f(0.65,0.10,0.0); glVertex3iv(p[e[i][3]]); glEnd(); } } else if (global.wireframe == 1) { glColor3f(0.60,0.15,0.07); glBegin(GL_LINES); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glColor3f(0.67,0.28,0.08); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glColor3f(0.35,0.42,0.10); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glColor3f(0.65,0.10,0.0); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glEnd(); } else { glColor3f(0.60,0.15,0.07); glBegin(GL_POINTS); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[0][0],p[0][1],p[0][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glColor3f(0.67,0.28,0.08); glVertex3i(p[7][0],p[7][1],p[7][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[3][0],p[3][1],p[3][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glColor3f(0.35,0.42,0.10); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[2][0],p[2][1],p[2][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[1][0],p[1][1],p[1][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[4][0],p[4][1],p[4][2]); glColor3f(0.65,0.10,0.0); glVertex3i(p[5][0],p[5][1],p[5][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[6][0],p[6][1],p[6][2]); glVertex3i(p[7][0],p[7][1],p[7][2]); glEnd(); } ProcessParticles(); drawParticles(); glutSwapBuffers(); glFlush(); } void mouse(int btn, int state, int x, int y) { if (state == GLUT_DOWN) { if (btn==GLUT_LEFT_BUTTON) { global.angle[global.axis] = global.angle[global.axis] + 0.1; } else if (btn == GLUT_RIGHT_BUTTON) { global.angle[global.axis] = global.angle[global.axis] - 0.1; } else {} } } void keyboard (unsigned char key, int x, int y) { switch (key) { case 'a': case 'A': if (global.numParticle < 20) { if (global.list == NULL) { Particle *p; p = new Particle(); global.numParticle++; p->number = global.numParticle; p->Rcolor = randomcolor(); p->Gcolor = randomcolor(); p->Bcolor = randomcolor(); p->age = randomAge(); p->x = 0; p->y = 40; p->z = 0; p->dx = randomX(); p->permdy = randomY(); p->dy = p->permdy; p->dz = randomZ(); p->scale = randomScale(); p->speed = 8; global.list = p; global.current = p; } else { global.current->next = new Particle(); global.numParticle++; global.current = global.current->next; global.current->number = global.numParticle; global.current->Rcolor = randomcolor(); global.current->Gcolor = randomcolor(); global.current->Bcolor = randomcolor(); global.current->age = randomAge(); global.current->dx = randomX(); global.current->permdy = randomY(); global.current->dy = global.current->permdy; global.current->dz = randomZ(); global.current->x = 0; global.current->y = 40; global.current->z = 0; global.current->scale = randomScale(); global.current->speed = 8; } } else printf("Cannot add more than 20 particles\n"); break; case 'x': case 'X': global.axis = X; break; case 'y': case 'Y': global.axis = Y; break; case 'z': case 'Z': global.axis = Z; break; case 0x1B: case 'q': case 'Q': exit(0); break; case 'c': case 'C': if (global.list == NULL) printf("No particle to switch the camera to\n"); else gluLookAt(global.current->x,global.current->y,global.current->z, global.current->dx,global.current->dy,global.current->dz, global.current->dx,global.current->dy,global.current->dz); break; case 'w': case 'W': if (global.wireframe == 2) glPointSize(2.5); if (global.wireframe > 2) global.wireframe = -1; global.wireframe++; break; case 'r': case 'R': global.angle[X] = 0.0; global.angle[Y] = 0.0; global.angle[Z] = 0.0; global.axis = Y; glPopMatrix(); glPushMatrix(); global.list = NULL; global.current = NULL; global.numParticle = 0; break; case 'o': case 'O': global.smooth = !global.smooth; if (global.smooth){ glShadeModel(GL_SMOOTH); } else { glShadeModel(GL_FLAT); } break; case 'f': case 'F': global.friction = !global.friction; break; case 'm': case 'M': global.spin = !global.spin; break; } } int main (int argc, char **argv) { srand ( time(NULL) ); //initialize the random seed userinit(); //user intro and initializing particle list glutInit(&argc, argv); glutInitWindowPosition(600,100); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(600,600); glutCreateWindow("VOLCANO"); //glutFullScreen(); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutCreateMenu(mymenu); glutAddMenuEntry("Add particle",1); glutAddMenuEntry("Smooth-Flat Shading",2); glutAddMenuEntry("Spin particles on-off",3); glutAddMenuEntry("Wire-Points-Lines on-off",4); glutAddMenuEntry("Friction on-off",5); glutAddMenuEntry("Reset",6); glutAddMenuEntry("Change camera",7); glutAddMenuEntry("X-axis Rotation",8); glutAddMenuEntry("Y-axis Rotation",9); glutAddMenuEntry("Z-axis Rotation",10); glutAddMenuEntry("Exit",11); glutAttachMenu(GLUT_MIDDLE_BUTTON); glutDisplayFunc(drawscene); glutIdleFunc(drawscene); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-300,300,-300,300,-300,300); glRotatef(30.0,1.0,0.0,0.0); glRotatef(30.0,0.0,1.0,0.0); glClearColor(0.0, 0.0, 0.0, 1.0); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); glPushMatrix(); //BackFace culling glFrontFace(GL_CCW); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glutMainLoop(); }