00001
00007 #include "OpenGLParticleSystem.h"
00008
00009 void OpenGLParticleSystem::draw() {
00010
00011 Vec3 v;
00012
00013
00014 glBegin(GL_QUADS);
00015 for (int i=0; i<MAX_PARTICLES; i++) {
00016 if (m_particles[i].m_age >= 0.0f) {
00017
00018 glColor4f( m_particles[i].m_color.x,
00019 m_particles[i].m_color.y,
00020 m_particles[i].m_color.z,
00021 m_particles[i].m_alpha );
00022
00023
00024
00025 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
00026 glVertex3f(
00027 m_particles[i].m_location.x-m_particles[i].m_size,
00028 m_particles[i].m_location.y-m_particles[i].m_size,
00029 m_particles[i].m_location.z );
00030
00031 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
00032 glVertex3f(
00033 m_particles[i].m_location.x-m_particles[i].m_size,
00034 m_particles[i].m_location.y+m_particles[i].m_size,
00035 m_particles[i].m_location.z );
00036
00037 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
00038 glVertex3f(
00039 m_particles[i].m_location.x+m_particles[i].m_size,
00040 m_particles[i].m_location.y+m_particles[i].m_size,
00041 m_particles[i].m_location.z );
00042
00043 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
00044 glVertex3f(
00045 m_particles[i].m_location.x+m_particles[i].m_size,
00046 m_particles[i].m_location.y-m_particles[i].m_size,
00047 m_particles[i].m_location.z );
00048
00049 }
00050 }
00051 glEnd();
00052
00053 }
00054
00055 bool OpenGLParticleSystem::drawAndUpdate(Camera *camera, float dTime, bool absoluteTime, bool billboard) {
00056 if (absoluteTime) {
00057 float time = dTime;
00058 dTime = dTime - m_timeLastUpdate;
00059 m_timeLastUpdate = time;
00060 }
00061
00062 if (!m_alive && m_particlesAlive == 0)
00063 return true;
00064
00065
00066 if (m_isMoving) {
00067 static float thetaHoriz = 0.0f;
00068 static float thetaVert = 180.0f;
00069
00070 thetaHoriz += 250.0f * dTime;
00071 thetaVert += 30.0f * dTime;
00072
00073 if (thetaHoriz > 350.0f)
00074 thetaHoriz = 0.0f;
00075
00076 if (thetaVert > 359.0f)
00077 thetaVert = 0.0f;
00078
00079 m_location.x = m_baseLocation.x + 0.5f*(float)cos(thetaHoriz*0.01745f);
00080
00081 m_location.z = m_baseLocation.z + 0.5f*(float)sin(thetaHoriz*0.01645f);
00082 }
00083 else {
00084
00085
00086
00087 }
00088
00089 m_particlesAlive = 0;
00090
00091 float mat[16];
00092 glGetFloatv(GL_MODELVIEW_MATRIX, mat);
00093
00094 Vec3 vRight(mat[0], mat[4], mat[8]);
00095 Vec3 vUp(mat[1], mat[5], mat[9]);
00096 Vec3 vPoint0, vPoint1, vPoint2, vPoint3;
00097 Vec3 vCenter;
00098
00099 glBegin(GL_QUADS);
00100 for (int i=0; i<MAX_PARTICLES; i++) {
00101 if (m_particles[i].m_age >= 0.0f) {
00102 if (m_particles[i].update(dTime)) {
00103 m_particlesAlive++;
00104
00105 if (billboard) {
00106 vCenter = m_particles[i].m_location;
00107
00108 vPoint0 = vCenter + ((-vRight - vUp) * m_particles[i].m_size);
00109 vPoint1 = vCenter + (( vRight - vUp) * m_particles[i].m_size );
00110 vPoint2 = vCenter + (( vRight + vUp) * m_particles[i].m_size );
00111 vPoint3 = vCenter + ((-vRight + vUp) * m_particles[i].m_size );
00112
00113 glColor4f( m_particles[i].m_color.x,
00114 m_particles[i].m_color.y,
00115 m_particles[i].m_color.z,
00116 m_particles[i].m_alpha );
00117
00118
00119 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
00120 glVertex3fv(vPoint0);
00121
00122 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
00123 glVertex3fv(vPoint1);
00124
00125 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
00126 glVertex3fv(vPoint2);
00127
00128 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
00129 glVertex3fv(vPoint3);
00130
00131 }
00132 else {
00133
00134 glColor4f( m_particles[i].m_color.x,
00135 m_particles[i].m_color.y,
00136 m_particles[i].m_color.z,
00137 m_particles[i].m_alpha );
00138
00139 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 0);
00140 glVertex3f(
00141 m_particles[i].m_location.x-m_particles[i].m_size,
00142 m_particles[i].m_location.y-m_particles[i].m_size,
00143 m_particles[i].m_location.z );
00144
00145 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0, 1);
00146 glVertex3f(
00147 m_particles[i].m_location.x-m_particles[i].m_size,
00148 m_particles[i].m_location.y+m_particles[i].m_size,
00149 m_particles[i].m_location.z );
00150
00151 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 1);
00152 glVertex3f(
00153 m_particles[i].m_location.x+m_particles[i].m_size,
00154 m_particles[i].m_location.y+m_particles[i].m_size,
00155 m_particles[i].m_location.z );
00156
00157 glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 1, 0);
00158 glVertex3f(
00159 m_particles[i].m_location.x+m_particles[i].m_size,
00160 m_particles[i].m_location.y-m_particles[i].m_size,
00161 m_particles[i].m_location.z );
00162 }
00163 }
00164 }
00165 }
00166 glEnd();
00167
00168
00169 if (!m_alive)
00170 return true;
00171
00172
00173 float particlesNeeded = m_particlesPerSec*dTime + m_emissionResidue;
00174
00175 unsigned int particlesCreated = (unsigned int)particlesNeeded;
00176
00177 if (!m_isSuppressed) {
00178 m_emissionResidue = particlesNeeded - particlesCreated;
00179 }
00180 else {
00181 m_emissionResidue = particlesNeeded;
00182 particlesCreated = 0;
00183 }
00184
00185
00186
00187 if (particlesCreated > 0) {
00188 for (i=0; i<MAX_PARTICLES; i++) {
00189 if (!particlesCreated)
00190 break;
00191
00192
00193 if (m_particles[i].m_age < 0.0f) {
00194 m_particles[i].m_age = 0.0f;
00195 m_particles[i].m_lifetime = m_life + RANDOM_NUM * m_lifeVar;
00196 Clamp(m_particles[i].m_lifetime, MIN_LIFETIME, MAX_LIFETIME);
00197
00198 m_particles[i].m_color.x = m_colorStart.x + RANDOM_NUM * m_colorVar.x;
00199 m_particles[i].m_color.y = m_colorStart.y + RANDOM_NUM * m_colorVar.y;
00200 m_particles[i].m_color.z = m_colorStart.z + RANDOM_NUM * m_colorVar.z;
00201 m_particles[i].m_color.w = 1.0f;
00202
00203 Clamp(m_particles[i].m_color.x, 0.0f, 1.0f);
00204 Clamp(m_particles[i].m_color.y, 0.0f, 1.0f);
00205 Clamp(m_particles[i].m_color.z, 0.0f, 1.0f);
00206
00207 m_particles[i].m_dColor.x = (m_colorEnd.x - m_particles[i].m_color.x)/m_particles[i].m_lifetime;
00208 m_particles[i].m_dColor.y = (m_colorEnd.y - m_particles[i].m_color.y)/m_particles[i].m_lifetime;
00209 m_particles[i].m_dColor.z = (m_colorEnd.z - m_particles[i].m_color.z)/m_particles[i].m_lifetime;
00210
00211 m_particles[i].m_alpha = m_alphaStart + RANDOM_NUM*m_alphaVar;
00212 Clamp(m_particles[i].m_alpha, MIN_ALPHA, MAX_ALPHA);
00213 m_particles[i].m_dAlpha = (m_alphaEnd - m_particles[i].m_alpha) / m_particles[i].m_lifetime;
00214
00215 m_particles[i].m_size = m_sizeStart + RANDOM_NUM*m_sizeVar;
00216 Clamp(m_particles[i].m_size, MIN_SIZE, MAX_SIZE);
00217 m_particles[i].m_dSize = (m_sizeEnd - m_particles[i].m_size) / m_particles[i].m_lifetime;
00218
00219 m_particles[i].m_size *= 0.01f;
00220 m_particles[i].m_dSize *= 0.01f;
00221
00222
00223 m_particles[i].m_gravity = m_gravityStart*9.82f + RANDOM_NUM*m_gravityVar*9.82f;
00224 Clamp(m_particles[i].m_gravity, MIN_GRAVITY*9.82f, MAX_GRAVITY*9.82f);
00225 m_particles[i].m_dGravity = (m_gravityEnd*9.82f - m_particles[i].m_gravity) / m_particles[i].m_lifetime;
00226
00227 m_particles[i].m_gravity *= 0.01f;
00228 m_particles[i].m_dGravity *= 0.01f;
00229
00230
00231 Vec3 tmpVelocity = (m_location - m_prevLocation)/dTime;
00232
00233 m_particles[i].m_location = m_prevLocation + tmpVelocity*RANDOM_NUM*dTime;
00234
00235 m_particles[i].m_prevLocation = m_location;
00236
00237 float randomYaw = RANDOM_NUM*3.14159f*2.0f;
00238 float randomPitch = RANDOM_NUM*m_theta*3.14159f/180.0f;
00239
00240 m_particles[i].m_velocity.y = cosf(randomPitch);
00241 m_particles[i].m_velocity.x = sinf(randomPitch)*cosf(randomYaw);
00242 m_particles[i].m_velocity.z = sinf(randomPitch)*sinf(randomYaw);
00243
00244
00245
00246
00247
00248 float newSpeed = m_speed + RANDOM_NUM*m_speedVar;
00249 Clamp(newSpeed, MIN_SPEED, MAX_SPEED);
00250
00251 m_particles[i].m_velocity *= newSpeed;
00252
00253 m_particles[i].m_velocity *= 0.01f;
00254
00255 m_particles[i].setParent(this);
00256
00257 particlesCreated--;
00258 }
00259 }
00260 }
00261
00262 m_prevLocation = m_location;
00263
00264 return true;
00265 }