diff --git a/src/modules/graphics/Buffer.cpp b/src/modules/graphics/Buffer.cpp index 53458a6ab..d57416564 100644 --- a/src/modules/graphics/Buffer.cpp +++ b/src/modules/graphics/Buffer.cpp @@ -29,7 +29,9 @@ namespace graphics love::Type Buffer::type("GraphicsBuffer", &Object::type); Buffer::Buffer(size_t size, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags) - : size(size) + : arrayLength(0) + , arrayStride(0) + , size(size) , typeFlags(typeflags) , usage(usage) , mapFlags(mapflags) @@ -37,12 +39,14 @@ Buffer::Buffer(size_t size, BufferTypeFlags typeflags, BufferUsage usage, uint32 { } -Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector &format, size_t arraylength) +Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector &dataMembers, size_t arraylength) : Buffer(0, settings.typeFlags, settings.usage, settings.mapFlags) { - if (format.size() == 0) + if (dataMembers.size() == 0) throw love::Exception("Data format must contain values."); + this->dataMembers = dataMembers; + bool supportsGLSL3 = gfx->getCapabilities().features[Graphics::FEATURE_GLSL3]; bool uniformbuffer = settings.typeFlags & BUFFERFLAG_UNIFORM; @@ -50,13 +54,13 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector 1) + if (indexbuffer && dataMembers.size() > 1) throw love::Exception("test"); size_t offset = 0; size_t stride = 0; - for (const auto &member : format) + for (const auto &member : dataMembers) { DataFormat format = member.format; const DataFormatInfo &info = getDataFormatInfo(format); @@ -85,11 +89,26 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vectorarrayLength = arraylength; + this->arrayStride = stride; + this->size = stride * arraylength; } Buffer::~Buffer() { } +int Buffer::getDataMemberIndex(const std::string &name) const +{ + for (size_t i = 0; i < dataMembers.size(); i++) + { + if (dataMembers[i].name == name) + return (int) i; + } + + return -1; +} + } // graphics } // love diff --git a/src/modules/graphics/Buffer.h b/src/modules/graphics/Buffer.h index 9d16107eb..857444fe0 100644 --- a/src/modules/graphics/Buffer.h +++ b/src/modules/graphics/Buffer.h @@ -69,7 +69,7 @@ public: }; Buffer(size_t size, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags); - Buffer(Graphics *gfx, const Settings &settings, const std::vector &format, size_t arraylength); + Buffer(Graphics *gfx, const Settings &settings, const std::vector &members, size_t arraylength); virtual ~Buffer(); size_t getSize() const { return size; } @@ -78,6 +78,13 @@ public: bool isMapped() const { return mapped; } uint32 getMapFlags() const { return mapFlags; } + size_t getArrayLength() const { return arrayLength; } + size_t getArrayStride() const { return arrayStride; } + const std::vector &getDataMembers() const { return dataMembers; } + const DataMember &getDataMember(int index) const { return dataMembers[index]; } + size_t getMemberOffset(int index) const { return memberOffsets[index]; } + int getDataMemberIndex(const std::string &name) const; + /** * Map the Buffer to client memory. * @@ -138,8 +145,9 @@ public: protected: - std::vector format; + std::vector dataMembers; std::vector memberOffsets; + size_t arrayLength; size_t arrayStride; // The size of the buffer, in bytes. diff --git a/src/modules/graphics/Mesh.cpp b/src/modules/graphics/Mesh.cpp index 913941461..13c7477a4 100644 --- a/src/modules/graphics/Mesh.cpp +++ b/src/modules/graphics/Mesh.cpp @@ -125,8 +125,8 @@ Mesh::~Mesh() for (const auto &attrib : attachedAttributes) { - if (attrib.second.mesh != this) - attrib.second.mesh->release(); + if (attrib.second.buffer != nullptr && attrib.second.buffer != vertexBuffer.get()) + attrib.second.buffer->release(); } } @@ -139,7 +139,7 @@ void Mesh::setupAttachedAttributes() if (attachedAttributes.find(name) != attachedAttributes.end()) throw love::Exception("Duplicate vertex attribute name: %s", name.c_str()); - attachedAttributes[name] = {this, (int) i, STEP_PER_VERTEX, true}; + attachedAttributes[name] = {nullptr, (int) i, STEP_PER_VERTEX, true}; } } @@ -260,6 +260,11 @@ size_t Mesh::getVertexStride() const return vertexStride; } +Buffer *Mesh::getVertexBuffer() const +{ + return vertexBuffer; +} + const std::vector &Mesh::getVertexFormat() const { return vertexFormat; @@ -305,23 +310,15 @@ bool Mesh::isAttributeEnabled(const std::string &name) const return it->second.enabled; } -void Mesh::attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname, AttributeStep step) +void Mesh::attachAttribute(const std::string &name, Buffer *buffer, const std::string &attachname, AttributeStep step) { + if ((buffer->getTypeFlags() & BUFFER_VERTEX) == 0) + throw love::Exception("GraphicsBuffer must be created with vertex buffer support to be used as a Mesh vertex attribute."); + auto gfx = Module::getInstance(Module::M_GRAPHICS); if (step == STEP_PER_INSTANCE && !gfx->getCapabilities().features[Graphics::FEATURE_INSTANCING]) throw love::Exception("Vertex attribute instancing is not supported on this system."); - if (mesh != this) - { - for (const auto &it : mesh->attachedAttributes) - { - // If the supplied Mesh has attached attributes of its own, then we - // prevent it from being attached to avoid reference cycles. - if (it.second.mesh != mesh) - throw love::Exception("Cannot attach a Mesh which has attached Meshes of its own."); - } - } - AttachedAttribute oldattrib = {}; AttachedAttribute newattrib = {}; @@ -331,34 +328,33 @@ void Mesh::attachAttribute(const std::string &name, Mesh *mesh, const std::strin else if (attachedAttributes.size() + 1 > VertexAttributes::MAX) throw love::Exception("A maximum of %d attributes can be attached at once.", VertexAttributes::MAX); - newattrib.mesh = mesh; - newattrib.enabled = oldattrib.mesh ? oldattrib.enabled : true; - newattrib.index = mesh->getAttributeIndex(attachname); + newattrib.buffer = buffer; + newattrib.enabled = oldattrib.buffer ? oldattrib.enabled : true; + newattrib.index = buffer->getDataMemberIndex(attachname); newattrib.step = step; if (newattrib.index < 0) - throw love::Exception("The specified mesh does not have a vertex attribute named '%s'", attachname.c_str()); + throw love::Exception("The specified vertex buffer does not have a vertex attribute named '%s'", attachname.c_str()); - if (newattrib.mesh != this) - newattrib.mesh->retain(); + newattrib.buffer->retain(); attachedAttributes[name] = newattrib; - if (oldattrib.mesh && oldattrib.mesh != this) - oldattrib.mesh->release(); + if (oldattrib.buffer) + oldattrib.buffer->release(); } bool Mesh::detachAttribute(const std::string &name) { auto it = attachedAttributes.find(name); - if (it != attachedAttributes.end() && it->second.mesh != this) + if (it != attachedAttributes.end() && it->second.buffer != vertexBuffer.get()) { - it->second.mesh->release(); + it->second.buffer->release(); attachedAttributes.erase(it); if (getAttributeIndex(name) != -1) - attachAttribute(name, this, name); + attachAttribute(name, vertexBuffer, name); return true; } @@ -590,7 +586,7 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) if (!attrib.second.enabled) continue; - Mesh *mesh = attrib.second.mesh; + Buffer *buffer = attrib.second.buffer; int attributeindex = -1; // If the attribute is one of the LOVE-defined ones, use the constant @@ -604,19 +600,18 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount) if (attributeindex >= 0) { // Make sure the buffer isn't mapped (sends data to GPU if needed.) - mesh->vertexBuffer->unmap(); + buffer->unmap(); - const auto &formats = mesh->getVertexFormat(); - const auto &format = formats[attrib.second.index]; + const auto &member = buffer->getDataMember(attrib.second.index); - uint16 offset = (uint16) mesh->getAttributeOffset(attrib.second.index); - uint16 stride = (uint16) mesh->getVertexStride(); + uint16 offset = (uint16) buffer->getMemberOffset(attrib.second.index); + uint16 stride = (uint16) buffer->getArrayStride(); - attributes.set(attributeindex, format.type, (uint8) format.components, offset, activebuffers); + attributes.set(attributeindex, member.format, offset, activebuffers); attributes.setBufferLayout(activebuffers, stride, attrib.second.step); // TODO: Ideally we want to reuse buffers with the same stride+step. - buffers.set(activebuffers, mesh->vertexBuffer, 0); + buffers.set(activebuffers, buffer, 0); activebuffers++; } } diff --git a/src/modules/graphics/Mesh.h b/src/modules/graphics/Mesh.h index 728dc0993..a0a16bb06 100644 --- a/src/modules/graphics/Mesh.h +++ b/src/modules/graphics/Mesh.h @@ -92,6 +92,8 @@ public: **/ size_t getVertexStride() const; + Buffer *getVertexBuffer() const; + /** * Gets the format of each vertex attribute stored in the Mesh. **/ @@ -106,10 +108,10 @@ public: bool isAttributeEnabled(const std::string &name) const; /** - * Attaches a vertex attribute from another Mesh to this one. The attribute - * will be used when drawing this Mesh. + * Attaches a vertex attribute from another vertex buffer to this Mesh. The + * attribute will be used when drawing this Mesh. **/ - void attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX); + void attachAttribute(const std::string &name, Buffer *buffer, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX); bool detachAttribute(const std::string &name); void *mapVertexData(); @@ -180,7 +182,7 @@ private: struct AttachedAttribute { - Mesh *mesh; + Buffer *buffer; int index; AttributeStep step; bool enabled; diff --git a/src/modules/graphics/SpriteBatch.cpp b/src/modules/graphics/SpriteBatch.cpp index 41da30043..50ee28123 100644 --- a/src/modules/graphics/SpriteBatch.cpp +++ b/src/modules/graphics/SpriteBatch.cpp @@ -244,24 +244,27 @@ int SpriteBatch::getBufferSize() const return size; } -void SpriteBatch::attachAttribute(const std::string &name, Mesh *mesh) +void SpriteBatch::attachAttribute(const std::string &name, Buffer *buffer) { + if ((buffer->getTypeFlags() & BUFFER_VERTEX) == 0) + throw love::Exception("GraphicsBuffer must be created with vertex buffer support to be used as a SpriteBatch vertex attribute."); + AttachedAttribute oldattrib = {}; AttachedAttribute newattrib = {}; - if (mesh->getVertexCount() < (size_t) next * 4) - throw love::Exception("Mesh has too few vertices to be attached to this SpriteBatch (at least %d vertices are required)", next*4); + if (buffer->getArrayLength() < (size_t) next * 4) + throw love::Exception("Buffer has too few vertices to be attached to this SpriteBatch (at least %d vertices are required)", next*4); auto it = attached_attributes.find(name); if (it != attached_attributes.end()) oldattrib = it->second; - newattrib.index = mesh->getAttributeIndex(name); + newattrib.index = buffer->getDataMemberIndex(name); if (newattrib.index < 0) - throw love::Exception("The specified mesh does not have a vertex attribute named '%s'", name.c_str()); + throw love::Exception("The specified Buffer does not have a vertex attribute named '%s'", name.c_str()); - newattrib.mesh = mesh; + newattrib.buffer = buffer; attached_attributes[name] = newattrib; } @@ -327,12 +330,12 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m) for (const auto &it : attached_attributes) { - Mesh *mesh = it.second.mesh.get(); + Buffer *buffer = it.second.buffer.get(); // We have to do this check here as wll because setBufferSize can be // called after attachAttribute. - if (mesh->getVertexCount() < (size_t) next * 4) - throw love::Exception("Mesh with attribute '%s' attached to this SpriteBatch has too few vertices", it.first.c_str()); + if (buffer->getArrayLength() < (size_t) next * 4) + throw love::Exception("Buffer with attribute '%s' attached to this SpriteBatch has too few vertices", it.first.c_str()); int attributeindex = -1; @@ -347,19 +350,18 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m) if (attributeindex >= 0) { // Make sure the buffer isn't mapped (sends data to GPU if needed.) - mesh->vertexBuffer->unmap(); + buffer->unmap(); - const auto &formats = mesh->getVertexFormat(); - const auto &format = formats[it.second.index]; + const auto &member = buffer->getDataMember(it.second.index); - uint16 offset = (uint16) mesh->getAttributeOffset(it.second.index); - uint16 stride = (uint16) mesh->getVertexStride(); + uint16 offset = (uint16) buffer->getMemberOffset(it.second.index); + uint16 stride = (uint16) buffer->getArrayStride(); - attributes.set(attributeindex, format.type, (uint8) format.components, offset, activebuffers); + attributes.set(attributeindex, member.format, offset, activebuffers); attributes.setBufferLayout(activebuffers, stride); // TODO: We should reuse buffer bindings with the same buffer+stride+step. - buffers.set(activebuffers, mesh->vertexBuffer, 0); + buffers.set(activebuffers, buffer, 0); activebuffers++; } } diff --git a/src/modules/graphics/SpriteBatch.h b/src/modules/graphics/SpriteBatch.h index f5b9db48f..40fbfd932 100644 --- a/src/modules/graphics/SpriteBatch.h +++ b/src/modules/graphics/SpriteBatch.h @@ -93,7 +93,7 @@ public: * Attaches a specific vertex attribute from a Mesh to this SpriteBatch. * The vertex attribute will be used when drawing the SpriteBatch. **/ - void attachAttribute(const std::string &name, Mesh *mesh); + void attachAttribute(const std::string &name, Buffer *buffer); void setDrawRange(int start, int count); void setDrawRange(); @@ -106,7 +106,7 @@ private: struct AttachedAttribute { - StrongRef mesh; + StrongRef buffer; int index; }; diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index a2c36d192..620372012 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -631,47 +631,151 @@ GLenum OpenGL::getGLIndexDataType(IndexDataType type) } } -GLenum OpenGL::getGLVertexDataType(DataType type, GLboolean &normalized, bool &intformat) +GLenum OpenGL::getGLVertexDataType(DataFormat format, int &components, GLboolean &normalized, bool &intformat) { normalized = GL_FALSE; intformat = false; + components = 1; - switch (type) + switch (format) { - case DATA_SNORM8: - normalized = GL_TRUE; - return GL_BYTE; - case DATA_UNORM8: - normalized = GL_TRUE; - return GL_UNSIGNED_BYTE; - case DATA_INT8: - intformat = true; - return GL_BYTE; - case DATA_UINT8: - intformat = true; - return GL_UNSIGNED_BYTE; - case DATA_SNORM16: - normalized = GL_TRUE; - return GL_SHORT; - case DATA_UNORM16: - normalized = GL_TRUE; - return GL_UNSIGNED_SHORT; - case DATA_INT16: - intformat = true; - return GL_SHORT; - case DATA_UINT16: - intformat = true; - return GL_UNSIGNED_SHORT; - case DATA_INT32: + case DATAFORMAT_FLOAT: + components = 1; + return GL_FLOAT; + case DATAFORMAT_FLOAT_VEC2: + components = 2; + return GL_FLOAT; + case DATAFORMAT_FLOAT_VEC3: + components = 3; + return GL_FLOAT; + case DATAFORMAT_FLOAT_VEC4: + components = 4; + return GL_FLOAT; + + case DATAFORMAT_FLOAT_MAT2X2: + case DATAFORMAT_FLOAT_MAT2X3: + case DATAFORMAT_FLOAT_MAT2X4: + case DATAFORMAT_FLOAT_MAT3X2: + case DATAFORMAT_FLOAT_MAT3X3: + case DATAFORMAT_FLOAT_MAT3X4: + case DATAFORMAT_FLOAT_MAT4X2: + case DATAFORMAT_FLOAT_MAT4X3: + case DATAFORMAT_FLOAT_MAT4X4: + return GL_ZERO; + + case DATAFORMAT_INT32: + components = 1; intformat = true; return GL_INT; - case DATA_UINT32: + case DATAFORMAT_INT32_VEC2: + components = 2; + intformat = true; + return GL_INT; + case DATAFORMAT_INT32_VEC3: + components = 3; + intformat = true; + return GL_INT; + case DATAFORMAT_INT32_VEC4: + components = 4; + intformat = true; + return GL_INT; + + case DATAFORMAT_UINT32: + components = 1; intformat = true; return GL_UNSIGNED_INT; - case DATA_FLOAT: - normalized = GL_FALSE; - return GL_FLOAT; - case DATA_MAX_ENUM: + case DATAFORMAT_UINT32_VEC2: + components = 2; + intformat = true; + return GL_UNSIGNED_INT; + case DATAFORMAT_UINT32_VEC3: + components = 3; + intformat = true; + return GL_UNSIGNED_INT; + case DATAFORMAT_UINT32_VEC4: + components = 4; + intformat = true; + return GL_UNSIGNED_INT; + + case DATAFORMAT_SNORM8_VEC4: + components = 4; + normalized = GL_TRUE; + return GL_BYTE; + + case DATAFORMAT_UNORM8_VEC4: + components = 4; + normalized = GL_TRUE; + return GL_UNSIGNED_BYTE; + + case DATAFORMAT_INT8_VEC4: + components = 4; + intformat = true; + return GL_BYTE; + + case DATAFORMAT_UINT8_VEC4: + components = 4; + intformat = true; + return GL_UNSIGNED_BYTE; + + case DATAFORMAT_SNORM16: + components = 1; + normalized = GL_TRUE; + return GL_SHORT; + case DATAFORMAT_SNORM16_VEC2: + components = 2; + normalized = GL_TRUE; + return GL_BYTE; + case DATAFORMAT_SNORM16_VEC4: + components = 4; + normalized = GL_TRUE; + return GL_BYTE; + + case DATAFORMAT_UNORM16: + components = 1; + normalized = GL_TRUE; + return GL_UNSIGNED_SHORT; + case DATAFORMAT_UNORM16_VEC2: + components = 2; + normalized = GL_TRUE; + return GL_UNSIGNED_SHORT; + case DATAFORMAT_UNORM16_VEC4: + components = 4; + normalized = GL_TRUE; + return GL_UNSIGNED_SHORT; + + case DATAFORMAT_INT16: + components = 1; + intformat = true; + return GL_SHORT; + case DATAFORMAT_INT16_VEC2: + components = 2; + intformat = true; + return GL_SHORT; + case DATAFORMAT_INT16_VEC4: + components = 4; + intformat = true; + return GL_SHORT; + + case DATAFORMAT_UINT16: + components = 1; + intformat = true; + return GL_UNSIGNED_SHORT; + case DATAFORMAT_UINT16_VEC2: + components = 2; + intformat = true; + return GL_UNSIGNED_SHORT; + case DATAFORMAT_UINT16_VEC4: + components = 4; + intformat = true; + return GL_UNSIGNED_SHORT; + + case DATAFORMAT_BOOL: + case DATAFORMAT_BOOL_VEC2: + case DATAFORMAT_BOOL_VEC3: + case DATAFORMAT_BOOL_VEC4: + return GL_ZERO; + + case DATAFORMAT_MAX_ENUM: return GL_ZERO; } @@ -746,18 +850,19 @@ void OpenGL::setVertexAttributes(const VertexAttributes &attributes, const Buffe if ((state.instancedAttribArrays & bit) ^ divisorbit) glVertexAttribDivisor(i, divisor); + int components = 0; GLboolean normalized = GL_FALSE; bool intformat = false; - GLenum gltype = getGLVertexDataType(attrib.type, normalized, intformat); + GLenum gltype = getGLVertexDataType(attrib.format, components, normalized, intformat); const void *offsetpointer = reinterpret_cast(bufferinfo.offset + attrib.offsetFromVertex); bindBuffer(BUFFER_VERTEX, (GLuint) bufferinfo.buffer->getHandle()); if (intformat) - glVertexAttribIPointer(i, attrib.components, gltype, layout.stride, offsetpointer); + glVertexAttribIPointer(i, components, gltype, layout.stride, offsetpointer); else - glVertexAttribPointer(i, attrib.components, gltype, normalized, layout.stride, offsetpointer); + glVertexAttribPointer(i, components, gltype, normalized, layout.stride, offsetpointer); } i++; diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 264a9fe3b..01faf8a37 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -404,7 +404,7 @@ public: static GLenum getGLPrimitiveType(PrimitiveType type); static GLenum getGLBufferType(BufferType type); static GLenum getGLIndexDataType(IndexDataType type); - static GLenum getGLVertexDataType(DataType type, GLboolean &normalized, bool &intformat); + static GLenum getGLVertexDataType(DataFormat format, int &components, GLboolean &normalized, bool &intformat); static GLenum getGLBufferUsage(BufferUsage usage); static GLenum getGLTextureType(TextureType type); static GLint getGLWrapMode(Texture::WrapMode wmode); diff --git a/src/modules/graphics/vertex.cpp b/src/modules/graphics/vertex.cpp index cfd7acdbb..42ab2f153 100644 --- a/src/modules/graphics/vertex.cpp +++ b/src/modules/graphics/vertex.cpp @@ -309,44 +309,44 @@ void VertexAttributes::setCommonFormat(CommonFormat format, uint8 bufferindex) case CommonFormat::NONE: break; case CommonFormat::XYf: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); + set(ATTRIB_POS, DATAFORMAT_FLOAT_VEC2, 0, bufferindex); break; case CommonFormat::XYZf: - set(ATTRIB_POS, DATA_FLOAT, 3, 0, bufferindex); + set(ATTRIB_POS, DATAFORMAT_FLOAT_VEC3, 0, bufferindex); break; case CommonFormat::RGBAub: - set(ATTRIB_COLOR, DATA_UNORM8, 4, 0, bufferindex); + set(ATTRIB_COLOR, DATAFORMAT_UNORM8_VEC4, 0, bufferindex); break; case CommonFormat::STf_RGBAub: - set(ATTRIB_TEXCOORD, DATA_FLOAT, 2, 0, bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 2), bufferindex); + set(ATTRIB_TEXCOORD, DATAFORMAT_FLOAT_VEC2, 0, bufferindex); + set(ATTRIB_COLOR, DATAFORMAT_UNORM8_VEC4, uint16(sizeof(float) * 2), bufferindex); break; case CommonFormat::STPf_RGBAub: - set(ATTRIB_TEXCOORD, DATA_FLOAT, 3, 0, bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 3), bufferindex); + set(ATTRIB_TEXCOORD, DATAFORMAT_FLOAT_VEC3, 0, bufferindex); + set(ATTRIB_COLOR, DATAFORMAT_UNORM8_VEC4, uint16(sizeof(float) * 3), bufferindex); break; case CommonFormat::XYf_STf: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); - set(ATTRIB_TEXCOORD, DATA_FLOAT, 2, uint16(sizeof(float) * 2), bufferindex); + set(ATTRIB_POS, DATAFORMAT_FLOAT_VEC2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATAFORMAT_FLOAT_VEC2, uint16(sizeof(float) * 2), bufferindex); break; case CommonFormat::XYf_STPf: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); - set(ATTRIB_TEXCOORD, DATA_FLOAT, 3, uint16(sizeof(float) * 2), bufferindex); + set(ATTRIB_POS, DATAFORMAT_FLOAT_VEC2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATAFORMAT_FLOAT_VEC3, uint16(sizeof(float) * 2), bufferindex); break; case CommonFormat::XYf_STf_RGBAub: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); - set(ATTRIB_TEXCOORD, DATA_FLOAT, 2, uint16(sizeof(float) * 2), bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 4), bufferindex); + set(ATTRIB_POS, DATAFORMAT_FLOAT_VEC2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATAFORMAT_FLOAT_VEC2, uint16(sizeof(float) * 2), bufferindex); + set(ATTRIB_COLOR, DATAFORMAT_UNORM8_VEC4, uint16(sizeof(float) * 4), bufferindex); break; case CommonFormat::XYf_STus_RGBAub: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); - set(ATTRIB_TEXCOORD, DATA_UNORM16, 2, uint16(sizeof(float) * 2), bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 2 + sizeof(uint16) * 2), bufferindex); + set(ATTRIB_POS, DATAFORMAT_FLOAT_VEC2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATAFORMAT_UNORM16_VEC2, uint16(sizeof(float) * 2), bufferindex); + set(ATTRIB_COLOR, DATAFORMAT_UNORM8_VEC4, uint16(sizeof(float) * 2 + sizeof(uint16) * 2), bufferindex); break; case CommonFormat::XYf_STPf_RGBAub: - set(ATTRIB_POS, DATA_FLOAT, 2, 0, bufferindex); - set(ATTRIB_TEXCOORD, DATA_FLOAT, 3, uint16(sizeof(float) * 2), bufferindex); - set(ATTRIB_COLOR, DATA_UNORM8, 4, uint16(sizeof(float) * 5), bufferindex); + set(ATTRIB_POS, DATAFORMAT_FLOAT_VEC2, 0, bufferindex); + set(ATTRIB_TEXCOORD, DATAFORMAT_FLOAT_VEC3, uint16(sizeof(float) * 2), bufferindex); + set(ATTRIB_COLOR, DATAFORMAT_UNORM8_VEC4, uint16(sizeof(float) * 5), bufferindex); break; } } diff --git a/src/modules/graphics/vertex.h b/src/modules/graphics/vertex.h index ded03f536..aacd0f53f 100644 --- a/src/modules/graphics/vertex.h +++ b/src/modules/graphics/vertex.h @@ -320,8 +320,7 @@ struct BufferBindings struct VertexAttributeInfo { uint8 bufferIndex; - DataType type : 4; - uint8 components : 4; + DataFormat format : 8; uint16 offsetFromVertex; }; @@ -346,13 +345,12 @@ struct VertexAttributes setCommonFormat(format, bufferindex); } - void set(uint32 index, DataType type, uint8 components, uint16 offsetfromvertex, uint8 bufferindex) + void set(uint32 index, DataFormat format, uint16 offsetfromvertex, uint8 bufferindex) { enableBits |= (1u << index); attribs[index].bufferIndex = bufferindex; - attribs[index].type = type; - attribs[index].components = components; + attribs[index].format = format; attribs[index].offsetFromVertex = offsetfromvertex; } diff --git a/src/modules/graphics/wrap_Mesh.cpp b/src/modules/graphics/wrap_Mesh.cpp index 2902dd5ed..8bad4cbfa 100644 --- a/src/modules/graphics/wrap_Mesh.cpp +++ b/src/modules/graphics/wrap_Mesh.cpp @@ -416,7 +416,17 @@ int w_Mesh_attachAttribute(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); const char *name = luaL_checkstring(L, 2); - Mesh *mesh = luax_checkmesh(L, 3); + + Buffer *buffer = nullptr; + if (luax_istype(L, 3, Buffer::type)) + { + buffer = luax_checktype(L, 3); + } + else + { + Mesh *mesh = luax_checkmesh(L, 3); + buffer = mesh->getVertexBuffer(); + } AttributeStep step = STEP_PER_VERTEX; const char *stepstr = lua_isnoneornil(L, 4) ? nullptr : luaL_checkstring(L, 4); @@ -425,7 +435,7 @@ int w_Mesh_attachAttribute(lua_State *L) const char *attachname = luaL_optstring(L, 5, name); - luax_catchexcept(L, [&](){ t->attachAttribute(name, mesh, attachname, step); }); + luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer, attachname, step); }); return 0; } diff --git a/src/modules/graphics/wrap_SpriteBatch.cpp b/src/modules/graphics/wrap_SpriteBatch.cpp index 7986f042e..598c45d7a 100644 --- a/src/modules/graphics/wrap_SpriteBatch.cpp +++ b/src/modules/graphics/wrap_SpriteBatch.cpp @@ -226,9 +226,19 @@ int w_SpriteBatch_attachAttribute(lua_State *L) { SpriteBatch *t = luax_checkspritebatch(L, 1); const char *name = luaL_checkstring(L, 2); - Mesh *m = luax_checktype(L, 3); - luax_catchexcept(L, [&](){ t->attachAttribute(name, m); }); + Buffer *buffer = nullptr; + if (luax_istype(L, 3, Buffer::type)) + { + buffer = luax_checktype(L, 3); + } + else + { + Mesh *mesh = luax_checktype(L, 3); + buffer = mesh->getVertexBuffer(); + } + + luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer); }); return 0; }