mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Add Mesh:getAttachedAttributes.
This commit is contained in:
@@ -121,10 +121,13 @@ Mesh::Mesh(const std::vector<Mesh::BufferAttribute> &attributes, PrimitiveType d
|
||||
|
||||
attachedAttributes = attributes;
|
||||
|
||||
vertexCount = LOVE_UINT32_MAX;
|
||||
vertexCount = attachedAttributes.size() > 0 ? LOVE_UINT32_MAX : 0;
|
||||
|
||||
for (const auto &attrib : attachedAttributes)
|
||||
{
|
||||
if ((attrib.buffer->getTypeFlags() & Buffer::TYPEFLAG_VERTEX) == 0)
|
||||
throw love::Exception("Buffer must be created with vertex buffer support to be used as a Mesh vertex attribute.");
|
||||
|
||||
if (getAttachedAttributeIndex(attrib.name) != -1)
|
||||
throw love::Exception("Duplicate vertex attribute name: %s", attrib.name.c_str());
|
||||
|
||||
@@ -268,17 +271,6 @@ const std::vector<Buffer::DataMember> &Mesh::getVertexFormat() const
|
||||
return vertexFormat;
|
||||
}
|
||||
|
||||
int Mesh::getAttributeIndex(const std::string &name) const
|
||||
{
|
||||
for (int i = 0; i < (int) vertexFormat.size(); i++)
|
||||
{
|
||||
if (vertexFormat[i].decl.name == name)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Mesh::setAttributeEnabled(const std::string &name, bool enable)
|
||||
{
|
||||
int index = getAttachedAttributeIndex(name);
|
||||
@@ -317,10 +309,10 @@ void Mesh::attachAttribute(const std::string &name, Buffer *buffer, const std::s
|
||||
|
||||
newattrib.buffer = buffer;
|
||||
newattrib.enabled = oldattrib.buffer.get() ? oldattrib.enabled : true;
|
||||
newattrib.index = buffer->getDataMemberIndex(attachname);
|
||||
newattrib.indexInBuffer = buffer->getDataMemberIndex(attachname);
|
||||
newattrib.step = step;
|
||||
|
||||
if (newattrib.index < 0)
|
||||
if (newattrib.indexInBuffer < 0)
|
||||
throw love::Exception("The specified vertex buffer does not have a vertex attribute named '%s'", attachname.c_str());
|
||||
|
||||
if (oldindex != -1)
|
||||
@@ -337,7 +329,7 @@ bool Mesh::detachAttribute(const std::string &name)
|
||||
|
||||
attachedAttributes.erase(attachedAttributes.begin() + index);
|
||||
|
||||
if (getAttributeIndex(name) != -1)
|
||||
if (vertexBuffer.get() && vertexBuffer->getDataMemberIndex(name) != -1)
|
||||
attachAttribute(name, vertexBuffer, name);
|
||||
|
||||
return true;
|
||||
@@ -594,9 +586,9 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
|
||||
// Make sure the buffer isn't mapped (sends data to GPU if needed.)
|
||||
buffer->unmap();
|
||||
|
||||
const auto &member = buffer->getDataMember(attrib.index);
|
||||
const auto &member = buffer->getDataMember(attrib.indexInBuffer);
|
||||
|
||||
uint16 offset = (uint16) buffer->getMemberOffset(attrib.index);
|
||||
uint16 offset = (uint16) member.offset;
|
||||
uint16 stride = (uint16) buffer->getArrayStride();
|
||||
|
||||
attributes.set(attributeindex, member.decl.format, offset, activebuffers);
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
{
|
||||
std::string name;
|
||||
StrongRef<Buffer> buffer;
|
||||
int index;
|
||||
int indexInBuffer;
|
||||
AttributeStep step;
|
||||
bool enabled;
|
||||
};
|
||||
@@ -101,7 +101,6 @@ public:
|
||||
* Gets the format of each vertex attribute stored in the Mesh.
|
||||
**/
|
||||
const std::vector<Buffer::DataMember> &getVertexFormat() const;
|
||||
int getAttributeIndex(const std::string &name) const;
|
||||
|
||||
/**
|
||||
* Sets whether a specific vertex attribute is used when drawing the Mesh.
|
||||
|
||||
@@ -1557,7 +1557,7 @@ static Mesh *newStandardMesh(lua_State *L)
|
||||
PrimitiveType drawmode = luax_optmeshdrawmode(L, 2, PRIMITIVE_TRIANGLE_FAN);
|
||||
BufferUsage usage = luax_optmeshusage(L, 3, BUFFERUSAGE_DYNAMIC);
|
||||
|
||||
auto format = Mesh::getDefaultVertexFormat();
|
||||
std::vector<Buffer::DataDeclaration> format = Mesh::getDefaultVertexFormat();
|
||||
|
||||
// First argument is a table of standard vertices, or the number of
|
||||
// standard vertices.
|
||||
|
||||
@@ -298,6 +298,8 @@ int w_Mesh_attachAttribute(lua_State *L)
|
||||
{
|
||||
Mesh *mesh = luax_checkmesh(L, 3);
|
||||
buffer = mesh->getVertexBuffer();
|
||||
if (buffer == nullptr)
|
||||
return luaL_error(L, "Mesh does not have its own vertex buffer.");
|
||||
}
|
||||
|
||||
AttributeStep step = STEP_PER_VERTEX;
|
||||
@@ -321,6 +323,41 @@ int w_Mesh_detachAttribute(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Mesh_getAttachedAttributes(lua_State *L)
|
||||
{
|
||||
Mesh *t = luax_checkmesh(L, 1);
|
||||
const auto &attributes = t->getAttachedAttributes();
|
||||
|
||||
lua_createtable(L, (int) attributes.size(), 0);
|
||||
|
||||
for (int i = 0; i < (int) attributes.size(); i++)
|
||||
{
|
||||
const auto &attrib = attributes[i];
|
||||
|
||||
lua_createtable(L, 4, 0);
|
||||
|
||||
luax_pushstring(L, attrib.name);
|
||||
lua_rawseti(L, -1, 1);
|
||||
|
||||
luax_pushtype(L, attrib.buffer.get());
|
||||
lua_rawseti(L, -1, 2);
|
||||
|
||||
const char *stepstr = nullptr;
|
||||
if (!getConstant(attrib.step, stepstr))
|
||||
return luaL_error(L, "Invalid vertex attribute step.");
|
||||
lua_pushstring(L, stepstr);
|
||||
lua_rawseti(L, -1, 3);
|
||||
|
||||
const Buffer::DataMember &member = attrib.buffer->getDataMember(attrib.indexInBuffer);
|
||||
luax_pushstring(L, member.decl.name);
|
||||
lua_rawseti(L, -1, 4);
|
||||
|
||||
lua_rawseti(L, -1, i + 1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int w_Mesh_flush(lua_State *L)
|
||||
{
|
||||
Mesh *t = luax_checkmesh(L, 1);
|
||||
@@ -507,6 +544,7 @@ static const luaL_Reg w_Mesh_functions[] =
|
||||
{ "isAttributeEnabled", w_Mesh_isAttributeEnabled },
|
||||
{ "attachAttribute", w_Mesh_attachAttribute },
|
||||
{ "detachAttribute", w_Mesh_detachAttribute },
|
||||
{ "getAttachedAttributes", w_Mesh_getAttachedAttributes },
|
||||
{ "flush", w_Mesh_flush },
|
||||
{ "setVertexMap", w_Mesh_setVertexMap },
|
||||
{ "getVertexMap", w_Mesh_getVertexMap },
|
||||
|
||||
Reference in New Issue
Block a user