diff --git a/src/modules/graphics/opengl/SpriteBatch.cpp b/src/modules/graphics/opengl/SpriteBatch.cpp index 08fcf7e04..0f35e92e5 100644 --- a/src/modules/graphics/opengl/SpriteBatch.cpp +++ b/src/modules/graphics/opengl/SpriteBatch.cpp @@ -47,7 +47,7 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage) , next(0) , color(0) , array_buf(nullptr) - , element_buf(nullptr) + , element_buf(size) , buffer_used_offset(0) , buffer_used_size(0) { @@ -74,18 +74,15 @@ SpriteBatch::SpriteBatch(Texture *texture, int size, int usage) try { array_buf = VertexBuffer::Create(vertex_size, GL_ARRAY_BUFFER, gl_usage); - element_buf = new VertexIndex(size); } catch (love::Exception &) { delete array_buf; - delete element_buf; throw; } catch (std::bad_alloc &) { delete array_buf; - delete element_buf; throw love::Exception("Out of memory."); } } @@ -94,7 +91,6 @@ SpriteBatch::~SpriteBatch() { delete color; delete array_buf; - delete element_buf; } int SpriteBatch::add(float x, float y, float a, float sx, float sy, float ox, float oy, float kx, float ky, int index /*= -1*/) @@ -171,7 +167,7 @@ void SpriteBatch::setTexture(Texture *newtexture) texture.set(newtexture); } -Texture *SpriteBatch::getTexture() +Texture *SpriteBatch::getTexture() const { return texture.get(); } @@ -216,40 +212,32 @@ void SpriteBatch::setBufferSize(int newsize) } size_t vertex_size = sizeof(Vertex) * 4 * newsize; - VertexBuffer *new_array_buf = nullptr; - VertexIndex *new_element_buf = nullptr; try { new_array_buf = VertexBuffer::Create(vertex_size, array_buf->getTarget(), array_buf->getUsage()); - new_element_buf = new VertexIndex(newsize); + + // Copy as much of the old data into the new VertexBuffer as can fit. + VertexBuffer::Bind bind(*new_array_buf); + void *new_data = new_array_buf->map(); + memcpy(new_data, old_data, sizeof(Vertex) * 4 * std::min(newsize, size)); + + element_buf = VertexIndex(newsize); } catch (love::Exception &) { delete new_array_buf; - delete new_element_buf; throw; } - // Copy as much of the old data into the new VertexBuffer as can fit. - { - VertexBuffer::Bind bind(*new_array_buf); - new_array_buf->fill(0, sizeof(Vertex) * 4 * std::min(newsize, size), old_data); - } - // We don't need to unmap the old VertexBuffer since we're deleting it. delete array_buf; - delete element_buf; array_buf = new_array_buf; - element_buf = new_element_buf; size = newsize; next = std::min(next, newsize); - - // The new VertexBuffer isn't mapped, so we should reset these variables. - buffer_used_offset = buffer_used_size = 0; } int SpriteBatch::getBufferSize() const @@ -275,7 +263,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float texture->predraw(); VertexBuffer::Bind array_bind(*array_buf); - VertexBuffer::Bind element_bind(*element_buf->getVertexBuffer()); + VertexBuffer::Bind element_bind(*element_buf.getVertexBuffer()); // Make sure the VBO isn't mapped when we draw (sends data to GPU if needed.) array_buf->unmap(buffer_used_offset, buffer_used_size); @@ -297,7 +285,7 @@ void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), array_buf->getPointer(texel_offset)); gl.prepareDraw(); - gl.drawElements(GL_TRIANGLES, element_buf->getIndexCount(next), element_buf->getType(), element_buf->getPointer(0)); + gl.drawElements(GL_TRIANGLES, element_buf.getIndexCount(next), element_buf.getType(), element_buf.getPointer(0)); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); diff --git a/src/modules/graphics/opengl/SpriteBatch.h b/src/modules/graphics/opengl/SpriteBatch.h index 55a736929..5f48b2f54 100644 --- a/src/modules/graphics/opengl/SpriteBatch.h +++ b/src/modules/graphics/opengl/SpriteBatch.h @@ -26,13 +26,13 @@ // LOVE #include "common/math.h" -#include "common/Object.h" #include "common/Matrix.h" #include "common/StringMap.h" #include "graphics/Drawable.h" #include "graphics/Volatile.h" #include "graphics/Color.h" #include "graphics/Quad.h" +#include "VertexBuffer.h" namespace love { @@ -43,8 +43,6 @@ namespace opengl // Forward declarations. class Texture; -class VertexBuffer; -class VertexIndex; class SpriteBatch : public Drawable { @@ -68,7 +66,7 @@ public: void flush(); void setTexture(Texture *newtexture); - Texture *getTexture(); + Texture *getTexture() const; /** * Set the current color for this SpriteBatch. The sprites added @@ -139,7 +137,7 @@ private: Color *color; VertexBuffer *array_buf; - VertexIndex *element_buf; + VertexIndex element_buf; // The portion of the vertex buffer that's been modified while mapped. size_t buffer_used_offset; diff --git a/src/modules/graphics/opengl/VertexBuffer.cpp b/src/modules/graphics/opengl/VertexBuffer.cpp index 88da3b854..2772cfb52 100644 --- a/src/modules/graphics/opengl/VertexBuffer.cpp +++ b/src/modules/graphics/opengl/VertexBuffer.cpp @@ -119,7 +119,7 @@ VBO::VBO(size_t size, GLenum target, GLenum usage, MemoryBacking backing) : VertexBuffer(size, target, usage, backing) , vbo(0) , memory_map(nullptr) - , is_dirty(true) + , is_dirty(false) { if (!(GLEE_ARB_vertex_buffer_object || GLEE_VERSION_1_5)) throw love::Exception("Not supported"); @@ -321,6 +321,20 @@ VertexIndex::VertexIndex(size_t size) addSize(size); } +VertexIndex::VertexIndex(const VertexIndex &other) + : size(other.size) +{ + addSize(size); +} + +VertexIndex &VertexIndex::operator = (const VertexIndex &other) +{ + addSize(other.size); + removeSize(size); + size = other.size; + return *this; +} + VertexIndex::~VertexIndex() { removeSize(size); diff --git a/src/modules/graphics/opengl/VertexBuffer.h b/src/modules/graphics/opengl/VertexBuffer.h index dc207e777..de960c88b 100644 --- a/src/modules/graphics/opengl/VertexBuffer.h +++ b/src/modules/graphics/opengl/VertexBuffer.h @@ -412,6 +412,9 @@ public: */ VertexIndex(size_t size); + VertexIndex(const VertexIndex &other); + VertexIndex &operator = (const VertexIndex &other); + /** * Removes an entry from the list of sizes and resizes the VertexBuffer * if needed.