Meshes expose vertex buffers, part 1

(compiles, but is currently half-implemented and broken)
This commit is contained in:
Alex Szpakowski
2020-01-19 15:03:19 -04:00
parent 816f132c9d
commit 25d9ae2ba0
12 changed files with 277 additions and 128 deletions
+24 -5
View File
@@ -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<DataMember> &format, size_t arraylength)
Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataMember> &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<DataMe
bool vertexbuffer = settings.typeFlags & BUFFERFLAG_VERTEX;
bool ssbuffer = settings.typeFlags & BUFFERFLAG_SHADER_STORAGE;
if (indexbuffer && format.size() > 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::vector<DataMe
throw love::Exception("");
}
}
this->arrayLength = 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
+10 -2
View File
@@ -69,7 +69,7 @@ public:
};
Buffer(size_t size, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags);
Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataMember> &format, size_t arraylength);
Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataMember> &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<DataMember> &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<DataMember> format;
std::vector<DataMember> dataMembers;
std::vector<size_t> memberOffsets;
size_t arrayLength;
size_t arrayStride;
// The size of the buffer, in bytes.
+29 -34
View File
@@ -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::AttribFormat> &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<Graphics>(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++;
}
}
+6 -4
View File
@@ -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;
+18 -16
View File
@@ -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++;
}
}
+2 -2
View File
@@ -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> mesh;
StrongRef<Buffer> buffer;
int index;
};
+140 -35
View File
@@ -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<void*>(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++;
+1 -1
View File
@@ -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);
+20 -20
View File
@@ -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;
}
}
+3 -5
View File
@@ -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;
}
+12 -2
View File
@@ -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<Buffer>(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;
}
+12 -2
View File
@@ -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<Mesh>(L, 3);
luax_catchexcept(L, [&](){ t->attachAttribute(name, m); });
Buffer *buffer = nullptr;
if (luax_istype(L, 3, Buffer::type))
{
buffer = luax_checktype<Buffer>(L, 3);
}
else
{
Mesh *mesh = luax_checktype<Mesh>(L, 3);
buffer = mesh->getVertexBuffer();
}
luax_catchexcept(L, [&](){ t->attachAttribute(name, buffer); });
return 0;
}