Browse Source

Merged love-experiments/particlesystem-quads into default

Alex Szpakowski 12 years ago
parent
commit
6a83eba5f2

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

@@ -100,6 +100,9 @@ ParticleSystem::ParticleSystem(Image *sprite, unsigned int buffer)
 
 ParticleSystem::~ParticleSystem()
 {
+	for (size_t i = 0; i < quads.size(); i++)
+		quads[i]->release();
+
 	if (this->sprite != 0)
 		this->sprite->release();
 
@@ -204,7 +207,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 +373,28 @@ void ParticleSystem::setColor(const std::vector<Color> &newColors)
 		colors[i] = colorToFloat(newColors[i]);
 }
 
+void ParticleSystem::setQuads(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::setQuads()
+{
+	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 +504,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();
 
 	// 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
+			size_t 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 +653,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
+			k = quads.size();
+			if (k > 0)
+			{
+				s = t * (float) k; // [0:numquads-1]
+				i = (s > 0) ? (size_t) s : 0;
+				p->quadIndex = (i < k) ? i : k - 1;
+			}
+			else
+				p->quadIndex = 0;
+
 			// Next particle.
 			p++;
 		}

+ 16 - 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,17 @@ public:
 	 **/
 	void setColor(const std::vector<Color> &newColors);
 
+	/**
+	 * Sets the quads used when drawing the particles.
+	 * @param newQuads Array of quads.
+	 **/
+	void setQuads(const std::vector<love::graphics::Quad *> &newQuads);
+
+	/**
+	 * Removes all quads from the particle system.
+	 **/
+	void setQuads();
+
 	/**
 	 * Returns the x-coordinate of the emitter's position.
 	 **/
@@ -480,6 +494,8 @@ protected:
 	// Color.
 	std::vector<Colorf> colors;
 
+	std::vector<love::graphics::Quad *> quads;
+
 	void add();
 	void remove(particle *p);
 

+ 40 - 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,44 @@ 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 (lua_istable(L, 2))
+		nQuads = lua_objlen(L, 2);
+
+	// Remove all quads if no argument is given.
+	if (nQuads == 0)
+	{
+		t->setQuads();
+		return 0;
+	}
+
+	std::vector<love::graphics::Quad *> quads(nQuads);
+
+	if (lua_istable(L, 2))
+	{
+		for (int i = 0; i < nQuads; i++)
+		{
+			lua_pushnumber(L, i + 1); // array index
+			lua_gettable(L, 2);
+			quads[i] = luax_checkframe(L, -1);
+			lua_pop(L, 1);
+		}
+	}
+	else
+	{
+		for (int i = 0; i < nQuads; i++)
+			quads[i] = luax_checkframe(L, i + 2);
+	}
+
+	t->setQuads(quads);
+
+	return 0;
+}
+
 int w_ParticleSystem_setOffset(lua_State *L)
 {
 	ParticleSystem *t = luax_checkparticlesystem(L, 1);
@@ -423,6 +462,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);