diff --git a/src/modules/graphics/Buffer.cpp b/src/modules/graphics/Buffer.cpp index f85205307..096217780 100644 --- a/src/modules/graphics/Buffer.cpp +++ b/src/modules/graphics/Buffer.cpp @@ -28,7 +28,7 @@ namespace graphics love::Type Buffer::type("GraphicsBuffer", &Object::type); -Buffer::Buffer(const Settings &settings, const void */*data*/, size_t size) +Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector &bufferformat, size_t size, size_t arraylength) : arrayLength(0) , arrayStride(0) , size(size) @@ -36,11 +36,6 @@ Buffer::Buffer(const Settings &settings, const void */*data*/, size_t size) , usage(settings.usage) , mapFlags(settings.mapFlags) , mapped(false) -{ -} - -Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector &bufferformat, const void *data, size_t size, size_t arraylength) - : Buffer(settings, data, size) { if (size == 0 && arraylength == 0) throw love::Exception("Size or array length must be specified."); @@ -128,5 +123,66 @@ int Buffer::getDataMemberIndex(const std::string &name) const return -1; } +std::vector Buffer::getCommonFormatDeclaration(CommonFormat format) +{ + switch (format) + { + case CommonFormat::NONE: + return {}; + case CommonFormat::XYf: + return { + {"VertexPosition", DATAFORMAT_FLOAT_VEC2} + }; + case CommonFormat::XYZf: + return { + {"VertexPosition", DATAFORMAT_FLOAT_VEC3} + }; + case CommonFormat::RGBAub: + return { + {"VertexColor", DATAFORMAT_UNORM8_VEC4} + }; + case CommonFormat::STf_RGBAub: + return { + {"VertexTexCoord", DATAFORMAT_FLOAT_VEC2}, + {"VertexColor", DATAFORMAT_UNORM8_VEC4}, + }; + case CommonFormat::STPf_RGBAub: + return { + {"VertexTexCoord", DATAFORMAT_FLOAT_VEC3}, + {"VertexColor", DATAFORMAT_UNORM8_VEC4}, + }; + case CommonFormat::XYf_STf: + return { + {"VertexPosition", DATAFORMAT_FLOAT_VEC2}, + {"VertexTexCoord", DATAFORMAT_FLOAT_VEC2}, + }; + case CommonFormat::XYf_STPf: + return { + {"VertexPosition", DATAFORMAT_FLOAT_VEC2}, + {"VertexTexCoord", DATAFORMAT_FLOAT_VEC3}, + }; + case CommonFormat::XYf_STf_RGBAub: + return { + {"VertexPosition", DATAFORMAT_FLOAT_VEC2}, + {"VertexTexCoord", DATAFORMAT_FLOAT_VEC2}, + {"VertexColor", DATAFORMAT_UNORM8_VEC4}, + }; + case CommonFormat::XYf_STus_RGBAub: + return { + {"VertexPosition", DATAFORMAT_FLOAT_VEC2}, + {"VertexTexCoord", DATAFORMAT_UNORM16_VEC2}, + {"VertexColor", DATAFORMAT_UNORM8_VEC4}, + }; + case CommonFormat::XYf_STPf_RGBAub: + return { + {"VertexPosition", DATAFORMAT_FLOAT_VEC2}, + {"VertexTexCoord", DATAFORMAT_FLOAT_VEC2}, + {"VertexColor", DATAFORMAT_UNORM8_VEC4}, + }; + } + + return {}; +} + } // graphics } // love diff --git a/src/modules/graphics/Buffer.h b/src/modules/graphics/Buffer.h index 86a08698b..68935569a 100644 --- a/src/modules/graphics/Buffer.h +++ b/src/modules/graphics/Buffer.h @@ -103,8 +103,7 @@ public: {} }; - Buffer(const Settings &settings, const void *data, size_t size); - Buffer(Graphics *gfx, const Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength); + Buffer(Graphics *gfx, const Settings &settings, const std::vector &format, size_t size, size_t arraylength); virtual ~Buffer(); size_t getSize() const { return size; } @@ -154,6 +153,8 @@ public: **/ virtual void copyTo(size_t offset, size_t size, Buffer *other, size_t otheroffset) = 0; + static std::vector getCommonFormatDeclaration(CommonFormat format); + class Mapper { public: diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 855a60d08..db1135840 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -265,7 +265,7 @@ Shader *Graphics::newShader(const std::string &vertex, const std::string &pixel) Buffer *Graphics::newBuffer(const Buffer::Settings &settings, DataFormat format, const void *data, size_t size, size_t arraylength) { std::vector dataformat = {{"", format, 0}}; - return newBuffer(settings, format, data, size, arraylength); + return newBuffer(settings, dataformat, data, size, arraylength); } Mesh *Graphics::newMesh(const std::vector &vertices, PrimitiveType drawmode, BufferUsage usage) diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index e47bc8b65..d598ff198 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -439,7 +439,6 @@ public: ShaderStage *newShaderStage(ShaderStage::StageType stage, const std::string &source); Shader *newShader(const std::string &vertex, const std::string &pixel); - virtual Buffer *newBuffer(const Buffer::Settings &settings, const void *data, size_t size) = 0; virtual Buffer *newBuffer(const Buffer::Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength) = 0; virtual Buffer *newBuffer(const Buffer::Settings &settings, DataFormat format, const void *data, size_t size, size_t arraylength); diff --git a/src/modules/graphics/Mesh.cpp b/src/modules/graphics/Mesh.cpp index 4396842d1..107c11e49 100644 --- a/src/modules/graphics/Mesh.cpp +++ b/src/modules/graphics/Mesh.cpp @@ -344,15 +344,16 @@ void Mesh::setVertexMap(const std::vector &map) size_t maxval = getVertexCount(); IndexDataType datatype = getIndexDataTypeFromMax(maxval); + DataFormat dataformat = getIndexDataFormat(datatype); // Calculate the size in bytes of the index buffer data. size_t size = map.size() * getIndexDataSize(datatype); - if (indexBuffer.get() == nullptr || size > indexBuffer->getSize()) + if (indexBuffer.get() == nullptr || size > indexBuffer->getSize() || indexBuffer->getDataMember(0).decl.format != dataformat) { auto gfx = Module::getInstance(Module::M_GRAPHICS); Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, Buffer::MAP_READ, vertexBuffer->getUsage()); - indexBuffer.set(gfx->newBuffer(settings, nullptr, size), Acquire::NORETAIN); + indexBuffer.set(gfx->newBuffer(settings, dataformat, nullptr, size, 0), Acquire::NORETAIN); } useIndexBuffer = true; @@ -380,11 +381,13 @@ void Mesh::setVertexMap(const std::vector &map) void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasize) { - if (indexBuffer.get() == nullptr || datasize > indexBuffer->getSize()) + DataFormat dataformat = getIndexDataFormat(datatype); + + if (indexBuffer.get() == nullptr || datasize > indexBuffer->getSize() || indexBuffer->getDataMember(0).decl.format != dataformat) { auto gfx = Module::getInstance(Module::M_GRAPHICS); Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, Buffer::MAP_READ, vertexBuffer->getUsage()); - indexBuffer.set(gfx->newBuffer(settings, nullptr, datasize), Acquire::NORETAIN); + indexBuffer.set(gfx->newBuffer(settings, dataformat, nullptr, datasize, 0), Acquire::NORETAIN); } indexCount = datasize / getIndexDataSize(datatype); diff --git a/src/modules/graphics/ParticleSystem.cpp b/src/modules/graphics/ParticleSystem.cpp index 0f8a5aa50..8f1396e2c 100644 --- a/src/modules/graphics/ParticleSystem.cpp +++ b/src/modules/graphics/ParticleSystem.cpp @@ -192,7 +192,8 @@ void ParticleSystem::createBuffers(size_t size) size_t bytes = sizeof(Vertex) * size * 4; Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, 0, BUFFERUSAGE_STREAM); - buffer = gfx->newBuffer(settings, nullptr, bytes); + auto decl = Buffer::getCommonFormatDeclaration(CommonFormat::XYf_STf_RGBAub); + buffer = gfx->newBuffer(settings, decl, nullptr, bytes, 0); } catch (std::bad_alloc &) { diff --git a/src/modules/graphics/SpriteBatch.cpp b/src/modules/graphics/SpriteBatch.cpp index b8a55f298..3553aa7c0 100644 --- a/src/modules/graphics/SpriteBatch.cpp +++ b/src/modules/graphics/SpriteBatch.cpp @@ -65,7 +65,8 @@ SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, BufferUsage size_t vertex_size = vertex_stride * 4 * size; Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, Buffer::MAP_EXPLICIT_RANGE_MODIFY, usage); - array_buf = gfx->newBuffer(settings, nullptr, vertex_size); + auto decl = Buffer::getCommonFormatDeclaration(vertex_format); + array_buf = gfx->newBuffer(settings, decl, nullptr, vertex_size, 0); } SpriteBatch::~SpriteBatch() @@ -220,7 +221,8 @@ void SpriteBatch::setBufferSize(int newsize) { auto gfx = Module::getInstance(Module::M_GRAPHICS); Buffer::Settings settings(array_buf->getTypeFlags(), array_buf->getMapFlags(), array_buf->getUsage()); - new_array_buf = gfx->newBuffer(settings, nullptr, vertex_size); + auto decl = Buffer::getCommonFormatDeclaration(vertex_format); + new_array_buf = gfx->newBuffer(settings, decl, nullptr, vertex_size, 0); // Copy as much of the old data into the new GLBuffer as can fit. size_t copy_size = vertex_stride * 4 * new_next; diff --git a/src/modules/graphics/Text.cpp b/src/modules/graphics/Text.cpp index f9db16d5e..3e2962d39 100644 --- a/src/modules/graphics/Text.cpp +++ b/src/modules/graphics/Text.cpp @@ -62,7 +62,8 @@ void Text::uploadVertices(const std::vector &vertices, size_t auto gfx = Module::getInstance(Module::M_GRAPHICS); Buffer::Settings settings(Buffer::TYPEFLAG_VERTEX, 0, BUFFERUSAGE_DYNAMIC); - Buffer *new_buffer = gfx->newBuffer(settings, nullptr, newsize); + auto decl = Buffer::getCommonFormatDeclaration(Font::vertexFormat); + Buffer *new_buffer = gfx->newBuffer(settings, decl, nullptr, newsize, 0); if (vertex_buffer != nullptr) vertex_buffer->copyTo(0, vertex_buffer->getSize(), new_buffer, 0); diff --git a/src/modules/graphics/opengl/Buffer.cpp b/src/modules/graphics/opengl/Buffer.cpp index 698aa5352..e94048d6d 100644 --- a/src/modules/graphics/opengl/Buffer.cpp +++ b/src/modules/graphics/opengl/Buffer.cpp @@ -35,25 +35,8 @@ namespace graphics namespace opengl { -Buffer::Buffer(const Settings &settings, const void *data, size_t size) - : love::graphics::Buffer(settings, data, size) -{ - initialize(data); -} - Buffer::Buffer(love::graphics::Graphics *gfx, const Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength) - : love::graphics::Buffer(gfx, settings, format, data, size, arraylength) -{ - initialize(data); -} - -Buffer::~Buffer() -{ - unloadVolatile(); - delete[] memoryMap; -} - -void Buffer::initialize(const void *data) + : love::graphics::Buffer(gfx, settings, format, size, arraylength) { if (typeFlags & TYPEFLAG_VERTEX) mapType = BUFFERTYPE_VERTEX; @@ -81,6 +64,12 @@ void Buffer::initialize(const void *data) } } +Buffer::~Buffer() +{ + unloadVolatile(); + delete[] memoryMap; +} + bool Buffer::loadVolatile() { return load(true); diff --git a/src/modules/graphics/opengl/Buffer.h b/src/modules/graphics/opengl/Buffer.h index df74fd982..e3c089ebc 100644 --- a/src/modules/graphics/opengl/Buffer.h +++ b/src/modules/graphics/opengl/Buffer.h @@ -42,7 +42,6 @@ class Buffer final : public love::graphics::Buffer, public Volatile { public: - Buffer(const Settings &settings, const void *data, size_t size); Buffer(love::graphics::Graphics *gfx, const Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength); virtual ~Buffer(); @@ -60,8 +59,6 @@ public: private: - void initialize(const void *data); - bool load(bool restore); void unmapStatic(size_t offset, size_t size); diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 3fba07d52..988b75f79 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -145,11 +145,6 @@ love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage return new Shader(vertex, pixel); } -love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const void *data, size_t size) -{ - return new Buffer(settings, data, size); -} - love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength) { return new Buffer(this, settings, format, data, size, arraylength); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index e40ee702b..d5e2e6bc7 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -60,7 +60,6 @@ public: const char *getName() const override; love::graphics::Texture *newTexture(const Texture::Settings &settings, const Texture::Slices *data = nullptr) override; - love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const void *data, size_t size) override; love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector &format, const void *data, size_t size, size_t arraylength) override; void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;