Browse Source

Issue #262: Add per-sprite colors.

rude 14 years ago
parent
commit
387a8ab2dc

+ 39 - 1
src/modules/graphics/opengl/SpriteBatch.cpp

@@ -34,7 +34,7 @@ namespace graphics
 namespace opengl
 namespace opengl
 {
 {
 	SpriteBatch::SpriteBatch(Image * image, int size, int usage)
 	SpriteBatch::SpriteBatch(Image * image, int size, int usage)
-		: image(image), size(size), next(0), usage(usage), lockp(0)
+		: image(image), size(size), next(0), usage(usage), lockp(0), color(0)
 	{
 	{
 		if (!(GLEE_ARB_vertex_buffer_object || GLEE_VERSION_1_5))
 		if (!(GLEE_ARB_vertex_buffer_object || GLEE_VERSION_1_5))
 			throw love::Exception("Your OpenGL version does not support SpriteBatches. Go upgrade!");
 			throw love::Exception("Your OpenGL version does not support SpriteBatches. Go upgrade!");
@@ -67,6 +67,7 @@ namespace opengl
 
 
 		delete [] vertices;
 		delete [] vertices;
 		delete [] indices;
 		delete [] indices;
+		delete color;
 	}
 	}
 
 
 	bool SpriteBatch::loadVolatile()
 	bool SpriteBatch::loadVolatile()
@@ -120,6 +121,9 @@ namespace opengl
 			t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
 			t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
 			t.transform(v, v, 4);
 			t.transform(v, v, 4);
 
 
+			if (color)
+				setColorv(v, *color);
+
 			addv(v);
 			addv(v);
 
 
 			// Increment counter.
 			// Increment counter.
@@ -143,6 +147,9 @@ namespace opengl
 			t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
 			t.setTransformation(x, y, a, sx, sy, ox, oy, kx, ky);
 			t.transform(v, v, 4);
 			t.transform(v, v, 4);
 
 
+			if (color)
+				setColorv(v, *color);
+
 			addv(v);
 			addv(v);
 
 
 			// Increment counter.
 			// Increment counter.
@@ -183,6 +190,20 @@ namespace opengl
 		image->retain();
 		image->retain();
 	}
 	}
 
 
+	void SpriteBatch::setColor(const Color & color)
+	{
+		if(!this->color)
+			this->color = new Color(color);
+		else
+			*(this->color) = color;
+	}
+
+	void SpriteBatch::setColor()
+	{
+		delete color;
+		color = 0;
+	}
+
 	void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
 	void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
 	{
 	{
 		static Matrix t;
 		static Matrix t;
@@ -201,12 +222,21 @@ namespace opengl
 		// Bind the VBO buffer.
 		// Bind the VBO buffer.
 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo[0]);
 		glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo[0]);
 		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbo[1]);
 		glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbo[1]);
+
+		// Apply per-sprite color, if a color is set.
+		if (color)
+		{
+			glEnableClientState(GL_COLOR_ARRAY);
+			glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vertex), 0);
+		}
+
 		glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)(sizeof(unsigned char)*4));
 		glVertexPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)(sizeof(unsigned char)*4));
 		glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)(sizeof(unsigned char)*4+sizeof(float)*2));
 		glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (GLvoid*)(sizeof(unsigned char)*4+sizeof(float)*2));
 		
 		
 		glDrawElements(GL_TRIANGLES, next*6, GL_UNSIGNED_SHORT, 0);
 		glDrawElements(GL_TRIANGLES, next*6, GL_UNSIGNED_SHORT, 0);
 
 
 		// Disable vertex arrays.
 		// Disable vertex arrays.
+		glDisableClientState(GL_COLOR_ARRAY);
 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 		glDisableClientState(GL_VERTEX_ARRAY);
 		glDisableClientState(GL_VERTEX_ARRAY);
 
 
@@ -232,6 +262,14 @@ namespace opengl
 		}
 		}
 	}
 	}
 
 
+	void SpriteBatch::setColorv(vertex * v, const Color & color)
+	{
+		v[0].r = color.r; v[0].g = color.g; v[0].b = color.b; v[0].a = color.a;
+		v[1].r = color.r; v[1].g = color.g; v[1].b = color.b; v[1].a = color.a;
+		v[2].r = color.r; v[2].g = color.g; v[2].b = color.b; v[2].a = color.a;
+		v[3].r = color.r; v[3].g = color.g; v[3].b = color.b; v[3].a = color.a;
+	}
+
 } // opengl
 } // opengl
 } // graphics
 } // graphics
 } // love
 } // love

+ 29 - 0
src/modules/graphics/opengl/SpriteBatch.h

@@ -31,6 +31,7 @@
 #include <common/Matrix.h>
 #include <common/Matrix.h>
 #include <graphics/Drawable.h>
 #include <graphics/Drawable.h>
 #include <graphics/Volatile.h>
 #include <graphics/Volatile.h>
+#include <graphics/Color.h>
 
 
 // OpenGL
 // OpenGL
 #include "GLee.h"
 #include "GLee.h"
@@ -73,6 +74,10 @@ namespace opengl
 		// If the buffer is locked, this pointer is nonzero.
 		// If the buffer is locked, this pointer is nonzero.
 		vertex * lockp;
 		vertex * lockp;
 
 
+		// Current color. This color, if present, will be applied to the next
+		// added quad.
+		Color * color;
+
 	public:
 	public:
 
 
 		enum UsageHint
 		enum UsageHint
@@ -98,6 +103,21 @@ namespace opengl
 
 
 		void setImage(Image * newimage);
 		void setImage(Image * newimage);
 
 
+		/**
+		 * Set the current color for this SpriteBatch. The geometry added
+		 * after this call will use this color. Note that global color
+		 * will not longer apply to the SpriteBatch if this is used.
+		 *
+		 * @param color The color to use for the following geometry.
+		 */
+		void setColor(const Color & color);
+
+		/**
+		 * Disable per-quad colors for this SpriteBatch. The next call to
+		 * draw will use the global color for all sprites.
+		 */
+		void setColor();
+
 		// Implements Drawable.
 		// Implements Drawable.
 		void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
 		void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
 
 
@@ -105,6 +125,15 @@ namespace opengl
 
 
 		void addv(const vertex * v);
 		void addv(const vertex * v);
 
 
+		/**
+		 * Set the color for vertices.
+		 *
+		 * @param v The vertices to set the color for. Must be an array of
+		 *          of size 4.
+		 * @param color The color to assign to each vertex.
+		 */
+		void setColorv(vertex * v, const Color & color);
+
 	}; // SpriteBatch
 	}; // SpriteBatch
 
 
 } // opengl
 } // opengl

+ 20 - 0
src/modules/graphics/opengl/wrap_SpriteBatch.cpp

@@ -93,6 +93,25 @@ namespace opengl
 		return 0;
 		return 0;
 	}
 	}
 
 
+	int w_SpriteBatch_setColor(lua_State * L)
+	{
+		SpriteBatch * t = luax_checkspritebatch(L, 1);
+
+		if (lua_gettop(L) <= 1)
+			t->setColor();
+		else
+		{
+			Color c;
+			c.r = (unsigned char)luaL_checkint(L, 2);
+			c.g = (unsigned char)luaL_checkint(L, 3);
+			c.b = (unsigned char)luaL_checkint(L, 4);
+			c.a = (unsigned char)luaL_optint(L, 5, 255);
+			t->setColor(c);
+		}
+
+		return 0;
+	}
+
 	static const luaL_Reg functions[] = {
 	static const luaL_Reg functions[] = {
 		{ "add", w_SpriteBatch_add },
 		{ "add", w_SpriteBatch_add },
 		{ "addq", w_SpriteBatch_addq },
 		{ "addq", w_SpriteBatch_addq },
@@ -100,6 +119,7 @@ namespace opengl
 		{ "bind", w_SpriteBatch_bind },
 		{ "bind", w_SpriteBatch_bind },
 		{ "unbind", w_SpriteBatch_unbind },
 		{ "unbind", w_SpriteBatch_unbind },
 		{ "setImage", w_SpriteBatch_setImage },
 		{ "setImage", w_SpriteBatch_setImage },
+		{ "setColor", w_SpriteBatch_setColor },
 		{ 0, 0 }
 		{ 0, 0 }
 	};
 	};