diff --git a/src/modules/graphics/opengl/Mesh.cpp b/src/modules/graphics/opengl/Mesh.cpp index 86044fdee..64877ce0b 100644 --- a/src/modules/graphics/opengl/Mesh.cpp +++ b/src/modules/graphics/opengl/Mesh.cpp @@ -68,8 +68,8 @@ Mesh::Mesh(const std::vector &vertexformat, const void *data, size , elementCount(0) , elementDataType(0) , drawMode(drawmode) - , rangeMin(-1) - , rangeMax(-1) + , rangeStart(-1) + , rangeCount(-1) { setupAttachedAttributes(); calculateAttributeSizes(); @@ -95,8 +95,8 @@ Mesh::Mesh(const std::vector &vertexformat, int vertexcount, DrawM , elementCount(0) , elementDataType(getGLDataTypeFromMax(vertexcount)) , drawMode(drawmode) - , rangeMin(-1) - , rangeMax(-1) + , rangeStart(-1) + , rangeCount(-1) { if (vertexcount <= 0) throw love::Exception("Invalid number of vertices (%d).", vertexcount); @@ -517,24 +517,28 @@ Mesh::DrawMode Mesh::getDrawMode() const return drawMode; } -void Mesh::setDrawRange(int min, int max) +void Mesh::setDrawRange(int start, int count) { - if (min < 0 || max < 0 || min > max) + if (start < 0 || count <= 0) throw love::Exception("Invalid draw range."); - rangeMin = min; - rangeMax = max; + rangeStart = start; + rangeCount = count; } void Mesh::setDrawRange() { - rangeMin = rangeMax = -1; + rangeStart = rangeCount = -1; } -void Mesh::getDrawRange(int &min, int &max) const +bool Mesh::getDrawRange(int &start, int &count) const { - min = rangeMin; - max = rangeMax; + if (rangeStart < 0 || rangeCount < 0) + return false; + + start = rangeStart; + count = rangeCount; + return true; } int Mesh::bindAttributeToShaderInput(int attributeindex, const std::string &inputname) @@ -614,31 +618,33 @@ void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, flo // Make sure the index buffer isn't mapped (sends data to GPU if needed.) ibo->unmap(); - int max = (int) elementCount - 1; - if (rangeMax >= 0) - max = std::min(rangeMax, max); + int start = std::min(std::max(0, rangeStart), (int) elementCount - 1); - int min = 0; - if (rangeMin >= 0) - min = std::min(rangeMin, max); + int count = (int) elementCount; + if (rangeCount > 0) + count = std::min(count, rangeCount); + + count = std::min(count, (int) elementCount - start); GLenum type = elementDataType; - const void *indices = ibo->getPointer(min * getGLDataTypeSize(type)); + const void *indices = ibo->getPointer(start * getGLDataTypeSize(type)); - gl.drawElements(getGLDrawMode(drawMode), max - min + 1, type, indices); + if (count > 0) + gl.drawElements(getGLDrawMode(drawMode), count, type, indices); } else { - int max = (int) vertexCount - 1; - if (rangeMax >= 0) - max = std::min(rangeMax, max); + int start = std::min(std::max(0, rangeStart), (int) vertexCount - 1); - int min = 0; - if (rangeMin >= 0) - min = std::min(rangeMin, max); + int count = (int) vertexCount; + if (rangeCount > 0) + count = std::min(count, rangeCount); + + count = std::min(count, (int) vertexCount - start); // Normal non-indexed drawing (no custom vertex map.) - gl.drawArrays(getGLDrawMode(drawMode), min, max - min + 1); + if (count > 0) + gl.drawArrays(getGLDrawMode(drawMode), start, count); } } diff --git a/src/modules/graphics/opengl/Mesh.h b/src/modules/graphics/opengl/Mesh.h index 10f3492fc..c3bea02b2 100644 --- a/src/modules/graphics/opengl/Mesh.h +++ b/src/modules/graphics/opengl/Mesh.h @@ -190,9 +190,9 @@ public: void setDrawMode(DrawMode mode); DrawMode getDrawMode() const; - void setDrawRange(int min, int max); + void setDrawRange(int start, int count); void setDrawRange(); - void getDrawRange(int &min, int &max) const; + bool getDrawRange(int &start, int &count) const; int bindAttributeToShaderInput(int attributeindex, const std::string &inputname); @@ -252,8 +252,8 @@ private: DrawMode drawMode; - int rangeMin; - int rangeMax; + int rangeStart; + int rangeCount; StrongRef texture; diff --git a/src/modules/graphics/opengl/wrap_Mesh.cpp b/src/modules/graphics/opengl/wrap_Mesh.cpp index 148883db8..1db25874c 100644 --- a/src/modules/graphics/opengl/wrap_Mesh.cpp +++ b/src/modules/graphics/opengl/wrap_Mesh.cpp @@ -480,9 +480,9 @@ int w_Mesh_setDrawRange(lua_State *L) t->setDrawRange(); else { - int rangemin = (int) luaL_checknumber(L, 2) - 1; - int rangemax = (int) luaL_checknumber(L, 3) - 1; - luax_catchexcept(L, [&](){ t->setDrawRange(rangemin, rangemax); }); + int start = (int) luaL_checknumber(L, 2) - 1; + int count = (int) luaL_checknumber(L, 3); + luax_catchexcept(L, [&](){ t->setDrawRange(start, count); }); } return 0; @@ -492,15 +492,13 @@ int w_Mesh_getDrawRange(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); - int rangemin = -1; - int rangemax = -1; - t->getDrawRange(rangemin, rangemax); - - if (rangemin < 0 || rangemax < 0) + int start = 0; + int count = 1; + if (!t->getDrawRange(start, count)) return 0; - lua_pushinteger(L, rangemin + 1); - lua_pushinteger(L, rangemax + 1); + lua_pushinteger(L, start + 1); + lua_pushinteger(L, count); return 2; }