Added SpriteBatch:remove(id)

This commit is contained in:
Alex Szpakowski
2013-02-11 18:27:57 -04:00
parent 842c01b4e5
commit ceb0ee6c7e
7 changed files with 137 additions and 18 deletions
+2 -2
View File
@@ -13,13 +13,13 @@
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>${PRODUCT_NAME}</string> <string>LÖVE</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>0.8.0</string> <string>0.8.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>LoVe</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>0.8.0</string> <string>0.8.0</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
@@ -685,7 +685,7 @@
FA577A8C16C71D3600860150 /* auto.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = auto.lua; sourceTree = "<group>"; }; FA577A8C16C71D3600860150 /* auto.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = auto.lua; sourceTree = "<group>"; };
FA577A8D16C71D3600860150 /* boot.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = boot.lua; sourceTree = "<group>"; }; FA577A8D16C71D3600860150 /* boot.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = boot.lua; sourceTree = "<group>"; };
FA577A8E16C71D3600860150 /* graphics.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = graphics.lua; sourceTree = "<group>"; }; FA577A8E16C71D3600860150 /* graphics.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = graphics.lua; sourceTree = "<group>"; };
FA577AAF16C7507900860150 /* love framework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = "love framework.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; FA577AAF16C7507900860150 /* love.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = "love.framework"; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -959,7 +959,7 @@
2F654C0235EB60C744A22507 /* Products */ = { 2F654C0235EB60C744A22507 /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FA577AAF16C7507900860150 /* love framework.framework */, FA577AAF16C7507900860150 /* love.framework */,
); );
name = Products; name = Products;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1578,9 +1578,9 @@
/* End PBXHeadersBuildPhase section */ /* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
FA577AAE16C7507900860150 /* love framework */ = { FA577AAE16C7507900860150 /* Framework */ = {
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "love framework" */; buildConfigurationList = FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "Framework" */;
buildPhases = ( buildPhases = (
FA577AAA16C7507900860150 /* Sources */, FA577AAA16C7507900860150 /* Sources */,
FA577AAB16C7507900860150 /* Frameworks */, FA577AAB16C7507900860150 /* Frameworks */,
@@ -1591,9 +1591,9 @@
); );
dependencies = ( dependencies = (
); );
name = "love framework"; name = Framework;
productName = love; productName = love;
productReference = FA577AAF16C7507900860150 /* love framework.framework */; productReference = FA577AAF16C7507900860150 /* love.framework */;
productType = "com.apple.product-type.framework"; productType = "com.apple.product-type.framework";
}; };
/* End PBXNativeTarget section */ /* End PBXNativeTarget section */
@@ -1615,7 +1615,7 @@
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
targets = ( targets = (
FA577AAE16C7507900860150 /* love framework */, FA577AAE16C7507900860150 /* Framework */,
); );
}; };
/* End PBXProject section */ /* End PBXProject section */
@@ -1951,7 +1951,7 @@
defaultConfigurationIsVisible = 0; defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug; defaultConfigurationName = Debug;
}; };
FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "love framework" */ = { FA577ABF16C7507900860150 /* Build configuration list for PBXNativeTarget "Framework" */ = {
isa = XCConfigurationList; isa = XCConfigurationList;
buildConfigurations = ( buildConfigurations = (
FA577AC016C7507900860150 /* Debug */, FA577AC016C7507900860150 /* Debug */,
@@ -29,6 +29,16 @@
FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; }; FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
FA08F6A616C77A4300F007B5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = FA577A9316C7217800860150 /* love-framework.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = FA577AAF16C7507900860150;
remoteInfo = "love framework";
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
A9255DDE1043185300BA1496 /* Copy Frameworks */ = { A9255DDE1043185300BA1496 /* Copy Frameworks */ = {
isa = PBXCopyFilesBuildPhase; isa = PBXCopyFilesBuildPhase;
@@ -147,6 +157,14 @@
name = Resources; name = Resources;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
FA08F6A316C77A4300F007B5 /* Products */ = {
isa = PBXGroup;
children = (
FA08F6A716C77A4300F007B5 /* love.framework */,
);
name = Products;
sourceTree = "<group>";
};
FA577A9D16C7262E00860150 /* Source */ = { FA577A9D16C7262E00860150 /* Source */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@@ -200,6 +218,12 @@
); );
mainGroup = 29B97314FDCFA39411CA2CEA /* love */; mainGroup = 29B97314FDCFA39411CA2CEA /* love */;
projectDirPath = ""; projectDirPath = "";
projectReferences = (
{
ProductGroup = FA08F6A316C77A4300F007B5 /* Products */;
ProjectRef = FA577A9316C7217800860150 /* love-framework.xcodeproj */;
},
);
projectRoot = ""; projectRoot = "";
targets = ( targets = (
8D1107260486CEB800E47090 /* love */, 8D1107260486CEB800E47090 /* love */,
@@ -207,6 +231,17 @@
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXReferenceProxy section */
FA08F6A716C77A4300F007B5 /* love.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
name = "love.framework";
path = love.framework;
remoteRef = FA08F6A616C77A4300F007B5 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
8D1107290486CEB800E47090 /* Resources */ = { 8D1107290486CEB800E47090 /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
+77 -8
View File
@@ -97,9 +97,25 @@ SpriteBatch::~SpriteBatch()
int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/) int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
{ {
// Only do this if there's a free slot. // Only do this if there's a free slot.
if ((index == -1 && next >= size) || index < -1 || index >= size) if ((index == -1 && next >= size && gaps.size() == 0) || index < -1 || index >= size)
return -1; return -1;
// Determine where in the vertex buffer to insert into, using the gap list
// if possible.
int realindex;
if (index == -1 && gaps.size() > 0)
{
realindex = gaps.front();
gaps.pop_front();
}
else
{
realindex = (index == -1) ? next : index;
std::deque<int>::iterator it = std::find(gaps.begin(), gaps.end(), realindex);
if (it != gaps.end())
gaps.erase(it); // This index is no longer a gap.
}
// Needed for colors. // Needed for colors.
memcpy(sprite, image->getVertices(), sizeof(vertex)*4); memcpy(sprite, image->getVertices(), sizeof(vertex)*4);
@@ -111,20 +127,38 @@ int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, fl
if (color) if (color)
setColorv(sprite, *color); setColorv(sprite, *color);
addv(sprite, (index == -1 ? next : index));
addv(sprite, realindex);
// Increment counter. // Increment counter.
if (index == -1) if (index == -1 && realindex == next)
return next++; return next++;
return index;
return realindex;
} }
int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/) int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/)
{ {
// Only do this if there's a free slot. // Only do this if there's a free slot.
if ((index == -1 && next >= size) || index < -1 || index >= next) if ((index == -1 && next >= size && gaps.size() == 0) || index < -1 || index >= next)
return -1; return -1;
// Determine where in the vertex buffer to insert into, using the gap list
// if possible.
int realindex;
if (index == -1 && gaps.size() > 0)
{
realindex = gaps.front();
gaps.pop_front();
}
else
{
realindex = (index == -1) ? next : index;
std::deque<int>::iterator it = std::find(gaps.begin(), gaps.end(), realindex);
if (it != gaps.end())
gaps.erase(it); // This index is no longer a gap.
}
// Needed for colors. // Needed for colors.
memcpy(sprite, quad->getVertices(), sizeof(vertex)*4); memcpy(sprite, quad->getVertices(), sizeof(vertex)*4);
@@ -136,18 +170,53 @@ int SpriteBatch::addq(Quad *quad, float x, float y, float a, float sx, float sy,
if (color) if (color)
setColorv(sprite, *color); setColorv(sprite, *color);
addv(sprite, (index == -1 ? next : index)); addv(sprite, realindex);
// Increment counter. // Increment counter.
if (index == -1) if (index == -1 && realindex == next)
return next++; return next++;
return index;
return realindex;
}
void SpriteBatch::remove(int index)
{
if (index < 0 || index >= next || next <= 0)
return;
// If this is the last index in the sprite list, decrease the total sprite
// count instead of adding a dummy sprite.
if (index == next - 1)
{
int spritecount = index;
// Remove all consecutive gaps at the end of the sprite list.
std::deque<int>::iterator it;
while ((it = std::find(gaps.begin(), gaps.end(), --spritecount)) != gaps.end())
gaps.erase(it);
next = spritecount + 1;
return;
}
else if (std::find(gaps.begin(), gaps.end(), index) != gaps.end())
return; // Don't add the same index to the gap list twice.
// OpenGL won't render any primitive whose vertices are all identical.
for (int i = 0; i < 4; i++)
sprite[i].x = sprite[i].y = 0;
// Replace the existing sprite at this index with the dummy sprite.
addv(sprite, index);
gaps.push_back(index);
} }
void SpriteBatch::clear() void SpriteBatch::clear()
{ {
// Reset the position of the next index. // Reset the position of the next index.
next = 0; next = 0;
gaps.clear();
} }
void *SpriteBatch::lock() void *SpriteBatch::lock()
@@ -23,6 +23,7 @@
// C // C
#include <cstring> #include <cstring>
#include <deque>
// LOVE // LOVE
#include "common/math.h" #include "common/math.h"
@@ -64,6 +65,7 @@ public:
int add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1); int add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
int addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1); int addq(Quad *quad, float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index = -1);
void remove(int index);
void clear(); void clear();
void *lock(); void *lock();
@@ -126,6 +128,10 @@ private:
VertexBuffer *array_buf; VertexBuffer *array_buf;
VertexIndex *element_buf; VertexIndex *element_buf;
// List of gaps in the SpriteBatch. Checked when adding sprites, and added
// to when removing them.
std::deque<int> gaps;
}; // SpriteBatch }; // SpriteBatch
} // opengl } // opengl
@@ -101,6 +101,13 @@ int w_SpriteBatch_setq(lua_State *L)
return 0; return 0;
} }
int w_SpriteBatch_remove(lua_State *L)
{
SpriteBatch *t = luax_checkspritebatch(L, 1);
int id = luaL_checkinteger(L, 2);
t->remove(id);
return 0;
}
int w_SpriteBatch_clear(lua_State *L) int w_SpriteBatch_clear(lua_State *L)
{ {
@@ -191,6 +198,7 @@ static const luaL_Reg functions[] =
{ "addq", w_SpriteBatch_addq }, { "addq", w_SpriteBatch_addq },
{ "set", w_SpriteBatch_set }, { "set", w_SpriteBatch_set },
{ "setq", w_SpriteBatch_setq }, { "setq", w_SpriteBatch_setq },
{ "remove", w_SpriteBatch_remove },
{ "clear", w_SpriteBatch_clear }, { "clear", w_SpriteBatch_clear },
{ "bind", w_SpriteBatch_bind }, { "bind", w_SpriteBatch_bind },
{ "unbind", w_SpriteBatch_unbind }, { "unbind", w_SpriteBatch_unbind },
@@ -36,6 +36,7 @@ int w_SpriteBatch_add(lua_State *L);
int w_SpriteBatch_addq(lua_State *L); int w_SpriteBatch_addq(lua_State *L);
int w_SpriteBatch_set(lua_State *L); int w_SpriteBatch_set(lua_State *L);
int w_SpriteBatch_setq(lua_State *L); int w_SpriteBatch_setq(lua_State *L);
int w_SpriteBatch_remove(lua_State *L);
int w_SpriteBatch_clear(lua_State *L); int w_SpriteBatch_clear(lua_State *L);
int w_SpriteBatch_lock(lua_State *L); int w_SpriteBatch_lock(lua_State *L);
int w_SpriteBatch_unlock(lua_State *L); int w_SpriteBatch_unlock(lua_State *L);