ParticleRenderer.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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         // Add a shadow of the smoke on the ground
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         // Size
00246         particle.size_[0] = 0.1f;
00247         particle.size_[1] = 1.0f - fabsf(cameraDirection[2]) + 0.1f;
00248 
00249         // Alpha
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         // Distance
00259         float distanceX = cameraPos[0] - particle.position_[0];
00260         float distanceY = cameraPos[1] - particle.position_[1];
00261         /*if (distanceX > 100.0f)
00262         {
00263                 particle.position_[0] = -100.0f + distanceX - 100.0f;
00264         }
00265         else if (distanceX < -100.0f)
00266         {
00267                 particle.position_[0] = 100.0f + distanceX + 100.0f;
00268         } 
00269 
00270         if (distanceY > 100.0f)
00271         {
00272                 particle.position_[1] = -100.0f + distanceY - 100.0f;
00273         }
00274         else if (distanceY < -100.0f)
00275         {
00276                 particle.position_[1] = 100.0f + distanceY + 100.0f;
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         // Alpha
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 }

Generated on Mon Feb 16 15:14:46 2009 for Scorched3D by  doxygen 1.5.3