git-svn-id: https://scorched3d.svn.sourceforge.net/svnroot/scorched3d/trunk/scorched...
[scorched3d/parasti.git] / src / client / graph / ParticleRenderer.cpp
blob0b9cd028c40ede4f89aa18f7b474982636558bae
1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Scorched3D; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ////////////////////////////////////////////////////////////////////////////////
21 #include <graph/ParticleRenderer.h>
22 #include <graph/Particle.h>
23 #include <sprites/ExplosionTextures.h>
24 #include <sprites/DebrisActionRenderer.h>
25 #include <sprites/SmokeActionRenderer.h>
26 #include <sprites/NapalmRenderer.h>
27 #include <sprites/ExplosionNukeRenderer.h>
28 #include <sprites/WallActionRenderer.h>
29 #include <landscape/Landscape.h>
30 #include <landscapemap/LandscapeMaps.h>
31 #include <landscape/ShadowMap.h>
32 #include <client/ScorchedClient.h>
33 #include <GLEXT/GLState.h>
34 #include <GLEXT/GLCamera.h>
35 #include <GLEXT/GLCameraFrustum.h>
36 #include <GLEXT/GLInfo.h>
37 #include <common/Defines.h>
38 #include <math.h>
40 ParticleRendererPoints *ParticleRendererPoints::getInstance()
42 static ParticleRendererPoints instance_;
43 return &instance_;
46 void ParticleRendererPoints::simulateParticle(Particle &particle, float time)
50 void ParticleRendererPoints::renderParticle(Particle &particle)
52 GLState state(GLState::TEXTURE_OFF);
53 glPointSize(4.0f);
54 glColor4f(
55 particle.color_[0],
56 particle.color_[1],
57 particle.color_[2],
58 particle.alpha_);
59 glBegin(GL_POINTS);
60 glVertex3fv(particle.position_);
61 glEnd();
62 glPointSize(1.0f);
65 ParticleRendererQuads *ParticleRendererQuads::getInstance()
67 static ParticleRendererQuads instance_;
68 return &instance_;
71 void ParticleRendererQuads::simulateParticle(Particle &particle, float time)
75 void ParticleRendererQuads::renderParticle(Particle &particle)
77 if (!particle.texture_ && !particle.textureSet_) return;
79 if (particle.textureSet_)
81 int tex = int((particle.textureSet_->getNoTextures() - 1) * particle.percent_);
82 tex = MIN(MAX(tex, 0), particle.textureSet_->getNoTextures() - 1);
83 GLTexture *texture = particle.textureSet_->getTexture(tex);
84 texture->draw();
86 else
88 particle.texture_->draw();
91 GLCameraFrustum::instance()->drawBilboard(
92 particle.position_, particle.color_, particle.alpha_,
93 particle.size_[0], particle.size_[1], particle.additiveTexture_,
94 particle.textureCoord_);
96 // Add a shadow of the smoke on the ground
97 float posX = particle.position_[0];
98 float posY = particle.position_[1];
99 float posZ = particle.position_[2];
100 if (particle.shadow_)
102 float aboveGround =
103 posZ - ScorchedClient::instance()->getLandscapeMaps().
104 getGroundMaps().getHeight(
105 int(posX), int(posY)).asFloat();
106 float smokeAlpha = particle.alpha_ + .2f;
107 if (smokeAlpha > 1.0f) smokeAlpha = 1.0f;
108 Landscape::instance()->getShadowMap().
109 addCircle(posX, posY,
110 (particle.size_[0] * aboveGround) / 10.0f, smokeAlpha);
113 GLInfo::addNoTriangles(2);
116 ParticleRendererDebris *ParticleRendererDebris::getInstance()
118 static ParticleRendererDebris instance_;
119 return &instance_;
122 void ParticleRendererDebris::renderParticle(Particle &particle)
124 DebrisActionRenderer *renderer = (DebrisActionRenderer *)
125 particle.userData_;
126 renderer->draw(particle.position_);
129 void ParticleRendererDebris::simulateParticle(Particle &particle, float time)
131 DebrisActionRenderer *renderer = (DebrisActionRenderer *)
132 particle.userData_;
133 renderer->simulate(time);
136 ParticleRendererSmoke *ParticleRendererSmoke::getInstance()
138 static ParticleRendererSmoke instance_;
139 return &instance_;
142 void ParticleRendererSmoke::renderParticle(Particle &particle)
146 void ParticleRendererSmoke::simulateParticle(Particle &particle, float time)
148 SmokeActionRenderer *renderer = (SmokeActionRenderer *)
149 particle.userData_;
152 ParticleRendererNapalm *ParticleRendererNapalm::getInstance()
154 static ParticleRendererNapalm instance_;
155 return &instance_;
158 void ParticleRendererNapalm::renderParticle(Particle &particle)
160 NapalmRenderer *renderer = (NapalmRenderer *)
161 particle.userData_;
162 renderer->draw(&particle);
163 ParticleRendererQuads::getInstance()->renderParticle(particle);
166 void ParticleRendererNapalm::simulateParticle(Particle &particle, float time)
168 NapalmRenderer *renderer = (NapalmRenderer *)
169 particle.userData_;
170 renderer->simulate(&particle, time);
173 ParticleRendererMushroom *ParticleRendererMushroom::getInstance()
175 static ParticleRendererMushroom instance_;
176 return &instance_;
179 void ParticleRendererMushroom::renderParticle(Particle &particle)
181 ExplosionNukeRendererEntry *renderer = (ExplosionNukeRendererEntry *)
182 particle.userData_;
184 Vector oldPosition = particle.position_;
185 bool shadow = particle.shadow_;
187 particle.shadow_ = false;
188 particle.position_[0] = oldPosition[0];
189 particle.position_[1] = oldPosition[1] +
190 getFastSin(renderer->getCloudRotation() + 2.0f) * 2.0f;
191 particle.position_[2] = oldPosition[2] +
192 getFastCos(renderer->getCloudRotation() + 2.0f) * 2.0f;
193 ParticleRendererQuads::getInstance()->renderParticle(particle);
195 particle.shadow_ = false;
196 particle.position_[0] = oldPosition[0];
197 particle.position_[1] = oldPosition[1] +
198 getFastSin(renderer->getCloudRotation() + 4.0f) * 2.0f;
199 particle.position_[2] = oldPosition[2] +
200 getFastCos(renderer->getCloudRotation() + 4.0f) * 2.0f;
201 ParticleRendererQuads::getInstance()->renderParticle(particle);
203 particle.shadow_ = shadow;
204 particle.position_[0] = oldPosition[0];
205 particle.position_[1] = oldPosition[1] +
206 getFastSin(renderer->getCloudRotation()) * 2.0f;
207 particle.position_[2] = oldPosition[2] +
208 getFastCos(renderer->getCloudRotation()) * 2.0f;
209 ParticleRendererQuads::getInstance()->renderParticle(particle);
211 particle.position_ = oldPosition;
212 particle.shadow_ = shadow;
215 void ParticleRendererMushroom::simulateParticle(Particle &particle, float time)
217 ExplosionNukeRendererEntry *renderer = (ExplosionNukeRendererEntry *)
218 particle.userData_;
219 renderer->simulate(&particle, time);
222 ParticleRendererRain *ParticleRendererRain::getInstance()
224 static ParticleRendererRain instance_;
225 return &instance_;
228 void ParticleRendererRain::renderParticle(Particle &particle)
230 ParticleRendererQuads::getInstance()->renderParticle(particle);
233 void ParticleRendererRain::simulateParticle(Particle &particle, float time)
235 if (particle.position_[2] < 0.0f)
237 particle.life_ = 0.0f;
238 return;
241 Vector &cameraPos = particle.engine_->getCamera()->getCurrentPos();
242 Vector &cameraTarget = particle.engine_->getCamera()->getLookAt();
243 Vector cameraDirection = (cameraTarget - cameraPos).Normalize();
245 // Size
246 particle.size_[0] = 0.1f;
247 particle.size_[1] = 1.0f - fabsf(cameraDirection[2]) + 0.1f;
249 // Alpha
250 const float MaxDist = 200.0f * 200.0f;
251 float alpha = 0.0f;
252 if (particle.distance_ < MaxDist)
254 alpha = 0.7f * (1.0f - (particle.distance_ / MaxDist));
256 particle.alpha_ = alpha;
258 // Distance
259 float distanceX = cameraPos[0] - particle.position_[0];
260 float distanceY = cameraPos[1] - particle.position_[1];
261 /*if (distanceX > 100.0f)
263 particle.position_[0] = -100.0f + distanceX - 100.0f;
265 else if (distanceX < -100.0f)
267 particle.position_[0] = 100.0f + distanceX + 100.0f;
270 if (distanceY > 100.0f)
272 particle.position_[1] = -100.0f + distanceY - 100.0f;
274 else if (distanceY < -100.0f)
276 particle.position_[1] = 100.0f + distanceY + 100.0f;
280 ParticleRendererSnow *ParticleRendererSnow::getInstance()
282 static ParticleRendererSnow instance_;
283 return &instance_;
286 void ParticleRendererSnow::renderParticle(Particle &particle)
288 ParticleRendererQuads::getInstance()->renderParticle(particle);
291 void ParticleRendererSnow::simulateParticle(Particle &particle, float time)
293 if (particle.position_[2] < 0.0f)
295 particle.life_ = 0.0f;
296 return;
299 // Alpha
300 const float MaxDist = 200.0f * 200.0f;
301 float alpha = 0.0f;
302 if (particle.distance_ < MaxDist)
304 alpha = 0.7f * (1.0f - (particle.distance_ / MaxDist));
306 particle.alpha_ = alpha;
309 ParticleRendererWall *ParticleRendererWall::getInstance()
311 static ParticleRendererWall instance_;
312 return &instance_;
315 void ParticleRendererWall::renderParticle(Particle &particle)
317 WallActionRenderer *renderer = (WallActionRenderer *)
318 particle.userData_;
319 renderer->draw();
322 void ParticleRendererWall::simulateParticle(Particle &particle, float time)
324 WallActionRenderer *renderer = (WallActionRenderer *)
325 particle.userData_;
326 renderer->simulate(time);