From 54498ce37886c3d23ebe5103b777d346d41f68ad Mon Sep 17 00:00:00 2001 From: rude Date: Sun, 18 Nov 2012 11:02:30 +0100 Subject: [PATCH] Apply slime73's ParticleSystem patch. --- .../graphics/opengl/ParticleSystem.cpp | 68 +++++++++++++++---- src/modules/graphics/opengl/ParticleSystem.h | 3 + 2 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/modules/graphics/opengl/ParticleSystem.cpp b/src/modules/graphics/opengl/ParticleSystem.cpp index 47e4b6552..167958dd7 100644 --- a/src/modules/graphics/opengl/ParticleSystem.cpp +++ b/src/modules/graphics/opengl/ParticleSystem.cpp @@ -62,6 +62,7 @@ ParticleSystem::ParticleSystem(Image *sprite, unsigned int buffer) : pStart(0) , pLast(0) , pEnd(0) + , particleVerts(0) , active(true) , emissionRate(0) , emitCounter(0) @@ -104,6 +105,9 @@ ParticleSystem::~ParticleSystem() if (pStart != 0) delete [] pStart; + + if (particleVerts != 0) + delete [] particleVerts; } void ParticleSystem::add() @@ -197,11 +201,18 @@ void ParticleSystem::setSprite(Image *image) void ParticleSystem::setBufferSize(unsigned int size) { // delete previous data - delete [] pStart; + if (pStart != 0) + delete [] pStart; pLast = pStart = new particle[size]; pEnd = pStart + size; + + if (particleVerts != 0) + delete [] particleVerts; + + // each particle has 4 vertices + particleVerts = new vertex[size*4]; } 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 { 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(); glPushAttrib(GL_CURRENT_BIT); - Matrix t; + static Matrix t; t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky); glMultMatrixf((const GLfloat *)t.getElements()); - - particle *p = pStart; - while (p != pLast) + + const vertex * imageVerts = sprite->getVertices(); + + // set the vertex data for each particle (transformation, texcoords, color) + for (int i = 0; i < numParticles; i++) { - glPushMatrix(); - - glColor4f(p->color.r, p->color.g, p->color.b, p->color.a); - sprite->draw(p->position[0], p->position[1], p->rotation, p->size, p->size, offsetX, offsetY, 0.0f, 0.0f); - - glPopMatrix(); - p++; + particle * p = pStart + i; + + // particle vertices are sprite vertices transformed by particle information + 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); + + // 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(); glPopMatrix(); diff --git a/src/modules/graphics/opengl/ParticleSystem.h b/src/modules/graphics/opengl/ParticleSystem.h index 64cb5c519..5c02f75d7 100644 --- a/src/modules/graphics/opengl/ParticleSystem.h +++ b/src/modules/graphics/opengl/ParticleSystem.h @@ -406,6 +406,9 @@ protected: // Pointer to the end of the memory allocation. particle *pEnd; + + // array of transformed vertex data for all particles, for drawing + vertex * particleVerts; // The sprite to be drawn. Image *sprite;