mirror of
https://github.com/love2d/love.git
synced 2026-08-14 01:20:56 +02:00
Internal restructuring of some Mesh code
This commit is contained in:
@@ -268,26 +268,21 @@ Buffer *Graphics::newBuffer(const Buffer::Settings &settings, DataFormat format,
|
||||
return newBuffer(settings, dataformat, data, size, arraylength);
|
||||
}
|
||||
|
||||
Mesh *Graphics::newMesh(const std::vector<Vertex> &vertices, PrimitiveType drawmode, BufferUsage usage)
|
||||
{
|
||||
return newMesh(Mesh::getDefaultVertexFormat(), &vertices[0], vertices.size() * sizeof(Vertex), drawmode, usage);
|
||||
}
|
||||
|
||||
Mesh *Graphics::newMesh(int vertexcount, PrimitiveType drawmode, BufferUsage usage)
|
||||
{
|
||||
return newMesh(Mesh::getDefaultVertexFormat(), vertexcount, drawmode, usage);
|
||||
}
|
||||
|
||||
love::graphics::Mesh *Graphics::newMesh(const std::vector<Buffer::DataDeclaration> &vertexformat, int vertexcount, PrimitiveType drawmode, BufferUsage usage)
|
||||
Mesh *Graphics::newMesh(const std::vector<Buffer::DataDeclaration> &vertexformat, int vertexcount, PrimitiveType drawmode, BufferUsage usage)
|
||||
{
|
||||
return new Mesh(this, vertexformat, vertexcount, drawmode, usage);
|
||||
}
|
||||
|
||||
love::graphics::Mesh *Graphics::newMesh(const std::vector<Buffer::DataDeclaration> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferUsage usage)
|
||||
Mesh *Graphics::newMesh(const std::vector<Buffer::DataDeclaration> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferUsage usage)
|
||||
{
|
||||
return new Mesh(this, vertexformat, data, datasize, drawmode, usage);
|
||||
}
|
||||
|
||||
Mesh *Graphics::newMesh(const std::vector<Mesh::BufferAttribute> &attributes, PrimitiveType drawmode)
|
||||
{
|
||||
return new Mesh(attributes, drawmode);
|
||||
}
|
||||
|
||||
love::graphics::Text *Graphics::newText(graphics::Font *font, const std::vector<Font::ColoredString> &text)
|
||||
{
|
||||
return new Text(font, text);
|
||||
|
||||
@@ -442,10 +442,9 @@ public:
|
||||
virtual Buffer *newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &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);
|
||||
|
||||
Mesh *newMesh(const std::vector<Vertex> &vertices, PrimitiveType drawmode, BufferUsage usage);
|
||||
Mesh *newMesh(int vertexcount, PrimitiveType drawmode, BufferUsage usage);
|
||||
Mesh *newMesh(const std::vector<Buffer::DataDeclaration> &vertexformat, int vertexcount, PrimitiveType drawmode, BufferUsage usage);
|
||||
Mesh *newMesh(const std::vector<Buffer::DataDeclaration> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferUsage usage);
|
||||
Mesh *newMesh(const std::vector<Mesh::BufferAttribute> &attributes, PrimitiveType drawmode);
|
||||
|
||||
Text *newText(Font *font, const std::vector<Font::ColoredString> &text = {});
|
||||
|
||||
|
||||
+100
-54
@@ -34,27 +34,13 @@ namespace love
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
static const char *getBuiltinAttribName(BuiltinVertexAttribute attribid)
|
||||
{
|
||||
const char *name = "";
|
||||
getConstant(attribid, name);
|
||||
return name;
|
||||
}
|
||||
|
||||
static_assert(offsetof(Vertex, x) == sizeof(float) * 0, "Incorrect position offset in Vertex struct");
|
||||
static_assert(offsetof(Vertex, s) == sizeof(float) * 2, "Incorrect texture coordinate offset in Vertex struct");
|
||||
static_assert(offsetof(Vertex, color.r) == sizeof(float) * 4, "Incorrect color offset in Vertex struct");
|
||||
|
||||
std::vector<Buffer::DataDeclaration> Mesh::getDefaultVertexFormat()
|
||||
{
|
||||
// Corresponds to the love::Vertex struct.
|
||||
std::vector<Buffer::DataDeclaration> vertexformat = {
|
||||
{ getBuiltinAttribName(ATTRIB_POS), DATAFORMAT_FLOAT_VEC2, 0 },
|
||||
{ getBuiltinAttribName(ATTRIB_TEXCOORD), DATAFORMAT_FLOAT_VEC2, 0 },
|
||||
{ getBuiltinAttribName(ATTRIB_COLOR), DATAFORMAT_UNORM8_VEC4, 0 },
|
||||
};
|
||||
|
||||
return vertexformat;
|
||||
return Buffer::getCommonFormatDeclaration(CommonFormat::XYf_STf_RGBAub);
|
||||
}
|
||||
|
||||
love::Type Mesh::type("Mesh", &Drawable::type);
|
||||
@@ -63,6 +49,7 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector<Buffer::DataDeclaration> &
|
||||
: vertexBuffer(nullptr)
|
||||
, vertexCount(0)
|
||||
, vertexStride(0)
|
||||
, vertexScratchBuffer(nullptr)
|
||||
, indexBuffer(nullptr)
|
||||
, useIndexBuffer(false)
|
||||
, indexCount(0)
|
||||
@@ -89,6 +76,7 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector<Buffer::DataDeclaration> &
|
||||
: vertexBuffer(nullptr)
|
||||
, vertexCount((size_t) vertexcount)
|
||||
, vertexStride(0)
|
||||
, vertexScratchBuffer(nullptr)
|
||||
, indexBuffer(nullptr)
|
||||
, useIndexBuffer(false)
|
||||
, indexCount(0)
|
||||
@@ -115,6 +103,37 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector<Buffer::DataDeclaration> &
|
||||
vertexScratchBuffer = new char[vertexStride];
|
||||
}
|
||||
|
||||
Mesh::Mesh(const std::vector<Mesh::BufferAttribute> &attributes, PrimitiveType drawmode)
|
||||
: vertexBuffer(nullptr)
|
||||
, vertexCount(0)
|
||||
, vertexStride(0)
|
||||
, vertexScratchBuffer(nullptr)
|
||||
, indexBuffer(nullptr)
|
||||
, useIndexBuffer(false)
|
||||
, indexCount(0)
|
||||
, indexDataType(INDEX_UINT16)
|
||||
, primitiveType(drawmode)
|
||||
, rangeStart(-1)
|
||||
, rangeCount(-1)
|
||||
{
|
||||
if (attributes.size() == 0)
|
||||
throw love::Exception("At least one buffer attribute must be specified in this constructor.");
|
||||
|
||||
attachedAttributes = attributes;
|
||||
|
||||
vertexCount = LOVE_UINT32_MAX;
|
||||
|
||||
for (const auto &attrib : attachedAttributes)
|
||||
{
|
||||
if (getAttachedAttributeIndex(attrib.name) != -1)
|
||||
throw love::Exception("Duplicate vertex attribute name: %s", attrib.name.c_str());
|
||||
|
||||
vertexCount = std::min(vertexCount, attrib.buffer->getArrayLength());
|
||||
}
|
||||
|
||||
indexDataType = getIndexDataTypeFromMax(vertexCount);
|
||||
}
|
||||
|
||||
Mesh::~Mesh()
|
||||
{
|
||||
delete vertexScratchBuffer;
|
||||
@@ -126,18 +145,32 @@ void Mesh::setupAttachedAttributes()
|
||||
{
|
||||
const std::string &name = vertexFormat[i].decl.name;
|
||||
|
||||
if (attachedAttributes.find(name) != attachedAttributes.end())
|
||||
if (getAttachedAttributeIndex(name) != -1)
|
||||
throw love::Exception("Duplicate vertex attribute name: %s", name.c_str());
|
||||
|
||||
attachedAttributes[name] = {vertexBuffer, (int) i, STEP_PER_VERTEX, true};
|
||||
attachedAttributes.push_back({name, vertexBuffer, (int) i, STEP_PER_VERTEX, true});
|
||||
}
|
||||
}
|
||||
|
||||
int Mesh::getAttachedAttributeIndex(const std::string &name) const
|
||||
{
|
||||
for (int i = 0; i < (int) attachedAttributes.size(); i++)
|
||||
{
|
||||
if (attachedAttributes[i].name == name)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Mesh::setVertex(size_t vertindex, const void *data, size_t datasize)
|
||||
{
|
||||
if (vertindex >= vertexCount)
|
||||
throw love::Exception("Invalid vertex index: %ld", vertindex + 1);
|
||||
|
||||
if (vertexBuffer.get() == nullptr)
|
||||
throw love::Exception("setVertex can only be called on a Mesh which owns its own vertex buffer.");
|
||||
|
||||
size_t offset = vertindex * vertexStride;
|
||||
size_t size = std::min(datasize, vertexStride);
|
||||
|
||||
@@ -152,6 +185,9 @@ size_t Mesh::getVertex(size_t vertindex, void *data, size_t datasize)
|
||||
if (vertindex >= vertexCount)
|
||||
throw love::Exception("Invalid vertex index: %ld", vertindex + 1);
|
||||
|
||||
if (vertexBuffer.get() == nullptr)
|
||||
throw love::Exception("getVertex can only be called on a Mesh which owns its own vertex buffer.");
|
||||
|
||||
size_t offset = vertindex * vertexStride;
|
||||
size_t size = std::min(datasize, vertexStride);
|
||||
|
||||
@@ -175,6 +211,9 @@ void Mesh::setVertexAttribute(size_t vertindex, int attribindex, const void *dat
|
||||
if (attribindex >= (int) vertexFormat.size())
|
||||
throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1);
|
||||
|
||||
if (vertexBuffer.get() == nullptr)
|
||||
throw love::Exception("setVertexAttribute can only be called on a Mesh which owns its own vertex buffer.");
|
||||
|
||||
const auto &member = vertexFormat[attribindex];
|
||||
|
||||
size_t offset = vertindex * vertexStride + member.offset;
|
||||
@@ -194,6 +233,9 @@ size_t Mesh::getVertexAttribute(size_t vertindex, int attribindex, void *data, s
|
||||
if (attribindex >= (int) vertexFormat.size())
|
||||
throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1);
|
||||
|
||||
if (vertexBuffer.get() == nullptr)
|
||||
throw love::Exception("getVertexAttribute can only be called on a Mesh which owns its own vertex buffer.");
|
||||
|
||||
const auto &member = vertexFormat[attribindex];
|
||||
|
||||
size_t offset = vertindex * vertexStride + member.offset;
|
||||
@@ -239,39 +281,37 @@ int Mesh::getAttributeIndex(const std::string &name) const
|
||||
|
||||
void Mesh::setAttributeEnabled(const std::string &name, bool enable)
|
||||
{
|
||||
auto it = attachedAttributes.find(name);
|
||||
|
||||
if (it == attachedAttributes.end())
|
||||
int index = getAttachedAttributeIndex(name);
|
||||
if (index == -1)
|
||||
throw love::Exception("Mesh does not have an attached vertex attribute named '%s'", name.c_str());
|
||||
|
||||
it->second.enabled = enable;
|
||||
attachedAttributes[index].enabled = enable;
|
||||
}
|
||||
|
||||
bool Mesh::isAttributeEnabled(const std::string &name) const
|
||||
{
|
||||
const auto it = attachedAttributes.find(name);
|
||||
|
||||
if (it == attachedAttributes.end())
|
||||
int index = getAttachedAttributeIndex(name);
|
||||
if (index == -1)
|
||||
throw love::Exception("Mesh does not have an attached vertex attribute named '%s'", name.c_str());
|
||||
|
||||
return it->second.enabled;
|
||||
return attachedAttributes[index].enabled;
|
||||
}
|
||||
|
||||
void Mesh::attachAttribute(const std::string &name, Buffer *buffer, const std::string &attachname, AttributeStep step)
|
||||
{
|
||||
if ((buffer->getTypeFlags() & Buffer::TYPEFLAG_VERTEX) == 0)
|
||||
throw love::Exception("GraphicsBuffer must be created with vertex buffer support to be used as a Mesh vertex attribute.");
|
||||
throw love::Exception("Buffer 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.");
|
||||
|
||||
AttachedAttribute oldattrib = {};
|
||||
AttachedAttribute newattrib = {};
|
||||
BufferAttribute oldattrib = {};
|
||||
BufferAttribute newattrib = {};
|
||||
|
||||
auto it = attachedAttributes.find(name);
|
||||
if (it != attachedAttributes.end())
|
||||
oldattrib = it->second;
|
||||
int oldindex = getAttachedAttributeIndex(name);
|
||||
if (oldindex != -1)
|
||||
oldattrib = attachedAttributes[oldindex];
|
||||
else if (attachedAttributes.size() + 1 > VertexAttributes::MAX)
|
||||
throw love::Exception("A maximum of %d attributes can be attached at once.", VertexAttributes::MAX);
|
||||
|
||||
@@ -283,42 +323,46 @@ void Mesh::attachAttribute(const std::string &name, Buffer *buffer, const std::s
|
||||
if (newattrib.index < 0)
|
||||
throw love::Exception("The specified vertex buffer does not have a vertex attribute named '%s'", attachname.c_str());
|
||||
|
||||
attachedAttributes[name] = newattrib;
|
||||
if (oldindex != -1)
|
||||
attachedAttributes[oldindex] = newattrib;
|
||||
else
|
||||
attachedAttributes.push_back(newattrib);
|
||||
}
|
||||
|
||||
bool Mesh::detachAttribute(const std::string &name)
|
||||
{
|
||||
auto it = attachedAttributes.find(name);
|
||||
int index = getAttachedAttributeIndex(name);
|
||||
if (index == -1)
|
||||
return false;
|
||||
|
||||
if (it != attachedAttributes.end())
|
||||
{
|
||||
attachedAttributes.erase(it);
|
||||
attachedAttributes.erase(attachedAttributes.begin() + index);
|
||||
|
||||
if (getAttributeIndex(name) != -1)
|
||||
attachAttribute(name, vertexBuffer, name);
|
||||
if (getAttributeIndex(name) != -1)
|
||||
attachAttribute(name, vertexBuffer, name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void *Mesh::mapVertexData()
|
||||
{
|
||||
return vertexBuffer->map();
|
||||
return vertexBuffer.get() != nullptr ? vertexBuffer->map() : nullptr;
|
||||
}
|
||||
|
||||
void Mesh::unmapVertexData(size_t modifiedoffset, size_t modifiedsize)
|
||||
{
|
||||
if (!vertexBuffer.get())
|
||||
return;
|
||||
|
||||
vertexBuffer->setMappedRangeModified(modifiedoffset, modifiedsize);
|
||||
vertexBuffer->unmap();
|
||||
}
|
||||
|
||||
void Mesh::flush()
|
||||
{
|
||||
vertexBuffer->unmap();
|
||||
if (vertexBuffer.get())
|
||||
vertexBuffer->unmap();
|
||||
|
||||
if (indexBuffer != nullptr)
|
||||
if (indexBuffer.get())
|
||||
indexBuffer->unmap();
|
||||
}
|
||||
|
||||
@@ -352,7 +396,8 @@ void Mesh::setVertexMap(const std::vector<uint32> &map)
|
||||
if (indexBuffer.get() == nullptr || size > indexBuffer->getSize() || indexBuffer->getDataMember(0).decl.format != dataformat)
|
||||
{
|
||||
auto gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
|
||||
Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, Buffer::MAP_READ, vertexBuffer->getUsage());
|
||||
auto usage = vertexBuffer.get() ? vertexBuffer->getUsage() : BUFFERUSAGE_DYNAMIC;
|
||||
Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, Buffer::MAP_READ, usage);
|
||||
indexBuffer.set(gfx->newBuffer(settings, dataformat, nullptr, size, 0), Acquire::NORETAIN);
|
||||
}
|
||||
|
||||
@@ -386,7 +431,8 @@ void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasiz
|
||||
if (indexBuffer.get() == nullptr || datasize > indexBuffer->getSize() || indexBuffer->getDataMember(0).decl.format != dataformat)
|
||||
{
|
||||
auto gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
|
||||
Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, Buffer::MAP_READ, vertexBuffer->getUsage());
|
||||
auto usage = vertexBuffer.get() ? vertexBuffer->getUsage() : BUFFERUSAGE_DYNAMIC;
|
||||
Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, Buffer::MAP_READ, usage);
|
||||
indexBuffer.set(gfx->newBuffer(settings, dataformat, nullptr, datasize, 0), Acquire::NORETAIN);
|
||||
}
|
||||
|
||||
@@ -529,32 +575,32 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
|
||||
|
||||
for (const auto &attrib : attachedAttributes)
|
||||
{
|
||||
if (!attrib.second.enabled)
|
||||
if (!attrib.enabled)
|
||||
continue;
|
||||
|
||||
Buffer *buffer = attrib.second.buffer.get();
|
||||
Buffer *buffer = attrib.buffer.get();
|
||||
int attributeindex = -1;
|
||||
|
||||
// If the attribute is one of the LOVE-defined ones, use the constant
|
||||
// attribute index for it, otherwise query the index from the shader.
|
||||
BuiltinVertexAttribute builtinattrib;
|
||||
if (getConstant(attrib.first.c_str(), builtinattrib))
|
||||
if (getConstant(attrib.name.c_str(), builtinattrib))
|
||||
attributeindex = (int) builtinattrib;
|
||||
else if (Shader::current)
|
||||
attributeindex = Shader::current->getVertexAttributeIndex(attrib.first);
|
||||
attributeindex = Shader::current->getVertexAttributeIndex(attrib.name);
|
||||
|
||||
if (attributeindex >= 0)
|
||||
{
|
||||
// Make sure the buffer isn't mapped (sends data to GPU if needed.)
|
||||
buffer->unmap();
|
||||
|
||||
const auto &member = buffer->getDataMember(attrib.second.index);
|
||||
const auto &member = buffer->getDataMember(attrib.index);
|
||||
|
||||
uint16 offset = (uint16) buffer->getMemberOffset(attrib.second.index);
|
||||
uint16 offset = (uint16) buffer->getMemberOffset(attrib.index);
|
||||
uint16 stride = (uint16) buffer->getArrayStride();
|
||||
|
||||
attributes.set(attributeindex, member.decl.format, offset, activebuffers);
|
||||
attributes.setBufferLayout(activebuffers, stride, attrib.second.step);
|
||||
attributes.setBufferLayout(activebuffers, stride, attrib.step);
|
||||
|
||||
// TODO: Ideally we want to reuse buffers with the same stride+step.
|
||||
buffers.set(activebuffers, buffer, 0);
|
||||
|
||||
@@ -50,10 +50,20 @@ class Mesh : public Drawable
|
||||
{
|
||||
public:
|
||||
|
||||
struct BufferAttribute
|
||||
{
|
||||
std::string name;
|
||||
StrongRef<Buffer> buffer;
|
||||
int index;
|
||||
AttributeStep step;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
static love::Type type;
|
||||
|
||||
Mesh(Graphics *gfx, const std::vector<Buffer::DataDeclaration> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferUsage usage);
|
||||
Mesh(Graphics *gfx, const std::vector<Buffer::DataDeclaration> &vertexformat, int vertexcount, PrimitiveType drawmode, BufferUsage usage);
|
||||
Mesh(const std::vector<BufferAttribute> &attributes, PrimitiveType drawmode);
|
||||
|
||||
virtual ~Mesh();
|
||||
|
||||
@@ -105,6 +115,7 @@ public:
|
||||
**/
|
||||
void attachAttribute(const std::string &name, Buffer *buffer, const std::string &attachname, AttributeStep step = STEP_PER_VERTEX);
|
||||
bool detachAttribute(const std::string &name);
|
||||
const std::vector<BufferAttribute> &getAttachedAttributes();
|
||||
|
||||
void *mapVertexData();
|
||||
void unmapVertexData(size_t modifiedoffset = 0, size_t modifiedsize = -1);
|
||||
@@ -172,19 +183,12 @@ private:
|
||||
|
||||
friend class SpriteBatch;
|
||||
|
||||
struct AttachedAttribute
|
||||
{
|
||||
StrongRef<Buffer> buffer;
|
||||
int index;
|
||||
AttributeStep step;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
void setupAttachedAttributes();
|
||||
int getAttachedAttributeIndex(const std::string &name) const;
|
||||
|
||||
std::vector<Buffer::DataMember> vertexFormat;
|
||||
|
||||
std::unordered_map<std::string, AttachedAttribute> attachedAttributes;
|
||||
std::vector<BufferAttribute> attachedAttributes;
|
||||
|
||||
// Vertex buffer, for the vertex data.
|
||||
StrongRef<Buffer> vertexBuffer;
|
||||
|
||||
@@ -358,14 +358,6 @@ DEFINE_STRINGMAP_BEGIN(AttributeStep, STEP_MAX_ENUM, attributeStep)
|
||||
}
|
||||
DEFINE_STRINGMAP_END(AttributeStep, STEP_MAX_ENUM, attributeStep)
|
||||
|
||||
DEFINE_STRINGMAP_BEGIN(DataTypeDeprecated, DATADEPRECATED_MAX_ENUM, dataType)
|
||||
{
|
||||
{ "unorm8", DATADEPRECATED_UNORM8 },
|
||||
{ "unorm16", DATADEPRECATED_UNORM16 },
|
||||
{ "float", DATADEPRECATED_FLOAT },
|
||||
}
|
||||
DEFINE_STRINGMAP_END(DataTypeDeprecated, DATADEPRECATED_MAX_ENUM, dataType)
|
||||
|
||||
DEFINE_STRINGMAP_BEGIN(DataFormat, DATAFORMAT_MAX_ENUM, dataFormat)
|
||||
{
|
||||
{ "float", DATAFORMAT_FLOAT },
|
||||
|
||||
@@ -102,14 +102,6 @@ enum BufferUsage
|
||||
BUFFERUSAGE_MAX_ENUM
|
||||
};
|
||||
|
||||
enum DataTypeDeprecated
|
||||
{
|
||||
DATADEPRECATED_UNORM8,
|
||||
DATADEPRECATED_UNORM16,
|
||||
DATADEPRECATED_FLOAT,
|
||||
DATADEPRECATED_MAX_ENUM
|
||||
};
|
||||
|
||||
// Value types used when interfacing with the GPU (vertex and shader data).
|
||||
// The order of this enum affects the dataFormatInfo array.
|
||||
enum DataFormat
|
||||
@@ -387,7 +379,6 @@ DECLARE_STRINGMAP(IndexDataType);
|
||||
DECLARE_STRINGMAP(BufferUsage);
|
||||
DECLARE_STRINGMAP(PrimitiveType);
|
||||
DECLARE_STRINGMAP(AttributeStep);
|
||||
DECLARE_STRINGMAP(DataTypeDeprecated);
|
||||
DECLARE_STRINGMAP(DataFormat);
|
||||
DECLARE_STRINGMAP(DataBaseType);
|
||||
DECLARE_STRINGMAP(CullMode);
|
||||
|
||||
@@ -1557,6 +1557,8 @@ 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();
|
||||
|
||||
// First argument is a table of standard vertices, or the number of
|
||||
// standard vertices.
|
||||
if (lua_istable(L, 1))
|
||||
@@ -1595,12 +1597,12 @@ static Mesh *newStandardMesh(lua_State *L)
|
||||
vertices.push_back(v);
|
||||
}
|
||||
|
||||
luax_catchexcept(L, [&](){ t = instance()->newMesh(vertices, drawmode, usage); });
|
||||
luax_catchexcept(L, [&](){ t = instance()->newMesh(format, vertices.data(), vertices.size() * sizeof(Vertex), drawmode, usage); });
|
||||
}
|
||||
else
|
||||
{
|
||||
int count = (int) luaL_checkinteger(L, 1);
|
||||
luax_catchexcept(L, [&](){ t = instance()->newMesh(count, drawmode, usage); });
|
||||
luax_catchexcept(L, [&](){ t = instance()->newMesh(format, count, drawmode, usage); });
|
||||
}
|
||||
|
||||
return t;
|
||||
@@ -1641,24 +1643,41 @@ static Mesh *newCustomMesh(lua_State *L)
|
||||
|
||||
if (!getConstant(tname, format))
|
||||
{
|
||||
DataTypeDeprecated legacyType = DATADEPRECATED_FLOAT;
|
||||
|
||||
if (strcmp(tname, "byte") == 0) // Legacy name.
|
||||
legacyType = DATADEPRECATED_UNORM8;
|
||||
else if (!getConstant(tname, legacyType))
|
||||
{
|
||||
luax_enumerror(L, "Mesh vertex data format name", getConstants(format), tname);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int components = (int) luaL_checkinteger(L, -1);
|
||||
if (components <= 0 || components > 4)
|
||||
{
|
||||
luaL_error(L, "Number of vertex attribute components must be between 1 and 4 (got %d)", components);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO: convert legacy type+components to new format enum.
|
||||
// Check deprecated format names.
|
||||
if (strcmp(tname, "byte") == 0 || strcmp(tname, "unorm8") == 0)
|
||||
{
|
||||
if (components == 4)
|
||||
format = DATAFORMAT_UNORM8_VEC4;
|
||||
else
|
||||
luaL_error(L, "Invalid component count (%d) for vertex data type %s", components, tname);
|
||||
}
|
||||
else if (strcmp(tname, "unorm16") == 0)
|
||||
{
|
||||
if (components == 2)
|
||||
format = DATAFORMAT_UNORM16_VEC2;
|
||||
else if (components == 4)
|
||||
format = DATAFORMAT_UNORM16_VEC4;
|
||||
else
|
||||
luaL_error(L, "Invalid component count (%d) for vertex data type %s", components, tname);
|
||||
|
||||
}
|
||||
else if (strcmp(tname, "float") == 0)
|
||||
{
|
||||
if (components == 1)
|
||||
format = DATAFORMAT_FLOAT;
|
||||
else if (components == 2)
|
||||
format = DATAFORMAT_FLOAT_VEC2;
|
||||
else if (components == 3)
|
||||
format = DATAFORMAT_FLOAT_VEC3;
|
||||
else if (components == 4)
|
||||
format = DATAFORMAT_FLOAT_VEC4;
|
||||
else
|
||||
luaL_error(L, "Invalid component count (%d) for vertex data type %s", components, tname);
|
||||
}
|
||||
else
|
||||
luax_enumerror(L, "vertex data format", getConstants(format), tname);
|
||||
}
|
||||
|
||||
lua_pop(L, 4);
|
||||
|
||||
Reference in New Issue
Block a user