Browse Source

Added ParticleSystem:setQuads(q1, q2, ...), quads are chosen based on current particle lifetime in a similar style to ParticleSystem:setColors

--HG--
branch : particlesystem-quads
Alex Szpakowski 12 years ago
parent
commit
d30809ebff

+ 63 - 6
src/modules/graphics/opengl/ParticleSystem.cpp

@@ -204,7 +204,7 @@ void ParticleSystem::setBufferSize(unsigned int size)
 	if (pStart != 0)
 		delete [] pStart;
 
-	pLast = pStart = new particle[size];
+	pLast = pStart = new particle[size]();
 
 	pEnd = pStart + size;
 
@@ -370,6 +370,40 @@ void ParticleSystem::setColor(const std::vector<Color> &newColors)
 		colors[i] = colorToFloat(newColors[i]);
 }
 
+void ParticleSystem::setQuad(love::graphics::Quad *quad)
+{
+
+	for (size_t i = 0; i < quads.size(); i++)
+		quads[i]->release();
+
+	quads.resize(1);
+
+	quads[0] = quad;
+	quad->retain();
+}
+
+void ParticleSystem::setQuad(const std::vector<love::graphics::Quad *> &newQuads)
+{
+	for (size_t i = 0; i < quads.size(); i++)
+		quads[i]->release();
+
+	quads.resize(newQuads.size());
+
+	for (size_t i = 0; i < newQuads.size(); i++)
+	{
+		quads[i] = newQuads[i];
+		quads[i]->retain();
+	}
+}
+
+void ParticleSystem::setQuad()
+{
+	for (size_t i = 0; i < quads.size(); i++)
+		quads[i]->release();
+
+	quads.resize(0);
+}
+
 void ParticleSystem::setOffset(float x, float y)
 {
 	offsetX = x;
@@ -479,24 +513,36 @@ void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, flo
 	t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
 	glMultMatrixf((const GLfloat *)t.getElements());
 
-	const vertex * imageVerts = sprite->getVertices();
+	const vertex *imageVerts = sprite->getVertices();
+	const vertex *tVerts;
+	size_t numQuads = quads.size();
+	size_t quadIndex = 0;
 
 	// set the vertex data for each particle (transformation, texcoords, color)
 	for (int i = 0; i < numParticles; i++)
 	{
-		particle * p = pStart + i;
+		particle *p = pStart + i;
+
+		if (numQuads > 0)
+		{
+			// Make sure the quad index is valid
+			quadIndex = (p->quadIndex >= numQuads) ? numQuads - 1 : p->quadIndex;
+			tVerts = quads[quadIndex]->getVertices();
+		}
+		else
+			tVerts = imageVerts;
 
 		// 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);
+		t.transform(&particleVerts[i*4], &tVerts[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;
+			particleVerts[vi].s = tVerts[v].s;
+			particleVerts[vi].t = tVerts[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;
@@ -616,6 +662,17 @@ void ParticleSystem::update(float dt)
 			s -= (float)i;                            // 0 <= s <= 1
 			p->color = colors[i] * (1.0f - s) + colors[k] * s;
 
+			// Update quad index
+			if (quads.size() > 0)
+			{
+				k = quads.size() - 1;
+				s = t * (float) k;
+				i = (s > 0) ? (size_t) s : 0;
+				p->quadIndex = (i <= k) ? i : k;
+			}
+			else
+				p->quadIndex = 0;
+
 			// Next particle.
 			p++;
 		}

+ 20 - 0
src/modules/graphics/opengl/ParticleSystem.h

@@ -27,6 +27,7 @@
 #include "common/Vector.h"
 #include "graphics/Drawable.h"
 #include "graphics/Color.h"
+#include "graphics/Quad.h"
 #include "Image.h"
 #include <vector>
 
@@ -63,6 +64,8 @@ struct particle
 	float spinEnd;
 
 	Colorf color;
+
+	size_t quadIndex;
 };
 
 /**
@@ -293,6 +296,21 @@ public:
 	 **/
 	void setColor(const std::vector<Color> &newColors);
 
+	/**
+	 *
+	 **/
+	void setQuad(love::graphics::Quad *quad);
+
+	/**
+	 *
+	 **/
+	void setQuad(const std::vector<love::graphics::Quad *> &newQuads);
+
+	/**
+	 *
+	 **/
+	void setQuad();
+
 	/**
 	 * Returns the x-coordinate of the emitter's position.
 	 **/
@@ -480,6 +498,8 @@ protected:
 	// Color.
 	std::vector<Colorf> colors;
 
+	std::vector<love::graphics::Quad *> quads;
+
 	void add();
 	void remove(particle *p);
 

+ 28 - 0
src/modules/graphics/opengl/wrap_ParticleSystem.cpp

@@ -19,6 +19,7 @@
  **/
 
 #include "wrap_ParticleSystem.h"
+#include "wrap_Quad.h"
 
 #include "common/Vector.h"
 
@@ -262,6 +263,32 @@ int w_ParticleSystem_setColors(lua_State *L)
 	return 0;
 }
 
+int w_ParticleSystem_setQuads(lua_State *L)
+{
+	ParticleSystem *t = luax_checkparticlesystem(L, 1);
+	int nQuads = lua_gettop(L) - 1;
+
+	if (nQuads == 0)
+		t->setQuad();
+	else if (nQuads == 1)
+	{
+		love::graphics::Quad *q = luax_checkframe(L, 2);
+		t->setQuad(q);
+	}
+	else
+	{
+		std::vector<love::graphics::Quad *> quads(nQuads);
+		for (size_t i = 0; i < nQuads; i++)
+		{
+			love::graphics::Quad *q = luax_checkframe(L, i + 2);
+			quads[i] = q;
+		}
+		t->setQuad(quads);
+	}
+
+	return 0;
+}
+
 int w_ParticleSystem_setOffset(lua_State *L)
 {
 	ParticleSystem *t = luax_checkparticlesystem(L, 1);
@@ -423,6 +450,7 @@ static const luaL_Reg functions[] =
 	{ "setSpin", w_ParticleSystem_setSpin },
 	{ "setSpinVariation", w_ParticleSystem_setSpinVariation },
 	{ "setColors", w_ParticleSystem_setColors },
+	{ "setQuads", w_ParticleSystem_setQuads },
 	{ "setOffset", w_ParticleSystem_setOffset },
 	{ "getX", w_ParticleSystem_getX },
 	{ "getY", w_ParticleSystem_getY },

+ 1 - 0
src/modules/graphics/opengl/wrap_ParticleSystem.h

@@ -53,6 +53,7 @@ int w_ParticleSystem_setRotation(lua_State *L);
 int w_ParticleSystem_setSpin(lua_State *L);
 int w_ParticleSystem_setSpinVariation(lua_State *L);
 int w_ParticleSystem_setColors(lua_State *L);
+int w_ParticleSystem_setQuads(lua_State *L);
 int w_ParticleSystem_setOffset(lua_State *L);
 int w_ParticleSystem_getX(lua_State *L);
 int w_ParticleSystem_getY(lua_State *L);