From 25376ba3107d36567a30a995fcaf3fd99937ed9d Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 21 Sep 2016 20:03:39 -0300 Subject: [PATCH] Added SpriteBatch:setDrawRange(start, count) and SpriteBatch:getDrawRange. --HG-- branch : minor --- src/modules/graphics/opengl/Mesh.cpp | 5 ++- src/modules/graphics/opengl/SpriteBatch.cpp | 39 ++++++++++++++++++- src/modules/graphics/opengl/SpriteBatch.h | 7 ++++ .../graphics/opengl/wrap_SpriteBatch.cpp | 32 +++++++++++++++ 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index 64877ce0b..e28768f44 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -533,7 +533,7 @@ void Mesh::setDrawRange() bool Mesh::getDrawRange(int &start, int &count) const { - if (rangeStart < 0 || rangeCount < 0) + if (rangeStart < 0 || rangeCount <= 0) return false; start = rangeStart; @@ -576,6 +576,9 @@ int Mesh::bindAttributeToShaderInput(int attributeindex, const std::string &inpu void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) { + if (vertexCount <= 0) + return; + OpenGL::TempDebugGroup debuggroup("Mesh draw"); uint32 enabledattribs = 0; diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index 27671dbd8..dcf9e8eac 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -48,6 +48,8 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, Mesh::Usage usage) , color(0) , array_buf(nullptr) , quad_indices(size) + , range_start(-1) + , range_count(-1) { if (size <= 0) throw love::Exception("Invalid SpriteBatch size."); @@ -223,6 +225,30 @@ void SpriteBatch::attachAttribute(const std::string &name, Mesh *mesh) attached_attributes[name] = newattrib; } +void SpriteBatch::setDrawRange(int start, int count) +{ + if (start < 0 || count <= 0) + throw love::Exception("Invalid draw range."); + + range_start = start; + range_count = count; +} + +void SpriteBatch::setDrawRange() +{ + range_start = range_count = -1; +} + +bool SpriteBatch::getDrawRange(int &start, int &count) const +{ + if (range_start < 0 || range_count <= 0) + return false; + + start = range_start; + count = range_count; + return true; +} + void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) { const size_t pos_offset = offsetof(Vertex, x); @@ -279,8 +305,19 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float gl.prepareDraw(); + int start = std::min(std::max(0, range_start), next - 1); + + int count = next; + if (range_count > 0) + count = std::min(count, range_count); + + count = std::min(count, next - start); + GLBuffer::Bind element_bind(*quad_indices.getBuffer()); - gl.drawElements(GL_TRIANGLES, (GLsizei) quad_indices.getIndexCount(next), quad_indices.getType(), quad_indices.getPointer(0)); + const void *indices = quad_indices.getPointer(start * quad_indices.getElementSize()); + + if (count > 0) + gl.drawElements(GL_TRIANGLES, (GLsizei) quad_indices.getIndexCount(count), quad_indices.getType(), indices); } void SpriteBatch::addv(const Vertex *v, const Matrix3 &m, int index) diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h index 8a40581dd..9e865b1b2 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -101,6 +101,10 @@ public: **/ void attachAttribute(const std::string &name, Mesh *mesh); + void setDrawRange(int start, int count); + void setDrawRange(); + bool getDrawRange(int &start, int &count) const; + // Implements Drawable. void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky); @@ -146,6 +150,9 @@ private: std::unordered_map attached_attributes; + int range_start; + int range_count; + }; // SpriteBatch } // opengl diff --git a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp index 325a6949b..e1eed3773 100644 --- a/src/modules/graphics/opengl/wrap_SpriteBatch.cpp +++ b/src/modules/graphics/opengl/wrap_SpriteBatch.cpp @@ -205,6 +205,36 @@ int w_SpriteBatch_attachAttribute(lua_State *L) return 0; } +int w_SpriteBatch_setDrawRange(lua_State *L) +{ + SpriteBatch *t = luax_checkspritebatch(L, 1); + + if (lua_isnoneornil(L, 2)) + t->setDrawRange(); + else + { + int start = (int) luaL_checknumber(L, 2) - 1; + int count = (int) luaL_checknumber(L, 3); + luax_catchexcept(L, [&](){ t->setDrawRange(start, count); }); + } + + return 0; +} + +int w_SpriteBatch_getDrawRange(lua_State *L) +{ + SpriteBatch *t = luax_checkspritebatch(L, 1); + + int start = 0; + int count = 1; + if (!t->getDrawRange(start, count)) + return 0; + + lua_pushnumber(L, start + 1); + lua_pushnumber(L, count); + return 2; +} + static const luaL_Reg w_SpriteBatch_functions[] = { { "add", w_SpriteBatch_add }, @@ -218,6 +248,8 @@ static const luaL_Reg w_SpriteBatch_functions[] = { "getCount", w_SpriteBatch_getCount }, { "getBufferSize", w_SpriteBatch_getBufferSize }, { "attachAttribute", w_SpriteBatch_attachAttribute }, + { "setDrawRange", w_SpriteBatch_setDrawRange }, + { "getDrawRange", w_SpriteBatch_getDrawRange }, { 0, 0 } };