[+] Added drawlevel sorting for particles
This commit is contained in:
parent
b9fb1bfd1b
commit
a63a4fff61
8 changed files with 118 additions and 41 deletions
|
@ -77,8 +77,8 @@ public:
|
||||||
class CParticle
|
class CParticle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CParticle(CPosition position) :
|
CParticle(CPosition position, int drawlevel = 0) :
|
||||||
pos(position), destroyed(false)
|
pos(position), destroyed(false), drawLevel(drawlevel)
|
||||||
{}
|
{}
|
||||||
virtual ~CParticle() {}
|
virtual ~CParticle() {}
|
||||||
|
|
||||||
|
@ -91,16 +91,20 @@ public:
|
||||||
|
|
||||||
virtual CParticle *clone() = 0;
|
virtual CParticle *clone() = 0;
|
||||||
|
|
||||||
|
int getDrawLevel() const { return drawLevel; }
|
||||||
|
void setDrawLevel(int value) { drawLevel = value; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CPosition pos;
|
CPosition pos;
|
||||||
bool destroyed;
|
bool destroyed;
|
||||||
|
int drawLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class StaticParticle : public CParticle
|
class StaticParticle : public CParticle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StaticParticle(CPosition position, GraphicAnimation *flame);
|
StaticParticle(CPosition position, GraphicAnimation *flame, int drawlevel = 0);
|
||||||
virtual ~StaticParticle();
|
virtual ~StaticParticle();
|
||||||
|
|
||||||
virtual bool isVisible(const CViewport &vp) const;
|
virtual bool isVisible(const CViewport &vp) const;
|
||||||
|
@ -120,13 +124,17 @@ public:
|
||||||
CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation,
|
CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation,
|
||||||
GraphicAnimation *destroyAnimation,
|
GraphicAnimation *destroyAnimation,
|
||||||
int minVelocity = 0, int maxVelocity = 400,
|
int minVelocity = 0, int maxVelocity = 400,
|
||||||
int minTrajectoryAngle = 77, int maxTTL = 0);
|
int minTrajectoryAngle = 77, int maxTTL = 0, int drawlevel = 0);
|
||||||
virtual ~CChunkParticle();
|
virtual ~CChunkParticle();
|
||||||
|
|
||||||
virtual bool isVisible(const CViewport &vp) const;
|
virtual bool isVisible(const CViewport &vp) const;
|
||||||
virtual void draw();
|
virtual void draw();
|
||||||
virtual void update(int ticks);
|
virtual void update(int ticks);
|
||||||
virtual CParticle *clone();
|
virtual CParticle *clone();
|
||||||
|
int getSmokeDrawLevel() const { return smokeDrawLevel; }
|
||||||
|
int getDestroyDrawLevel() const { return destroyDrawLevel; }
|
||||||
|
void setSmokeDrawLevel(int value) { smokeDrawLevel = value; }
|
||||||
|
void setDestroyDrawLevel(int value) { destroyDrawLevel = value; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CPosition initialPos;
|
CPosition initialPos;
|
||||||
|
@ -140,6 +148,8 @@ protected:
|
||||||
int maxVelocity;
|
int maxVelocity;
|
||||||
int minTrajectoryAngle;
|
int minTrajectoryAngle;
|
||||||
float height;
|
float height;
|
||||||
|
int smokeDrawLevel;
|
||||||
|
int destroyDrawLevel;
|
||||||
GraphicAnimation *debrisAnimation;
|
GraphicAnimation *debrisAnimation;
|
||||||
GraphicAnimation *smokeAnimation;
|
GraphicAnimation *smokeAnimation;
|
||||||
GraphicAnimation *destroyAnimation;
|
GraphicAnimation *destroyAnimation;
|
||||||
|
@ -155,7 +165,7 @@ protected:
|
||||||
class CSmokeParticle : public CParticle
|
class CSmokeParticle : public CParticle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0f);
|
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0f, int drawlevel = 0);
|
||||||
virtual ~CSmokeParticle();
|
virtual ~CSmokeParticle();
|
||||||
|
|
||||||
virtual bool isVisible(const CViewport &vp) const;
|
virtual bool isVisible(const CViewport &vp) const;
|
||||||
|
@ -174,7 +184,7 @@ protected:
|
||||||
class CRadialParticle : public CParticle
|
class CRadialParticle : public CParticle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed);
|
CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed, int drawlevel = 0);
|
||||||
virtual ~CRadialParticle();
|
virtual ~CRadialParticle();
|
||||||
|
|
||||||
virtual bool isVisible(const CViewport &vp) const;
|
virtual bool isVisible(const CViewport &vp) const;
|
||||||
|
@ -199,7 +209,9 @@ public:
|
||||||
static void init();
|
static void init();
|
||||||
static void exit();
|
static void exit();
|
||||||
|
|
||||||
void draw(const CViewport &vp);
|
void prepareToDraw(const CViewport &vp, std::vector<CParticle *> &table);
|
||||||
|
void endDraw();
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
void add(CParticle *particle);
|
void add(CParticle *particle);
|
||||||
|
|
|
@ -332,25 +332,68 @@ void CViewport::Draw() const
|
||||||
|
|
||||||
CurrentViewport = this;
|
CurrentViewport = this;
|
||||||
{
|
{
|
||||||
|
// Now we need to sort units, missiles, particles by draw level and draw them
|
||||||
std::vector<CUnit *> unittable;
|
std::vector<CUnit *> unittable;
|
||||||
std::vector<Missile *> missiletable;
|
std::vector<Missile *> missiletable;
|
||||||
|
std::vector<CParticle *> particletable;
|
||||||
|
|
||||||
// We find and sort units after draw level.
|
|
||||||
FindAndSortUnits(*this, unittable);
|
FindAndSortUnits(*this, unittable);
|
||||||
const size_t nunits = unittable.size();
|
const size_t nunits = unittable.size();
|
||||||
FindAndSortMissiles(*this, missiletable);
|
FindAndSortMissiles(*this, missiletable);
|
||||||
const size_t nmissiles = missiletable.size();
|
const size_t nmissiles = missiletable.size();
|
||||||
|
ParticleManager.prepareToDraw(*this, particletable);
|
||||||
|
const size_t nparticles = particletable.size();
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
|
size_t k = 0;
|
||||||
|
|
||||||
while (i < nunits && j < nmissiles) {
|
|
||||||
if (unittable[i]->Type->DrawLevel <= missiletable[j]->Type->DrawLevel) {
|
while ((i < nunits && j < nmissiles) || (i < nunits && k < nparticles)
|
||||||
unittable[i]->Draw(*this);
|
|| (j < nmissiles && k < nparticles)) {
|
||||||
++i;
|
if (i == nunits) {
|
||||||
} else {
|
if (missiletable[j]->Type->DrawLevel < particletable[k]->getDrawLevel()) {
|
||||||
missiletable[j]->DrawMissile(*this);
|
missiletable[j]->DrawMissile(*this);
|
||||||
++j;
|
++j;
|
||||||
}
|
} else {
|
||||||
|
particletable[k]->draw();
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
} else if (j == nmissiles) {
|
||||||
|
if (unittable[i]->Type->DrawLevel < particletable[k]->getDrawLevel()) {
|
||||||
|
unittable[i]->Draw(*this);
|
||||||
|
++i;
|
||||||
|
} else {
|
||||||
|
particletable[k]->draw();
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
} else if (k == nparticles) {
|
||||||
|
if (unittable[i]->Type->DrawLevel < missiletable[j]->Type->DrawLevel) {
|
||||||
|
unittable[i]->Draw(*this);
|
||||||
|
++i;
|
||||||
|
} else {
|
||||||
|
missiletable[j]->DrawMissile(*this);
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (unittable[i]->Type->DrawLevel <= missiletable[j]->Type->DrawLevel) {
|
||||||
|
if (unittable[i]->Type->DrawLevel < particletable[k]->getDrawLevel()) {
|
||||||
|
unittable[i]->Draw(*this);
|
||||||
|
++i;
|
||||||
|
} else {
|
||||||
|
particletable[k]->draw();
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (missiletable[j]->Type->DrawLevel < particletable[k]->getDrawLevel()) {
|
||||||
|
missiletable[j]->DrawMissile(*this);
|
||||||
|
++j;
|
||||||
|
} else {
|
||||||
|
particletable[k]->draw();
|
||||||
|
++k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (; i < nunits; ++i) {
|
for (; i < nunits; ++i) {
|
||||||
unittable[i]->Draw(*this);
|
unittable[i]->Draw(*this);
|
||||||
|
@ -358,10 +401,12 @@ void CViewport::Draw() const
|
||||||
for (; j < nmissiles; ++j) {
|
for (; j < nmissiles; ++j) {
|
||||||
missiletable[j]->DrawMissile(*this);
|
missiletable[j]->DrawMissile(*this);
|
||||||
}
|
}
|
||||||
|
for (; k < nparticles; ++k) {
|
||||||
|
particletable[k]->draw();
|
||||||
|
}
|
||||||
|
ParticleManager.endDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
ParticleManager.draw(*this);
|
|
||||||
|
|
||||||
this->DrawMapFogOfWar();
|
this->DrawMapFogOfWar();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -46,8 +46,8 @@ static inline float deg2rad(int degrees)
|
||||||
|
|
||||||
CChunkParticle::CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation,
|
CChunkParticle::CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation,
|
||||||
GraphicAnimation *destroyAnimation,
|
GraphicAnimation *destroyAnimation,
|
||||||
int minVelocity, int maxVelocity, int minTrajectoryAngle, int maxTTL) :
|
int minVelocity, int maxVelocity, int minTrajectoryAngle, int maxTTL, int drawlevel) :
|
||||||
CParticle(position), initialPos(position), maxTTL(maxTTL), nextSmokeTicks(0),
|
CParticle(position, drawlevel), initialPos(position), maxTTL(maxTTL), nextSmokeTicks(0),
|
||||||
age(0), height(0.f)
|
age(0), height(0.f)
|
||||||
{
|
{
|
||||||
float radians = deg2rad(MyRand() % 360);
|
float radians = deg2rad(MyRand() % 360);
|
||||||
|
@ -112,7 +112,7 @@ void CChunkParticle::update(int ticks)
|
||||||
if (destroyAnimation) {
|
if (destroyAnimation) {
|
||||||
CPosition p(pos.x, calculateScreenPos(pos.y, height));
|
CPosition p(pos.x, calculateScreenPos(pos.y, height));
|
||||||
GraphicAnimation *destroyanimation = destroyAnimation->clone();
|
GraphicAnimation *destroyanimation = destroyAnimation->clone();
|
||||||
StaticParticle *destroy = new StaticParticle(p, destroyanimation);
|
StaticParticle *destroy = new StaticParticle(p, destroyanimation, destroyDrawLevel);
|
||||||
ParticleManager.add(destroy);
|
ParticleManager.add(destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ void CChunkParticle::update(int ticks)
|
||||||
if (age > nextSmokeTicks) {
|
if (age > nextSmokeTicks) {
|
||||||
CPosition p(pos.x, calculateScreenPos(pos.y, height));
|
CPosition p(pos.x, calculateScreenPos(pos.y, height));
|
||||||
GraphicAnimation *smokeanimation = smokeAnimation->clone();
|
GraphicAnimation *smokeanimation = smokeAnimation->clone();
|
||||||
CSmokeParticle *smoke = new CSmokeParticle(p, smokeanimation);
|
CSmokeParticle *smoke = new CSmokeParticle(p, smokeanimation, 0, -22.0f, smokeDrawLevel);
|
||||||
ParticleManager.add(smoke);
|
ParticleManager.add(smoke);
|
||||||
|
|
||||||
nextSmokeTicks += MyRand() % randSmokeTicks + minSmokeTicks;
|
nextSmokeTicks += MyRand() % randSmokeTicks + minSmokeTicks;
|
||||||
|
@ -151,7 +151,10 @@ void CChunkParticle::update(int ticks)
|
||||||
|
|
||||||
CParticle *CChunkParticle::clone()
|
CParticle *CChunkParticle::clone()
|
||||||
{
|
{
|
||||||
return new CChunkParticle(pos, smokeAnimation, debrisAnimation, destroyAnimation, minVelocity, maxVelocity, minTrajectoryAngle, maxTTL);
|
CChunkParticle *particle = new CChunkParticle(pos, smokeAnimation, debrisAnimation, destroyAnimation, minVelocity, maxVelocity, minTrajectoryAngle, maxTTL, drawLevel);
|
||||||
|
particle->smokeDrawLevel = smokeDrawLevel;
|
||||||
|
particle->destroyDrawLevel = destroyDrawLevel;
|
||||||
|
return particle;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
CParticleManager ParticleManager;
|
CParticleManager ParticleManager;
|
||||||
|
|
||||||
|
@ -70,17 +72,27 @@ void CParticleManager::clear()
|
||||||
new_particles.clear();
|
new_particles.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CParticleManager::draw(const CViewport &vp)
|
static inline bool DrawLevelCompare(const CParticle *lhs, const CParticle *rhs)
|
||||||
|
{
|
||||||
|
return lhs->getDrawLevel() < rhs->getDrawLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CParticleManager::prepareToDraw(const CViewport &vp, std::vector<CParticle *> &table)
|
||||||
{
|
{
|
||||||
this->vp = &vp;
|
this->vp = &vp;
|
||||||
|
|
||||||
std::vector<CParticle *>::iterator i;
|
for (std::vector<CParticle *>::iterator it = particles.begin(); it != particles.end(); ++it) {
|
||||||
for (i = particles.begin(); i != particles.end(); ++i) {
|
CParticle &particle = **it;
|
||||||
if ((*i)->isVisible(vp)) {
|
if (particle.isVisible(vp)) {
|
||||||
(*i)->draw();
|
table.push_back(&particle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::sort(table.begin(), table.end(), DrawLevelCompare);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CParticleManager::endDraw()
|
||||||
|
{
|
||||||
this->vp = NULL;
|
this->vp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#include "stratagus.h"
|
#include "stratagus.h"
|
||||||
#include "particle.h"
|
#include "particle.h"
|
||||||
|
|
||||||
CRadialParticle::CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed) :
|
CRadialParticle::CRadialParticle(CPosition position, GraphicAnimation *animation, int maxSpeed, int drawlevel) :
|
||||||
CParticle(position)
|
CParticle(position, drawlevel)
|
||||||
{
|
{
|
||||||
Assert(animation);
|
Assert(animation);
|
||||||
this->animation = animation->clone();
|
this->animation = animation->clone();
|
||||||
|
@ -76,7 +76,7 @@ void CRadialParticle::update(int ticks)
|
||||||
|
|
||||||
CParticle *CRadialParticle::clone()
|
CParticle *CRadialParticle::clone()
|
||||||
{
|
{
|
||||||
CParticle *p = new CRadialParticle(pos, animation, maxSpeed);
|
CParticle *p = new CRadialParticle(pos, animation, maxSpeed, drawLevel);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@
|
||||||
|
|
||||||
|
|
||||||
CSmokeParticle::CSmokeParticle(CPosition position, GraphicAnimation *smoke,
|
CSmokeParticle::CSmokeParticle(CPosition position, GraphicAnimation *smoke,
|
||||||
float speedx, float speedy) :
|
float speedx, float speedy, int drawlevel) :
|
||||||
CParticle(position)
|
CParticle(position, drawlevel)
|
||||||
{
|
{
|
||||||
Assert(smoke);
|
Assert(smoke);
|
||||||
this->puff = smoke->clone();
|
this->puff = smoke->clone();
|
||||||
|
@ -77,7 +77,7 @@ void CSmokeParticle::update(int ticks)
|
||||||
|
|
||||||
CParticle *CSmokeParticle::clone()
|
CParticle *CSmokeParticle::clone()
|
||||||
{
|
{
|
||||||
return new CSmokeParticle(pos, puff, speedVector.x, speedVector.y);
|
return new CSmokeParticle(pos, puff, speedVector.x, speedVector.y, drawLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
#include "particle.h"
|
#include "particle.h"
|
||||||
|
|
||||||
|
|
||||||
StaticParticle::StaticParticle(CPosition position, GraphicAnimation *animation) :
|
StaticParticle::StaticParticle(CPosition position, GraphicAnimation *animation, int drawlevel) :
|
||||||
CParticle(position)
|
CParticle(position, drawlevel)
|
||||||
{
|
{
|
||||||
Assert(animation);
|
Assert(animation);
|
||||||
this->animation = animation->clone();
|
this->animation = animation->clone();
|
||||||
|
@ -66,7 +66,7 @@ void StaticParticle::update(int ticks)
|
||||||
|
|
||||||
CParticle *StaticParticle::clone()
|
CParticle *StaticParticle::clone()
|
||||||
{
|
{
|
||||||
CParticle *p = new StaticParticle(pos, animation);
|
CParticle *p = new StaticParticle(pos, animation, drawLevel);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,30 +16,35 @@ class GraphicAnimation
|
||||||
class CParticle
|
class CParticle
|
||||||
{
|
{
|
||||||
virtual CParticle* clone();
|
virtual CParticle* clone();
|
||||||
|
void setDrawLevel(int value);
|
||||||
};
|
};
|
||||||
|
|
||||||
class StaticParticle : public CParticle
|
class StaticParticle : public CParticle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StaticParticle(CPosition position, GraphicAnimation *animation);
|
StaticParticle(CPosition position, GraphicAnimation *animation, int drawlevel = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CChunkParticle : public CParticle
|
class CChunkParticle : public CParticle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation, GraphicAnimation *destroyAnimation, int minVelocity = 0, int maxVelocity = 400, int minTrajectoryAngle = 77, int maxTTL = 0);
|
CChunkParticle(CPosition position, GraphicAnimation *smokeAnimation, GraphicAnimation *debrisAnimation, GraphicAnimation *destroyAnimation, int minVelocity = 0, int maxVelocity = 400, int minTrajectoryAngle = 77, int maxTTL = 0, int drawlevel = 0);
|
||||||
|
int getSmokeDrawLevel() const;
|
||||||
|
int getDestroyDrawLevel() const;
|
||||||
|
void setSmokeDrawLevel(int value);
|
||||||
|
void setDestroyDrawLevel(int value);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CSmokeParticle : public CParticle
|
class CSmokeParticle : public CParticle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0);
|
CSmokeParticle(CPosition position, GraphicAnimation *animation, float speedx = 0, float speedy = -22.0, int drawlevel = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CRadialParticle : public CParticle
|
class CRadialParticle : public CParticle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CRadialParticle(CPosition position, GraphicAnimation *smokeAnimation, int maxSpeed);
|
CRadialParticle(CPosition position, GraphicAnimation *smokeAnimation, int maxSpeed, int drawlevel = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CParticleManager
|
class CParticleManager
|
||||||
|
|
Loading…
Reference in a new issue