Facebook
From Crippled Hog, 7 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 287
  1. // opengl_explosion.cpp : Defines the entry point for the console application.
  2.  
  3. //
  4.  
  5. #include "stdafx.h"
  6.  
  7. /*
  8.  
  9. * explosion.cpp - Simple particle system based explosion demonstration.
  10.  
  11. *
  12.  
  13. * Author: Gustav Taxen, [email protected]
  14.  
  15. *
  16.  
  17. * This program is in the Public Domain. You may freely use, modify
  18.  
  19. * and distribute this program.
  20.  
  21. *
  22.  
  23. *
  24.  
  25. * Description:
  26.  
  27. * This program shows an easy way to make simple explosions using
  28.  
  29. * OpenGL. Press SPACE to blow the rotating cube to pieces! Use
  30.  
  31. * the menu to toggle between normalized speed vectors and non-
  32.  
  33. * normalized speed vectors.
  34.  
  35. *
  36.  
  37. * Theory:
  38.  
  39. * This program uses an extremely simple particle system to create
  40.  
  41. * an explosion effect. Each particle is moved from the origin
  42.  
  43. * towards a random direction and, if activated, a random speed.
  44.  
  45. * The color of the particles are changed from white to orange to
  46.  
  47. * red to create a glowing effect. The GL_POINTS primitive is used
  48.  
  49. * to render the particles.
  50.  
  51. * The debris is similar to the particles, with the addition of
  52.  
  53. * orientation and orientation speed.
  54.  
  55. * A point light source is placed in the center of the explosion.
  56.  
  57. *
  58.  
  59. */
  60.  
  61. #include <GL/glut.h>
  62.  
  63. #include <math.h>
  64.  
  65. #include <stdlib.h>
  66.  
  67. #include <time.h>
  68.  
  69. #include <sys/types.h>
  70.  
  71. #include <stdio.h>
  72.  
  73. #define NUM_PARTICLES 1000 /* Number of particles */
  74.  
  75. #define NUM_DEBRIS 70 /* Number of debris */
  76.  
  77. /* GLUT menu entries */
  78.  
  79. #define PAUSE 0
  80.  
  81. #define NORMALIZE_SPEED 1
  82.  
  83. #define QUIT 2
  84.  
  85. /* A particle */
  86.  
  87. struct particleData
  88.  
  89. {
  90.  
  91.         float position[3];
  92.  
  93.         float speed[3];
  94.  
  95.         float color[3];
  96.  
  97. };
  98.  
  99. typedef struct particleData particleData;
  100.  
  101. /* A piece of debris */
  102.  
  103. struct debrisData
  104.  
  105. {
  106.  
  107.         float position[3];
  108.  
  109.         float speed[3];
  110.  
  111.         float orientation[3]; /* Rotation angles around x, y, and z axes */
  112.  
  113.         float orientationSpeed[3];
  114.  
  115.         float color[3];
  116.  
  117.         float scale[3];
  118.  
  119. };
  120.  
  121. typedef struct debrisData debrisData;
  122.  
  123. /* Globals */
  124.  
  125. particleData particles[NUM_PARTICLES];
  126.  
  127. debrisData debris[NUM_DEBRIS];
  128.  
  129. int fuel = 0; /* "fuel" of the explosion */
  130.  
  131. float angle = 0.0; /* camera rotation angle */
  132.  
  133. //material * /
  134.  
  135. GLfloat light0Amb[4] = { 1.0, 0.6, 0.2, 1.0 };
  136.  
  137. GLfloat light0Dif[4] = { 1.0, 0.6, 0.2, 1.0 };
  138.  
  139. GLfloat light0Spec[4] = { 0.0, 0.0, 0.0, 1.0 };
  140.  
  141. GLfloat light0Pos[4] = { 0.0, 0.0, 0.0, 1.0 };
  142.  
  143. GLfloat light1Amb[4] = { 0.0, 0.0, 0.0, 1.0 };
  144.  
  145. GLfloat light1Dif[4] = { 1.0, 1.0, 1.0, 1.0 };
  146.  
  147. GLfloat light1Spec[4] = { 1.0, 1.0, 1.0, 1.0 };
  148.  
  149. GLfloat light1Pos[4] = { 0.0, 5.0, 5.0, 0.0 };
  150.  
  151. GLfloat materialAmb[4] = { 0.25, 0.22, 0.26, 1.0 };
  152.  
  153. GLfloat materialDif[4] = { 0.63, 0.57, 0.60, 1.0 };
  154.  
  155. GLfloat materialSpec[4] = { 0.99, 0.91, 0.81, 1.0 };
  156.  
  157. GLfloat materialShininess = 27.8;
  158.  
  159. int wantNormalize = 0; /* Speed vector normalization flag */
  160.  
  161. int wantPause = 0; /* Pause flag */
  162.  
  163. void
  164.  
  165. newSpeed(float dest[3])
  166.  
  167. {
  168.  
  169.         float x;
  170.  
  171.         float y;
  172.  
  173.         float z;
  174.  
  175.         float len;
  176.  
  177.         x = (2.0 * ((GLfloat)rand()) / ((GLfloat)RAND_MAX)) - 1.0;
  178.  
  179.         y = (2.0 * ((GLfloat)rand()) / ((GLfloat)RAND_MAX)) - 1.0;
  180.  
  181.         z = (2.0 * ((GLfloat)rand()) / ((GLfloat)RAND_MAX)) - 1.0;
  182.  
  183.         /*
  184.  
  185.         * Normalizing the speed vectors gives a "fireball" effect
  186.  
  187.         *
  188.  
  189.         */
  190.  
  191.         if (wantNormalize)
  192.  
  193.         {
  194.  
  195.                 len = sqrt(x * x + y * y + z * z);
  196.  
  197.                 if (len)
  198.  
  199.                 {
  200.  
  201.                         x = x / len;
  202.  
  203.                         y = y / len;
  204.  
  205.                         z = z / len;
  206.  
  207.                 }
  208.  
  209.         }
  210.  
  211.         dest[0] = x;
  212.  
  213.         dest[1] = y;
  214.  
  215.         dest[2] = z;
  216.  
  217. }
  218.  
  219. /*
  220.  
  221. * newExplosion
  222.  
  223. *
  224.  
  225. * Create a new explosion.
  226.  
  227. *
  228.  
  229. */
  230.  
  231. void newExplosion(void)
  232.  
  233. {
  234.  
  235.         int i;
  236.  
  237.         for (i = 0; i < NUM_PARTICLES; i++)
  238.  
  239.         {
  240.  
  241.                 particles[i].position[0] = 0.0;
  242.  
  243.                 particles[i].position[1] = 0.0;
  244.  
  245.                 particles[i].position[2] = 0.0;
  246.  
  247.                 particles[i].color[0] = 1.0;
  248.  
  249.                 particles[i].color[1] = 1.0;
  250.  
  251.                 particles[i].color[2] = 0.5;
  252.  
  253.                 newSpeed(particles[i].speed);
  254.  
  255.         }
  256.  
  257.         for (i = 0; i < NUM_DEBRIS; i++)
  258.  
  259.         {
  260.  
  261.                 debris[i].position[0] = 0.0;
  262.  
  263.                 debris[i].position[1] = 0.0;
  264.  
  265.                 debris[i].position[2] = 0.0;
  266.  
  267.                 debris[i].orientation[0] = 0.0;
  268.  
  269.                 debris[i].orientation[1] = 0.0;
  270.  
  271.                 debris[i].orientation[2] = 0.0;
  272.  
  273.                 debris[i].color[0] = 0.7;
  274.  
  275.                 debris[i].color[1] = 0.7;
  276.  
  277.                 debris[i].color[2] = 0.7;
  278.  
  279.                 debris[i].scale[0] = (2.0 *
  280.  
  281.                         ((GLfloat)rand()) / ((GLfloat)RAND_MAX)) - 1.0;
  282.  
  283.                 debris[i].scale[1] = (2.0 *
  284.  
  285.                         ((GLfloat)rand()) / ((GLfloat)RAND_MAX)) - 1.0;
  286.  
  287.                 debris[i].scale[2] = (2.0 *
  288.  
  289.                         ((GLfloat)rand()) / ((GLfloat)RAND_MAX)) - 1.0;
  290.  
  291.                 newSpeed(debris[i].speed);
  292.  
  293.                 newSpeed(debris[i].orientationSpeed);
  294.  
  295.         }
  296.  
  297.         fuel = 100;
  298.  
  299. }
  300.  
  301. /*
  302.  
  303. * display
  304.  
  305. *
  306.  
  307. * Draw the scene.
  308.  
  309. *
  310.  
  311. */
  312.  
  313. void display(void)
  314.  
  315. {
  316.  
  317.         int i;
  318.  
  319.         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  320.  
  321.         glLoadIdentity();
  322.  
  323.         /* Place the camera */
  324.  
  325.         glTranslatef(0.0, 0.0, -10.0);
  326.  
  327.         glRotatef(angle, 0.0, 1.0, 0.0);
  328.  
  329.         /* If no explosion, draw cube */
  330.  
  331.         if (fuel == 0)
  332.  
  333.         {
  334.  
  335.                 glEnable(GL_LIGHTING);
  336.  
  337.                 glDisable(GL_LIGHT0);
  338.  
  339.                 glEnable(GL_DEPTH_TEST);
  340.  
  341.                 glutSolidCube(1.0);
  342.  
  343.                 //glutSolidCone(2.0, 2.0, 5, 5);
  344.  
  345.         }
  346.  
  347.         if (fuel > 0)
  348.  
  349.         {
  350.  
  351.                 glPushMatrix();
  352.  
  353.                 glDisable(GL_LIGHTING);
  354.  
  355.                 glDisable(GL_DEPTH_TEST);
  356.  
  357.                 glBegin(GL_POINTS);
  358.  
  359.                 for (i = 0; i < NUM_PARTICLES; i++)
  360.  
  361.                 {
  362.  
  363.                         glColor3fv(particles[i].color);
  364.  
  365.                         glVertex3fv(particles[i].position);
  366.  
  367.                 }
  368.  
  369.                 glEnd();
  370.  
  371.                 glPopMatrix();
  372.  
  373.                 glEnable(GL_LIGHTING);
  374.  
  375.                 glEnable(GL_LIGHT0);
  376.  
  377.                 glEnable(GL_DEPTH_TEST);
  378.  
  379.                 glNormal3f(0.0, 0.0, 1.0);
  380.  
  381.                 for (i = 0; i < NUM_DEBRIS; i++)
  382.  
  383.                 {
  384.  
  385.                         glColor3fv(debris[i].color);
  386.  
  387.                         glPushMatrix();
  388.  
  389.                         glTranslatef(debris[i].position[0],
  390.  
  391.                                 debris[i].position[1],
  392.  
  393.                                 debris[i].position[2]);
  394.  
  395.                         glRotatef(debris[i].orientation[0], 1.0, 0.0, 0.0);
  396.  
  397.                         glRotatef(debris[i].orientation[1], 0.0, 1.0, 0.0);
  398.  
  399.                         glRotatef(debris[i].orientation[2], 0.0, 0.0, 1.0);
  400.  
  401.                         glScalef(debris[i].scale[0],
  402.  
  403.                                 debris[i].scale[1],
  404.  
  405.                                 debris[i].scale[2]);
  406.  
  407.                         glBegin(GL_TRIANGLES);
  408.  
  409.                         glVertex3f(0.0, 0.5, 0.0);
  410.  
  411.                         glVertex3f(-0.25, 0.0, 0.0);
  412.  
  413.                         glVertex3f(0.25, 0.0, 0.0);
  414.  
  415.                         glEnd();
  416.  
  417.                         glPopMatrix();
  418.  
  419.                 }
  420.  
  421.         }
  422.  
  423.         glutSwapBuffers();
  424.  
  425. }
  426.  
  427. /*
  428.  
  429. * keyboard
  430.  
  431. *
  432.  
  433. * Keyboard callback.
  434.  
  435. *
  436.  
  437. */
  438.  
  439. void keyboard(unsigned char key,
  440.  
  441.         int x,
  442.  
  443.         int y)
  444.  
  445. {
  446.  
  447.         switch (key)
  448.  
  449.         {
  450.  
  451.         case ' ':
  452.  
  453.         case 27:
  454.  
  455.                 newExplosion();
  456.  
  457.                 break;
  458.  
  459.                 exit(0);
  460.  
  461.                 break;
  462.  
  463.                 wantPause = 1 - wantPause;
  464.  
  465.                 break;
  466.  
  467.         case 'p':
  468.                 break;
  469.  
  470.         }
  471.  
  472. }
  473.  
  474. /*
  475.  
  476. * idle
  477.  
  478. *
  479.  
  480. * Update animation variables.
  481.  
  482. *
  483.  
  484. */
  485.  
  486. void idle(void)
  487.  
  488. {
  489.  
  490.         int i;
  491.  
  492.         if (!wantPause)
  493.  
  494.         {
  495.  
  496.                 if (fuel > 0)
  497.  
  498.                 {
  499.  
  500.                         for (i = 0; i < NUM_PARTICLES; i++)
  501.  
  502.                         {
  503.  
  504.                                 particles[i].position[0] += particles[i].speed[0] * 0.2;
  505.  
  506.                                 particles[i].position[1] += particles[i].speed[1] * 0.2;
  507.  
  508.                                 particles[i].position[2] += particles[i].speed[2] * 0.2;
  509.  
  510.                                 particles[i].color[0] -= 1.0 / 500.0;
  511.  
  512.                                 if (particles[i].color[0] < 0.0)
  513.  
  514.                                 {
  515.  
  516.                                 }
  517.  
  518.                                 particles[i].color[1] -= 1.0 / 100.0;
  519.  
  520.                                 if (particles[i].color[1] < 0.0)
  521.  
  522.                                 {
  523.  
  524.                                 }
  525.  
  526.                                 particles[i].color[2] -= 1.0 / 50.0;
  527.  
  528.                                 if (particles[i].color[2] < 0.0)
  529.  
  530.                                 {
  531.  
  532.                                 }
  533.  
  534.                         }
  535.  
  536.                         for (i = 0; i < NUM_DEBRIS; i++)
  537.  
  538.                         {
  539.  
  540.                                 debris[i].position[0] += debris[i].speed[0] * 0.1;
  541.  
  542.                                 debris[i].position[1] += debris[i].speed[1] * 0.1;
  543.  
  544.                                 debris[i].position[2] += debris[i].speed[2] * 0.1;
  545.  
  546.                                 debris[i].orientation[0] += debris[i].orientationSpeed[0] * 10;
  547.  
  548.                                 debris[i].orientation[1] += debris[i].orientationSpeed[1] * 10;
  549.  
  550.                                 debris[i].orientation[2] += debris[i].orientationSpeed[2] * 10;
  551.  
  552.                         }
  553.  
  554.                         --fuel;
  555.  
  556.                 }
  557.  
  558.                 angle += 0.3; /* Always continue to rotate the camera */
  559.  
  560.         }
  561.  
  562.         glutPostRedisplay();
  563.  
  564. }
  565.  
  566. /*
  567.  
  568. * reshape
  569.  
  570. *
  571.  
  572. * Window reshape callback.
  573.  
  574. *
  575.  
  576. */
  577.  
  578. void reshape(int w,
  579.  
  580.         int h)
  581.  
  582. {
  583.  
  584.         glViewport(0.0, 0.0, (GLfloat)w, (GLfloat)h);
  585.  
  586.         glMatrixMode(GL_PROJECTION);
  587.  
  588.         glLoadIdentity();
  589.  
  590.         gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 0.1, 100.0);
  591.  
  592.         glMatrixMode(GL_MODELVIEW);
  593.  
  594. }
  595.  
  596. /*
  597.  
  598. * menuSelect
  599.  
  600. *
  601.  
  602. * Menu selection callback.
  603.  
  604. *
  605.  
  606. */
  607.  
  608. void menuSelect(int value)
  609.  
  610. {
  611.  
  612.         switch (value)
  613.  
  614.         {
  615.  
  616.         case PAUSE:
  617.  
  618.                 wantPause = 1 - wantPause;
  619.  
  620.                 break;
  621.  
  622.         case NORMALIZE_SPEED:
  623.  
  624.                 wantNormalize = 1 - wantNormalize;
  625.  
  626.                 break;
  627.  
  628.                 exit(0);
  629.  
  630.                 break;
  631.  
  632.         case QUIT:
  633.                 break;
  634.         }
  635.  
  636. }
  637.  
  638. /*
  639.  
  640. * main
  641.  
  642. *
  643.  
  644. * Setup OpenGL and hand over to GLUT.
  645.  
  646. *
  647.  
  648. */
  649.  
  650. int main(int argc,
  651.  
  652.         char *argv[])
  653.  
  654. {
  655.  
  656.         glutInit(&argc, argv);
  657.  
  658.         glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
  659.  
  660.         glutCreateWindow("Explosion demo");
  661.  
  662.         glutKeyboardFunc(keyboard);
  663.  
  664.         glutIdleFunc(idle);
  665.  
  666.         glutDisplayFunc(display);
  667.  
  668.         glutReshapeFunc(reshape);
  669.  
  670.         srand(time(NULL));
  671.  
  672.         glEnable(GL_LIGHT0);
  673.  
  674.         glEnable(GL_LIGHT1);
  675.  
  676.         glLightfv(GL_LIGHT0, GL_AMBIENT, light0Amb);
  677.  
  678.         glLightfv(GL_LIGHT0, GL_DIFFUSE, light0Dif);
  679.  
  680.         glLightfv(GL_LIGHT0, GL_SPECULAR, light0Spec);
  681.  
  682.         glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
  683.  
  684.         glLightfv(GL_LIGHT1, GL_AMBIENT, light1Amb);
  685.  
  686.         glLightfv(GL_LIGHT1, GL_DIFFUSE, light1Dif);
  687.  
  688.         glLightfv(GL_LIGHT1, GL_SPECULAR, light1Spec);
  689.  
  690.         glLightfv(GL_LIGHT1, GL_POSITION, light1Pos);
  691.  
  692.         glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  693.  
  694.         glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, materialAmb);
  695.  
  696.         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, materialDif);
  697.  
  698.         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, materialSpec);
  699.  
  700.         glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, materialShininess);
  701.  
  702.         glEnable(GL_NORMALIZE);
  703.  
  704.         glutCreateMenu(menuSelect);
  705.  
  706.         glutAddMenuEntry("Pause", PAUSE);
  707.  
  708.         glutAddMenuEntry("Toggle normalized speed vectors", NORMALIZE_SPEED);
  709.  
  710.         glutAddMenuEntry("Quit", QUIT);
  711.  
  712.         glutAttachMenu(GLUT_RIGHT_BUTTON);
  713.  
  714.         glutMainLoop();
  715.  
  716.         return 0;
  717.  
  718. }