OPENGL粒子,帮助随机化位置进行雪模拟

时间:2013-12-23 04:15:10

标签: visual-c++ opengl

我正在尝试使用粒子系统制作降雪模拟效果,我的意思是让粒子随机方向和随机起点和随机速度移动。以下代码示例具有沿x轴旋转30度的粒子。任何人都可以指出我需要在哪里进行更改才能进行降雪模拟

    //A single particle.
 struct Particle {
    Vec3f pos;
    Vec3f velocity;
    Vec3f color;
    float timeAlive; //The time that this particle has been alive.
    float lifespan;  //The total time that this particle is to live.
    };

  //Rotates the vector by the indicated number of degrees about the specified axis
   Vec3f rotate(Vec3f v, Vec3f axis, float degrees) {
     axis = axis.normalize();
     float radians = degrees * PI / 180;
     float s = sin(radians);
     float c = cos(radians);
    return v * c + axis * axis.dot(v) * (1 - c) + v.cross(axis) * s;
  }

  //Returns the position of the particle, after rotating the camera
  Vec3f adjParticlePos(Vec3f pos) {
    return rotate(pos, Vec3f(1, 0, 0), -30);
  } 

  //Returns whether particle1 is in back of particle2
   bool compareParticles(Particle* particle1, Particle* particle2) {

    return adjParticlePos(particle1->pos)[2] < adjParticlePos(particle2->pos)[2];
   }

   const float GRAVITY = 2.5f;
   const int NUM_PARTICLES = 1000;

   //steps.
  const float STEP_TIME = 0.01f;

  //length of each side of the square drawn -> for each particle.
  const float PARTICLE_SIZE = 0.025f;

  class SnowCreator {
    private:
        GLuint textureId;
        Particle particles[NUM_PARTICLES];
        // time to next call of step function
        float timeToStepFunc;

        float colorTime;    // color in a specific time

         //Returns the current color to white
         Vec3f curColor() {
             Vec3f color;

            if (colorTime <= 1.0f){
                color = Vec3f(1.0f, 1.0f, 1.0f);
            }
            return color;
        }

        //Returns the average velocity of particles
        Vec3f curVelocity() {
            return Vec3f((randomFloat() + 1) * cos(angle), 2.0f, 
                                        (randomFloat() + 1) * sin(angle));
        }

        //Alters p to be a particle newly produced.
        void snowParticle(Particle* p) {
            p->pos = Vec3f( randomFloat(), randomFloat(), randomFloat());
            p->velocity = curVelocity() + Vec3f(0.5f * randomFloat() - 0.25f, 
                                                        0.5f * randomFloat() - 0.25f,
                                                        0.5f * randomFloat() - 0.25f);


            p->color = curColor();
            p->timeAlive = 0;
            p->lifespan = randomFloat() + 2;    //help in fading
        }

         //Advances the particle by STEP_TIME seconds.
        void step() {
             colorTime += STEP_TIME / 10;
            while (colorTime >= 1) {
                 colorTime -= 1;
            }

            angle += 0.5f * STEP_TIME;
            while (angle > 2 * PI) {
                angle -= 2 * PI;
            }

            for(int i = 0; i < NUM_PARTICLES; i++) {
                Particle* p = particles + i;

                p->pos += p->velocity * STEP_TIME;
                p->velocity += Vec3f(0.0f,-GRAVITY * STEP_TIME, 0.0f);
                p->timeAlive += STEP_TIME;
                if (p->timeAlive > p->lifespan) {
                    snowParticle(p);
                }
            }
        }
    public:
        SnowCreator(GLuint textureId1) {
            textureId = textureId1;
            timeToStepFunc = 0;
            colorTime = 0;
            angle = 0;
            for(int i = 0; i < NUM_PARTICLES; i++) {
                snowParticle(particles + i);
            }
            for(int i = 0; i < 10 / STEP_TIME; i++) {
                step();
            }
        }

        //Advances the particle fountain by the specified amount of time.
        void advance(float dt) {
            while (dt > 0) {
                if (timeToStepFunc < dt) {
                    dt -= timeToStepFunc;
                    step();
                    timeToStepFunc = STEP_TIME;
                }
                else {
                    timeToStepFunc -= dt;
                    dt = 0;
                }
            }
        }

        //Draws the particle fountain.
        void draw() {
            vector<Particle*> ps;
            for(int i = 0; i < NUM_PARTICLES; i++) {
                ps.push_back(particles + i);
            }
            sort(ps.begin(), ps.end(), compareParticles);

            glEnable(GL_TEXTURE_2D);
            glBindTexture(GL_TEXTURE_2D, textureId);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

            glBegin(GL_QUADS);
            for(unsigned int i = 0; i < ps.size(); i++) {
                Particle* p = ps[i];
                glColor3f(p->color[0], p->color[1], p->color[2]); 
                float size = PARTICLE_SIZE / 2;

                Vec3f pos = adjParticlePos(p->pos);

                glTexCoord2f(0, 0);
                glVertex3f(pos[0] - size, pos[1] - size, pos[2]);
                glTexCoord2f(0, 1);
                glVertex3f(pos[0] - size, pos[1] + size, pos[2]);
                glTexCoord2f(1, 1);
                glVertex3f(pos[0] + size, pos[1] + size, pos[2]);
                glTexCoord2f(1, 0);
                glVertex3f(pos[0] + size, pos[1] - size, pos[2]);
            }
            glEnd();
        }
   };

0 个答案:

没有答案