1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
4 // This file is part of Scorched3D.
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>
40 ParticleRendererPoints
*ParticleRendererPoints::getInstance()
42 static ParticleRendererPoints instance_
;
46 void ParticleRendererPoints::simulateParticle(Particle
&particle
, float time
)
50 void ParticleRendererPoints::renderParticle(Particle
&particle
)
52 GLState
state(GLState::TEXTURE_OFF
);
60 glVertex3fv(particle
.position_
);
65 ParticleRendererQuads
*ParticleRendererQuads::getInstance()
67 static ParticleRendererQuads 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
);
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_
)
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_
;
122 void ParticleRendererDebris::renderParticle(Particle
&particle
)
124 DebrisActionRenderer
*renderer
= (DebrisActionRenderer
*)
126 renderer
->draw(particle
.position_
);
129 void ParticleRendererDebris::simulateParticle(Particle
&particle
, float time
)
131 DebrisActionRenderer
*renderer
= (DebrisActionRenderer
*)
133 renderer
->simulate(time
);
136 ParticleRendererSmoke
*ParticleRendererSmoke::getInstance()
138 static ParticleRendererSmoke instance_
;
142 void ParticleRendererSmoke::renderParticle(Particle
&particle
)
146 void ParticleRendererSmoke::simulateParticle(Particle
&particle
, float time
)
148 SmokeActionRenderer
*renderer
= (SmokeActionRenderer
*)
152 ParticleRendererNapalm
*ParticleRendererNapalm::getInstance()
154 static ParticleRendererNapalm instance_
;
158 void ParticleRendererNapalm::renderParticle(Particle
&particle
)
160 NapalmRenderer
*renderer
= (NapalmRenderer
*)
162 renderer
->draw(&particle
);
163 ParticleRendererQuads::getInstance()->renderParticle(particle
);
166 void ParticleRendererNapalm::simulateParticle(Particle
&particle
, float time
)
168 NapalmRenderer
*renderer
= (NapalmRenderer
*)
170 renderer
->simulate(&particle
, time
);
173 ParticleRendererMushroom
*ParticleRendererMushroom::getInstance()
175 static ParticleRendererMushroom instance_
;
179 void ParticleRendererMushroom::renderParticle(Particle
&particle
)
181 ExplosionNukeRendererEntry
*renderer
= (ExplosionNukeRendererEntry
*)
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
*)
219 renderer
->simulate(&particle
, time
);
222 ParticleRendererRain
*ParticleRendererRain::getInstance()
224 static ParticleRendererRain 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
;
241 Vector
&cameraPos
= particle
.engine_
->getCamera()->getCurrentPos();
242 Vector
&cameraTarget
= particle
.engine_
->getCamera()->getLookAt();
243 Vector cameraDirection
= (cameraTarget
- cameraPos
).Normalize();
246 particle
.size_
[0] = 0.1f
;
247 particle
.size_
[1] = 1.0f
- fabsf(cameraDirection
[2]) + 0.1f
;
250 const float MaxDist
= 200.0f
* 200.0f
;
252 if (particle
.distance_
< MaxDist
)
254 alpha
= 0.7f
* (1.0f
- (particle
.distance_
/ MaxDist
));
256 particle
.alpha_
= alpha
;
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_
;
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
;
300 const float MaxDist
= 200.0f
* 200.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_
;
315 void ParticleRendererWall::renderParticle(Particle
&particle
)
317 WallActionRenderer
*renderer
= (WallActionRenderer
*)
322 void ParticleRendererWall::simulateParticle(Particle
&particle
, float time
)
324 WallActionRenderer
*renderer
= (WallActionRenderer
*)
326 renderer
->simulate(time
);