00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <graph/ParticleRenderer.h>
00022 #include <graph/Particle.h>
00023 #include <sprites/ExplosionTextures.h>
00024 #include <sprites/DebrisActionRenderer.h>
00025 #include <sprites/SmokeActionRenderer.h>
00026 #include <sprites/NapalmRenderer.h>
00027 #include <sprites/ExplosionNukeRenderer.h>
00028 #include <sprites/WallActionRenderer.h>
00029 #include <landscape/Landscape.h>
00030 #include <landscapemap/LandscapeMaps.h>
00031 #include <landscape/ShadowMap.h>
00032 #include <client/ScorchedClient.h>
00033 #include <GLEXT/GLState.h>
00034 #include <GLEXT/GLCamera.h>
00035 #include <GLEXT/GLCameraFrustum.h>
00036 #include <GLEXT/GLInfo.h>
00037 #include <common/Defines.h>
00038 #include <math.h>
00039
00040 ParticleRendererPoints *ParticleRendererPoints::getInstance()
00041 {
00042 static ParticleRendererPoints instance_;
00043 return &instance_;
00044 }
00045
00046 void ParticleRendererPoints::simulateParticle(Particle &particle, float time)
00047 {
00048 }
00049
00050 void ParticleRendererPoints::renderParticle(Particle &particle)
00051 {
00052 GLState state(GLState::TEXTURE_OFF);
00053 glPointSize(4.0f);
00054 glColor4f(
00055 particle.color_[0],
00056 particle.color_[1],
00057 particle.color_[2],
00058 particle.alpha_);
00059 glBegin(GL_POINTS);
00060 glVertex3fv(particle.position_);
00061 glEnd();
00062 glPointSize(1.0f);
00063 }
00064
00065 ParticleRendererQuads *ParticleRendererQuads::getInstance()
00066 {
00067 static ParticleRendererQuads instance_;
00068 return &instance_;
00069 }
00070
00071 void ParticleRendererQuads::simulateParticle(Particle &particle, float time)
00072 {
00073 }
00074
00075 void ParticleRendererQuads::renderParticle(Particle &particle)
00076 {
00077 if (!particle.texture_ && !particle.textureSet_) return;
00078
00079 if (particle.textureSet_)
00080 {
00081 int tex = int((particle.textureSet_->getNoTextures() - 1) * particle.percent_);
00082 tex = MIN(MAX(tex, 0), particle.textureSet_->getNoTextures() - 1);
00083 GLTexture *texture = particle.textureSet_->getTexture(tex);
00084 texture->draw();
00085 }
00086 else
00087 {
00088 particle.texture_->draw();
00089 }
00090
00091 GLCameraFrustum::instance()->drawBilboard(
00092 particle.position_, particle.color_, particle.alpha_,
00093 particle.size_[0], particle.size_[1], particle.additiveTexture_,
00094 particle.textureCoord_);
00095
00096
00097 float posX = particle.position_[0];
00098 float posY = particle.position_[1];
00099 float posZ = particle.position_[2];
00100 if (particle.shadow_)
00101 {
00102 float aboveGround =
00103 posZ - ScorchedClient::instance()->getLandscapeMaps().
00104 getGroundMaps().getHeight(
00105 int(posX), int(posY)).asFloat();
00106 float smokeAlpha = particle.alpha_ + .2f;
00107 if (smokeAlpha > 1.0f) smokeAlpha = 1.0f;
00108 Landscape::instance()->getShadowMap().
00109 addCircle(posX, posY,
00110 (particle.size_[0] * aboveGround) / 10.0f, smokeAlpha);
00111 }
00112
00113 GLInfo::addNoTriangles(2);
00114 }
00115
00116 ParticleRendererDebris *ParticleRendererDebris::getInstance()
00117 {
00118 static ParticleRendererDebris instance_;
00119 return &instance_;
00120 }
00121
00122 void ParticleRendererDebris::renderParticle(Particle &particle)
00123 {
00124 DebrisActionRenderer *renderer = (DebrisActionRenderer *)
00125 particle.userData_;
00126 renderer->draw(particle.position_);
00127 }
00128
00129 void ParticleRendererDebris::simulateParticle(Particle &particle, float time)
00130 {
00131 DebrisActionRenderer *renderer = (DebrisActionRenderer *)
00132 particle.userData_;
00133 renderer->simulate(time);
00134 }
00135
00136 ParticleRendererSmoke *ParticleRendererSmoke::getInstance()
00137 {
00138 static ParticleRendererSmoke instance_;
00139 return &instance_;
00140 }
00141
00142 void ParticleRendererSmoke::renderParticle(Particle &particle)
00143 {
00144 }
00145
00146 void ParticleRendererSmoke::simulateParticle(Particle &particle, float time)
00147 {
00148 SmokeActionRenderer *renderer = (SmokeActionRenderer *)
00149 particle.userData_;
00150 }
00151
00152 ParticleRendererNapalm *ParticleRendererNapalm::getInstance()
00153 {
00154 static ParticleRendererNapalm instance_;
00155 return &instance_;
00156 }
00157
00158 void ParticleRendererNapalm::renderParticle(Particle &particle)
00159 {
00160 NapalmRenderer *renderer = (NapalmRenderer *)
00161 particle.userData_;
00162 renderer->draw(&particle);
00163 ParticleRendererQuads::getInstance()->renderParticle(particle);
00164 }
00165
00166 void ParticleRendererNapalm::simulateParticle(Particle &particle, float time)
00167 {
00168 NapalmRenderer *renderer = (NapalmRenderer *)
00169 particle.userData_;
00170 renderer->simulate(&particle, time);
00171 }
00172
00173 ParticleRendererMushroom *ParticleRendererMushroom::getInstance()
00174 {
00175 static ParticleRendererMushroom instance_;
00176 return &instance_;
00177 }
00178
00179 void ParticleRendererMushroom::renderParticle(Particle &particle)
00180 {
00181 ExplosionNukeRendererEntry *renderer = (ExplosionNukeRendererEntry *)
00182 particle.userData_;
00183
00184 Vector oldPosition = particle.position_;
00185 bool shadow = particle.shadow_;
00186
00187 particle.shadow_ = false;
00188 particle.position_[0] = oldPosition[0];
00189 particle.position_[1] = oldPosition[1] +
00190 getFastSin(renderer->getCloudRotation() + 2.0f) * 2.0f;
00191 particle.position_[2] = oldPosition[2] +
00192 getFastCos(renderer->getCloudRotation() + 2.0f) * 2.0f;
00193 ParticleRendererQuads::getInstance()->renderParticle(particle);
00194
00195 particle.shadow_ = false;
00196 particle.position_[0] = oldPosition[0];
00197 particle.position_[1] = oldPosition[1] +
00198 getFastSin(renderer->getCloudRotation() + 4.0f) * 2.0f;
00199 particle.position_[2] = oldPosition[2] +
00200 getFastCos(renderer->getCloudRotation() + 4.0f) * 2.0f;
00201 ParticleRendererQuads::getInstance()->renderParticle(particle);
00202
00203 particle.shadow_ = shadow;
00204 particle.position_[0] = oldPosition[0];
00205 particle.position_[1] = oldPosition[1] +
00206 getFastSin(renderer->getCloudRotation()) * 2.0f;
00207 particle.position_[2] = oldPosition[2] +
00208 getFastCos(renderer->getCloudRotation()) * 2.0f;
00209 ParticleRendererQuads::getInstance()->renderParticle(particle);
00210
00211 particle.position_ = oldPosition;
00212 particle.shadow_ = shadow;
00213 }
00214
00215 void ParticleRendererMushroom::simulateParticle(Particle &particle, float time)
00216 {
00217 ExplosionNukeRendererEntry *renderer = (ExplosionNukeRendererEntry *)
00218 particle.userData_;
00219 renderer->simulate(&particle, time);
00220 }
00221
00222 ParticleRendererRain *ParticleRendererRain::getInstance()
00223 {
00224 static ParticleRendererRain instance_;
00225 return &instance_;
00226 }
00227
00228 void ParticleRendererRain::renderParticle(Particle &particle)
00229 {
00230 ParticleRendererQuads::getInstance()->renderParticle(particle);
00231 }
00232
00233 void ParticleRendererRain::simulateParticle(Particle &particle, float time)
00234 {
00235 if (particle.position_[2] < 0.0f)
00236 {
00237 particle.life_ = 0.0f;
00238 return;
00239 }
00240
00241 Vector &cameraPos = particle.engine_->getCamera()->getCurrentPos();
00242 Vector &cameraTarget = particle.engine_->getCamera()->getLookAt();
00243 Vector cameraDirection = (cameraTarget - cameraPos).Normalize();
00244
00245
00246 particle.size_[0] = 0.1f;
00247 particle.size_[1] = 1.0f - fabsf(cameraDirection[2]) + 0.1f;
00248
00249
00250 const float MaxDist = 200.0f * 200.0f;
00251 float alpha = 0.0f;
00252 if (particle.distance_ < MaxDist)
00253 {
00254 alpha = 0.7f * (1.0f - (particle.distance_ / MaxDist));
00255 }
00256 particle.alpha_ = alpha;
00257
00258
00259 float distanceX = cameraPos[0] - particle.position_[0];
00260 float distanceY = cameraPos[1] - particle.position_[1];
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 }
00279
00280 ParticleRendererSnow *ParticleRendererSnow::getInstance()
00281 {
00282 static ParticleRendererSnow instance_;
00283 return &instance_;
00284 }
00285
00286 void ParticleRendererSnow::renderParticle(Particle &particle)
00287 {
00288 ParticleRendererQuads::getInstance()->renderParticle(particle);
00289 }
00290
00291 void ParticleRendererSnow::simulateParticle(Particle &particle, float time)
00292 {
00293 if (particle.position_[2] < 0.0f)
00294 {
00295 particle.life_ = 0.0f;
00296 return;
00297 }
00298
00299
00300 const float MaxDist = 200.0f * 200.0f;
00301 float alpha = 0.0f;
00302 if (particle.distance_ < MaxDist)
00303 {
00304 alpha = 0.7f * (1.0f - (particle.distance_ / MaxDist));
00305 }
00306 particle.alpha_ = alpha;
00307 }
00308
00309 ParticleRendererWall *ParticleRendererWall::getInstance()
00310 {
00311 static ParticleRendererWall instance_;
00312 return &instance_;
00313 }
00314
00315 void ParticleRendererWall::renderParticle(Particle &particle)
00316 {
00317 WallActionRenderer *renderer = (WallActionRenderer *)
00318 particle.userData_;
00319 renderer->draw();
00320 }
00321
00322 void ParticleRendererWall::simulateParticle(Particle &particle, float time)
00323 {
00324 WallActionRenderer *renderer = (WallActionRenderer *)
00325 particle.userData_;
00326 renderer->simulate(time);
00327 }