Commits

rude  committed 77889bd

Apply slime73's ParticleSystem patch.

  • Participants
  • Parent commits a4d5166

Comments (0)

Files changed (2)

File src/modules/graphics/opengl/ParticleSystem.cpp

 	: pStart(0)
 	, pLast(0)
 	, pEnd(0)
+	, particleVerts(0)
 	, active(true)
 	, emissionRate(0)
 	, emitCounter(0)
 
 	if (pStart != 0)
 		delete [] pStart;
+	
+	if (particleVerts != 0)
+		delete [] particleVerts;
 }
 
 void ParticleSystem::add()
 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)
 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();

File src/modules/graphics/opengl/ParticleSystem.h

 
 	// 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;