Apply slime73's ParticleSystem patch.

This commit is contained in:
rude
2012-11-18 11:02:30 +01:00
parent 2149ecdf44
commit 54498ce378
2 changed files with 59 additions and 12 deletions
+56 -12
View File
@@ -62,6 +62,7 @@ ParticleSystem::ParticleSystem(Image *sprite, unsigned int buffer)
: pStart(0) : pStart(0)
, pLast(0) , pLast(0)
, pEnd(0) , pEnd(0)
, particleVerts(0)
, active(true) , active(true)
, emissionRate(0) , emissionRate(0)
, emitCounter(0) , emitCounter(0)
@@ -104,6 +105,9 @@ ParticleSystem::~ParticleSystem()
if (pStart != 0) if (pStart != 0)
delete [] pStart; delete [] pStart;
if (particleVerts != 0)
delete [] particleVerts;
} }
void ParticleSystem::add() void ParticleSystem::add()
@@ -197,11 +201,18 @@ void ParticleSystem::setSprite(Image *image)
void ParticleSystem::setBufferSize(unsigned int size) void ParticleSystem::setBufferSize(unsigned int size)
{ {
// delete previous data // delete previous data
delete [] pStart; if (pStart != 0)
delete [] pStart;
pLast = pStart = new particle[size]; pLast = pStart = new particle[size];
pEnd = pStart + size; pEnd = pStart + size;
if (particleVerts != 0)
delete [] particleVerts;
// each particle has 4 vertices
particleVerts = new vertex[size*4];
} }
void ParticleSystem::setEmissionRate(int rate) void ParticleSystem::setEmissionRate(int rate)
@@ -457,25 +468,58 @@ bool ParticleSystem::isFull() const
void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
{ {
if (sprite == 0) return; // just in case of failure if (sprite == 0) return; // just in case of failure
int numParticles = count();
if (numParticles == 0) return; // don't bother if there's nothing to do
glPushMatrix(); glPushMatrix();
glPushAttrib(GL_CURRENT_BIT); glPushAttrib(GL_CURRENT_BIT);
Matrix t; static Matrix t;
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
glMultMatrixf((const GLfloat *)t.getElements()); glMultMatrixf((const GLfloat *)t.getElements());
particle *p = pStart; const vertex * imageVerts = sprite->getVertices();
while (p != pLast)
// set the vertex data for each particle (transformation, texcoords, color)
for (int i = 0; i < numParticles; i++)
{ {
glPushMatrix(); particle * p = pStart + i;
glColor4f(p->color.r, p->color.g, p->color.b, p->color.a); // particle vertices are sprite vertices transformed by particle information
sprite->draw(p->position[0], p->position[1], p->rotation, p->size, p->size, offsetX, offsetY, 0.0f, 0.0f); t.setTransformation(p->position[0], p->position[1], p->rotation, p->size, p->size, offsetX, offsetY, 0.0f, 0.0f);
t.transform(&particleVerts[i*4], &imageVerts[0], 4);
glPopMatrix();
p++; // set the texture coordinate and color data for particle vertices
for (int v = 0; v < 4; v++) {
int vi = (i * 4) + v; // current vertex index for particle
particleVerts[vi].s = imageVerts[v].s;
particleVerts[vi].t = imageVerts[v].t;
// particle colors are stored as floats (0-1) but vertex colors are stored as unsigned bytes (0-255)
particleVerts[vi].r = p->color.r*255;
particleVerts[vi].g = p->color.g*255;
particleVerts[vi].b = p->color.b*255;
particleVerts[vi].a = p->color.a*255;
}
} }
sprite->bind();
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), (GLvoid *)&particleVerts[0].r);
glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&particleVerts[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid *)&particleVerts[0].s);
glDrawArrays(GL_QUADS, 0, numParticles*4);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glPopAttrib(); glPopAttrib();
glPopMatrix(); glPopMatrix();
@@ -406,6 +406,9 @@ protected:
// Pointer to the end of the memory allocation. // Pointer to the end of the memory allocation.
particle *pEnd; particle *pEnd;
// array of transformed vertex data for all particles, for drawing
vertex * particleVerts;
// The sprite to be drawn. // The sprite to be drawn.
Image *sprite; Image *sprite;