1. Bart van Strien
  2. love-experiments

Commits

Alex Szpakowski  committed 6ed4698

Added SpriteBatch:setDrawRange(min_id, max_id). Prevents sprites other than those whose ids are within the specified range from being drawn in subsequent draw calls.
Also changed SpriteBatch ids to be 1-based instead of 0-based.

  • Participants
  • Parent commits 45e6935
  • Branches SpriteBatch-setDrawRange

Comments (0)

Files changed (4)

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

View file
  • Ignore whitespace
 
 // stdlib
 #include <algorithm>
+#include <limits>
 
 namespace love
 {
 	, color(0)
 	, array_buf(0)
 	, element_buf(0)
+	, drawRangeMin(0)
+	, drawRangeMax(std::numeric_limits<int>::max() - 1)
 {
 	if (size <= 0)
 		throw love::Exception("Invalid SpriteBatch size.");
 	return size;
 }
 
+void SpriteBatch::setDrawRange(int minid, int maxid)
+{
+	if (minid > maxid || maxid < 0)
+		throw love::Exception("Invalid draw range.");
+
+	drawRangeMin = std::max(minid, 0);
+	drawRangeMax = std::max(maxid, 0);
+}
+
+void SpriteBatch::setDrawRange()
+{
+	drawRangeMin = 0;
+	drawRangeMax = std::numeric_limits<int>::max() - 1;
+}
+
+int SpriteBatch::getDrawRangeMin() const
+{
+	return drawRangeMin;
+}
+
+int SpriteBatch::getDrawRangeMax() const
+{
+	return drawRangeMax;
+}
+
 void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
 {
 	const int color_offset = 0;
 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 	glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), array_buf->getPointer(texel_offset));
 
-	glDrawElements(GL_TRIANGLES, element_buf->getIndexCount(next), element_buf->getType(), element_buf->getPointer(0));
+	size_t startindex = element_buf->getIndexCount(drawRangeMin);
+	size_t indexcount = element_buf->getIndexCount(std::min(drawRangeMax - drawRangeMin, next));
+
+	const GLvoid *indices = element_buf->getPointer(startindex * element_buf->getElementSize());
+
+	glDrawElements(GL_TRIANGLES, indexcount, element_buf->getType(), indices);
 
 	glDisableClientState(GL_VERTEX_ARRAY);
 	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

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

View file
  • Ignore whitespace
 	 **/
 	int getBufferSize() const;
 
+	/**
+	 * Sets which sprites will be drawn in subsequent draw calls, by specifying
+	 * a minimum and maximum sprite id to be drawn.
+	 **/
+	void setDrawRange(int minid, int maxid);
+
+	/**
+	 * Resets the draw range back to the default (all sprites will be drawn.)
+	 **/
+	void setDrawRange();
+
+	int getDrawRangeMin() const;
+	int getDrawRangeMax() const;
+
 	// Implements Drawable.
 	void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
 
 	VertexBuffer *array_buf;
 	VertexIndex *element_buf;
 
+	int drawRangeMin;
+	int drawRangeMax;
+
 	static StringMap<UsageHint, USAGE_MAX_ENUM>::Entry usageHintEntries[];
 	static StringMap<UsageHint, USAGE_MAX_ENUM> usageHints;
 

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

View file
  • Ignore whitespace
 	float oy = (float)luaL_optnumber(L, 8, 0);
 	float kx = (float)luaL_optnumber(L, 9, 0);
 	float ky = (float)luaL_optnumber(L, 10, 0);
-	lua_pushnumber(L, t->add(x, y, angle, sx, sy, ox, oy, kx, ky));
+	lua_pushnumber(L, t->add(x, y, angle, sx, sy, ox, oy, kx, ky) + 1);
 	return 1;
 }
 
 	float ky = (float)luaL_optnumber(L, 11, 0);
 	try
 	{
-		lua_pushnumber(L, t->addg(g, x, y, angle, sx, sy, ox, oy, kx, ky));
+		lua_pushnumber(L, t->addg(g, x, y, angle, sx, sy, ox, oy, kx, ky) + 1);
 	}
 	catch (love::Exception &e)
 	{
 	float oy = (float)luaL_optnumber(L, 9, 0);
 	float kx = (float)luaL_optnumber(L, 10, 0);
 	float ky = (float)luaL_optnumber(L, 11, 0);
-	t->add(x, y, angle, sx, sy, ox, oy, kx, ky, index);
+	t->add(x, y, angle, sx, sy, ox, oy, kx, ky, index - 1);
 	return 0;
 }
 
 	float ky = (float)luaL_optnumber(L, 12, 0);
 	try
 	{
-		t->addg(g, x, y, angle, sx, sy, ox, oy, kx, ky, index);
+		t->addg(g, x, y, angle, sx, sy, ox, oy, kx, ky, index - 1);
 	}
 	catch (love::Exception &e)
 	{
 	return 1;
 }
 
+int w_SpriteBatch_setDrawRange(lua_State *L)
+{
+	SpriteBatch *t = luax_checkspritebatch(L, 1);
+
+	// Set the default draw range if no arguments are given.
+	if (lua_isnoneornil(L, 2) && lua_isnoneornil(L, 3))
+	{
+		t->setDrawRange();
+		return 0;
+	}
+
+	int minid = luaL_checkint(L, 2) - 1;
+	int maxid = luaL_checkint(L, 3) - 1;
+	try
+	{
+		t->setDrawRange(minid, maxid);
+	}
+	catch (love::Exception &e)
+	{
+		return luaL_error(L, "%s", e.what());
+	}
+	return 0;
+}
+
+int w_SpriteBatch_getDrawRange(lua_State *L)
+{
+	SpriteBatch *t = luax_checkspritebatch(L, 1);
+	lua_pushinteger(L, t->getDrawRangeMin() + 1);
+	lua_pushinteger(L, t->getDrawRangeMax() + 1);
+	return 2;
+}
+
 static const luaL_Reg functions[] =
 {
 	{ "add", w_SpriteBatch_add },
 	{ "getCount", w_SpriteBatch_getCount },
 	{ "setBufferSize", w_SpriteBatch_setBufferSize },
 	{ "getBufferSize", w_SpriteBatch_getBufferSize },
+	{ "setDrawRange", w_SpriteBatch_setDrawRange },
+	{ "getDrawRange", w_SpriteBatch_getDrawRange },
 	{ 0, 0 }
 };
 

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

View file
  • Ignore whitespace
 int w_SpriteBatch_getCount(lua_State *L);
 int w_SpriteBatch_setBufferSize(lua_State *L);
 int w_SpriteBatch_getBufferSize(lua_State *L);
+int w_SpriteBatch_setDrawRange(lua_State *L);
+int w_SpriteBatch_getDrawRange(lua_State *L);
 
 extern "C" int luaopen_spritebatch(lua_State *L);