Facebook
From MT, 7 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 338
  1. #undef UNICODE
  2. #include <windows.h>
  3. #include <iostream>
  4. #include <vector>
  5. #include <list>
  6. #define GLUT_DISABLE_ATEXIT_HACK
  7.  
  8. #include <math.h>
  9. #include <ctime>
  10. #include "GL/glut.h"
  11. #include <GL/gl.h>
  12. #include "teksture.h"
  13. //#include <math.h>
  14.  
  15. using namespace std;
  16.  
  17. static double x, y;
  18. static double dx = 1;
  19. static double dy = 0.5;
  20. static double cr = 0;
  21.  
  22. struct SParticle
  23. {
  24.   GLfloat lifetime;                                     //current lifetime of the particle
  25.   GLfloat maximum_lifetime;                       //time of death of particle
  26.   GLfloat r,g,b;                          // color values of the particle
  27.   GLfloat xpos,ypos,zpos;                 // position of the particle
  28.   GLfloat xspeed,yspeed,zspeed;           // speed of the particle
  29.   //TODO: add new parameters if needed
  30. };
  31. struct SVertex {
  32.         GLfloat tx, ty;
  33.         GLfloat x, y, z;
  34.        
  35. };
  36. const float s = 0.5;
  37. SVertex bilboard[] =
  38. {
  39.         {0,0,                   -s,-s,0},
  40.         {0,1,                   -s,s,0},
  41.         {1,1,                   s,s,0},
  42.         {1,0,                   s,-s,0}
  43. };
  44. const int MAX_PARTICLES = 500;
  45. list<SParticle> Particles;
  46. list<SParticle>::iterator particle_iter;
  47. //TODO: texture for particles - change if You want
  48. const char texture_name[] = "media//particlewhite.bmp";
  49. Ctexture *bilboard_tex;
  50. //Gaussian random number generator - mean 0.0, standard deviation 1.0
  51. float   NRand()
  52. {
  53.          static int q = 15;
  54.          static float c1 = (1 << q) - 1;
  55.          static float c2 = ((int)(c1 / 3)) + 1;
  56.          static float c3 = 1.f / c1;
  57.         /* random number in range 0 - 1 not including 1 */
  58.         float random = 0.f;
  59.  
  60.         /* the white noise */
  61.         float noise = 0.f;
  62.         random = ((float)(rand()) / (float)(RAND_MAX + 1));
  63.         random = (2.f * ((random * c2) + (random * c2) + (random * c2)) - 3.f * (c2 - 1.f)) * c3;
  64.         return random;
  65. }
  66. //single bilboard drawing
  67. void bilboarddrawinglist()
  68. {
  69.        
  70.         glNewList(1,GL_COMPILE);
  71.         glPushMatrix();
  72.         // Wlaczamy tablice koordynatow tekstur
  73.         glEnableClientState(GL_TEXTURE_COORD_ARRAY);   
  74.         // Wlaczamy tablice wspolrzednych wierzcholkow
  75.         glEnableClientState(GL_VERTEX_ARRAY);
  76.  
  77.  
  78.         glInterleavedArrays( GL_T2F_V3F, 0, (GLvoid*)bilboard);
  79.         glDrawArrays(GL_QUADS, 0, 4);
  80.         glPopMatrix();
  81.         glEndList();
  82. }
  83.  
  84. int initTexture(void)
  85. {
  86.                 glEnable(GL_TEXTURE_2D);
  87.  
  88.                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  89.  
  90.  
  91.                 // texture for particle
  92.  
  93.                 bilboard_tex = new Ctexture(texture_name);
  94.  
  95.                 //empty texture, currently not needed
  96.                 //tekstury[0] = new Ctexture();
  97.                 return true;
  98. }
  99. void drawScene(void)
  100. {
  101.    // Clear screen to background color.
  102.    glClear(GL_COLOR_BUFFER_BIT);
  103.  
  104.    // Set foreground (or drawing) color.
  105.    glColor3f(1.0, 0.0, 0.0);
  106.  
  107.    if(bilboard_tex)bilboard_tex->Bind();
  108.    list<SParticle>::iterator currP = Particles.begin();
  109.    //TODO 0: Set proper render states in OpenGL - blending and depth test
  110.    // glEnable() with GL_BLEND, glBlendFunc() with GL_ONE,GL_ONE and glDisable() GL_DEPTH_TEST
  111.    //notice what happens if they are not set
  112.  
  113.    glEnable(GL_BLEND);
  114.    glBlendFunc(GL_ONE, GL_ONE);
  115.    glDisable(GL_DEPTH_TEST);
  116.  
  117.    for(unsigned int i = 0;i<Particles.size();i++,currP++)
  118.    {
  119.            glPushMatrix();
  120.            
  121.            //Draw particle
  122.            //TODO 1: set particles params like color or size (glColor3f glScalef), posision is done for example
  123.            
  124.            glColor3f(currP->r, currP->g, currP->b);
  125.            glTranslatef(currP->xpos,currP->ypos,currP->zpos);
  126.            //...
  127.  
  128.            //Draw particle
  129.            glCallList(1);
  130.            glPopMatrix();
  131.    }
  132.    
  133.  
  134.    
  135.    glutSwapBuffers();
  136. }
  137.  
  138. // Initialization routine.
  139. void setup(void)
  140. {
  141.         x = 0;
  142.         y = 0;
  143.    // Set background (or clearing) color.
  144.    glClearColor(0.0, 0.0, 0.0, 0.0);
  145.    initTexture();
  146.    bilboarddrawinglist();
  147.    
  148. }
  149.  
  150. // OpenGL window reshape routine.
  151. void resize(int w, int h)
  152. {
  153.    // Set viewport size to be entire OpenGL window.
  154.    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
  155.  
  156.    // Set matrix mode to projection.
  157.    glMatrixMode(GL_PROJECTION);
  158.  
  159.    // Clear current projection matrix to identity.
  160.    glLoadIdentity();
  161.  
  162.    // Specify the orthographic (or perpendicular) projection,
  163.    // i.e., define the viewing box.
  164.    gluPerspective(90,(float)w/(float)h,1,200);
  165.   //glOrtho(-10.0, 10.0, -10.0, 10.0,-10.0, 10.0);
  166.   //glFrustum(-10.0, 10.0, -10.0, 10.0, 5.0, 100.0);
  167.  
  168.    // Set matrix mode to modelview.
  169.    glMatrixMode(GL_MODELVIEW);
  170.  
  171.    // Clear current modelview matrix to identity.
  172.    glLoadIdentity();
  173. }
  174. void EmitParticles()
  175. {
  176.         //TODO 2:
  177.         //Emit particles:
  178.         //set parameters for new particles (SParticle structure),
  179.         //You can add new parameters to the SParticle structure
  180.         //For random numbers use NRand() - Gaussian  random number generator - mean 0.0, standard deviation 1.0
  181.         for(int i = 0;i<=15;i++)
  182.         {
  183.                 SParticle NewPArticle =
  184.                 {/* current lifetime - 0 at start*/ 0,
  185.                 /* maximum lifetime in seconds*/ abs(NRand())*0.2+1.0,
  186.                 /*color R,G,B, float*/0.0, abs(NRand()) * 0.1 + 0.1, abs(NRand()) * 0.2 + 0.8,
  187.                 /*pos: X = 0 , Y = -8, Z = -10 is around bottom*/NRand() * 3,4,-5,
  188.                 /*speed*/ 0,0,0,
  189.                 };
  190.  
  191.                 Particles.push_front(NewPArticle);
  192.         }
  193. }
  194. void AffectParticles()
  195. {
  196.         list<SParticle> ParticlesToRemove;
  197.         static std::clock_t  oldtime = std::clock();
  198.         std::clock_t newtime = std::clock();
  199.         double timebetweenframes = (double)(newtime - oldtime) / (double) CLOCKS_PER_SEC;
  200.  
  201.        
  202.         particle_iter = Particles.begin();
  203.         while(particle_iter != Particles.end())
  204.         {
  205.                 //TODO 3:
  206.                 //update particle parameters:
  207.                 //position, color (fading color for example), speed(gravity for example)
  208.                 //timebetweenframes - delta time, can be used for updating position in current frame like: particle_iter->ypos + particle_iter->yspeed*timebetweenframes
  209.                 //particle_iter->lifetime/particle_iter->maximum_lifetime - usefull proportion for changing color and size
  210.                 //...
  211.  
  212.                 if(particle_iter->lifetime < 0.2)
  213.                         particle_iter->yspeed += NRand() * 0.01 + 0.01;
  214.                 else if (particle_iter->lifetime / particle_iter->maximum_lifetime > 0.7)
  215.                 {
  216.                         particle_iter->b -= 0.1;
  217.                         particle_iter->g -= 0.1;
  218.                 }
  219.  
  220.                 particle_iter->ypos -= particle_iter->yspeed;
  221.  
  222.                 //removing particles
  223.                 particle_iter->lifetime = particle_iter->lifetime+timebetweenframes;
  224.                 if(particle_iter->lifetime >= particle_iter->maximum_lifetime)
  225.                 {
  226.                         //if You need to create particles in place when other died (fireworks particle effect for example)
  227.                         //Then You can create them here like in TODO 1
  228.                         particle_iter = Particles.erase(particle_iter);
  229.                 }
  230.                 else
  231.                         particle_iter++;
  232.                        
  233.         }
  234.         cout << Particles.size() << endl;
  235.  
  236.         oldtime = newtime;
  237. }
  238. void animate() {
  239.         EmitParticles();
  240.         AffectParticles();
  241.     glutPostRedisplay();
  242. }
  243.  
  244. // Keyboard input processing routine.
  245. void keyInput(unsigned char key, int x, int y)
  246. {
  247.  
  248. }
  249.  
  250. // Mouse callback routine.
  251. void mouseControl(int button, int state, int x, int y)
  252. {
  253.  
  254.  
  255. }
  256.  
  257. // Main routine: defines window properties, creates window,
  258. // registers callback routines and begins processing.
  259. int main(int argc, char **argv)
  260. {  
  261.    // Initialize GLUT.
  262.    glutInit(&argc, argv);
  263.  
  264.    // Set display mode as single-buffered and RGB color.
  265.    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE );
  266.    
  267.    // Set OpenGL window size.
  268.    glutInitWindowSize(500, 500);
  269.  
  270.    // Set position of OpenGL window upper-left corner.
  271.    glutInitWindowPosition(100, 100);
  272.    
  273.    // Create OpenGL window with title.
  274.    glutCreateWindow("Laboratorium GK: 11_OGL");
  275.    
  276.    // Initialize.
  277.    setup();
  278.    
  279.    // Register display routine.
  280.    glutDisplayFunc(drawScene);
  281.    
  282.    // Register reshape routine.
  283.    glutReshapeFunc(resize);  
  284.    
  285.  
  286.    // Register the mouse and keyboard callback function.
  287.    glutMouseFunc(mouseControl);
  288.    glutKeyboardFunc(keyInput);
  289.  
  290.  
  291.    glutIdleFunc(animate);
  292.    // Begin processing.
  293.    glutMainLoop();
  294.  
  295.    if(bilboard_tex) delete bilboard_tex;
  296.    return 0;  
  297. }
  298.