mirror of
https://github.com/love2d/love.git
synced 2026-08-20 04:30:09 +02:00
Add a variant of Mesh:setVertexMap which takes a Data object, an index data type (“uint16” or “uint32”), and an optional index count. Thanks Shell32!
--HG-- branch : minor
This commit is contained in:
@@ -69,7 +69,7 @@ Mesh::Mesh(const std::vector<AttribFormat> &vertexformat, const void *data, size
|
|||||||
, ibo(nullptr)
|
, ibo(nullptr)
|
||||||
, useIndexBuffer(false)
|
, useIndexBuffer(false)
|
||||||
, elementCount(0)
|
, elementCount(0)
|
||||||
, elementDataType(0)
|
, elementDataType(INDEX_UINT16)
|
||||||
, drawMode(drawmode)
|
, drawMode(drawmode)
|
||||||
, rangeStart(-1)
|
, rangeStart(-1)
|
||||||
, rangeCount(-1)
|
, rangeCount(-1)
|
||||||
@@ -78,7 +78,7 @@ Mesh::Mesh(const std::vector<AttribFormat> &vertexformat, const void *data, size
|
|||||||
calculateAttributeSizes();
|
calculateAttributeSizes();
|
||||||
|
|
||||||
vertexCount = datasize / vertexStride;
|
vertexCount = datasize / vertexStride;
|
||||||
elementDataType = getGLDataTypeFromMax(vertexCount);
|
elementDataType = getIndexTypeFromMax(vertexCount);
|
||||||
|
|
||||||
if (vertexCount == 0)
|
if (vertexCount == 0)
|
||||||
throw love::Exception("Data size is too small for specified vertex attribute formats.");
|
throw love::Exception("Data size is too small for specified vertex attribute formats.");
|
||||||
@@ -96,7 +96,7 @@ Mesh::Mesh(const std::vector<AttribFormat> &vertexformat, int vertexcount, DrawM
|
|||||||
, ibo(nullptr)
|
, ibo(nullptr)
|
||||||
, useIndexBuffer(false)
|
, useIndexBuffer(false)
|
||||||
, elementCount(0)
|
, elementCount(0)
|
||||||
, elementDataType(getGLDataTypeFromMax(vertexcount))
|
, elementDataType(getIndexTypeFromMax(vertexcount))
|
||||||
, drawMode(drawmode)
|
, drawMode(drawmode)
|
||||||
, rangeStart(-1)
|
, rangeStart(-1)
|
||||||
, rangeCount(-1)
|
, rangeCount(-1)
|
||||||
@@ -406,10 +406,10 @@ void Mesh::setVertexMap(const std::vector<uint32> &map)
|
|||||||
{
|
{
|
||||||
size_t maxval = getVertexCount();
|
size_t maxval = getVertexCount();
|
||||||
|
|
||||||
GLenum datatype = getGLDataTypeFromMax(maxval);
|
IndexDataType datatype = getIndexTypeFromMax(maxval);
|
||||||
|
|
||||||
// Calculate the size in bytes of the index buffer data.
|
// Calculate the size in bytes of the index buffer data.
|
||||||
size_t size = map.size() * getGLDataTypeSize(datatype);
|
size_t size = map.size() * vertex::getIndexDataSize(datatype);
|
||||||
|
|
||||||
if (ibo && size > ibo->getSize())
|
if (ibo && size > ibo->getSize())
|
||||||
{
|
{
|
||||||
@@ -431,10 +431,10 @@ void Mesh::setVertexMap(const std::vector<uint32> &map)
|
|||||||
// Fill the buffer with the index values from the vector.
|
// Fill the buffer with the index values from the vector.
|
||||||
switch (datatype)
|
switch (datatype)
|
||||||
{
|
{
|
||||||
case GL_UNSIGNED_SHORT:
|
case INDEX_UINT16:
|
||||||
copyToIndexBuffer<uint16>(map, ibomap, maxval);
|
copyToIndexBuffer<uint16>(map, ibomap, maxval);
|
||||||
break;
|
break;
|
||||||
case GL_UNSIGNED_INT:
|
case INDEX_UINT32:
|
||||||
default:
|
default:
|
||||||
copyToIndexBuffer<uint32>(map, ibomap, maxval);
|
copyToIndexBuffer<uint32>(map, ibomap, maxval);
|
||||||
break;
|
break;
|
||||||
@@ -443,6 +443,29 @@ void Mesh::setVertexMap(const std::vector<uint32> &map)
|
|||||||
elementDataType = datatype;
|
elementDataType = datatype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasize)
|
||||||
|
{
|
||||||
|
if (ibo && datasize > ibo->getSize())
|
||||||
|
{
|
||||||
|
delete ibo;
|
||||||
|
ibo = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ibo && datasize > 0)
|
||||||
|
ibo = new GLBuffer(datasize, nullptr, BUFFER_INDEX, vbo->getUsage());
|
||||||
|
|
||||||
|
elementCount = datasize / vertex::getIndexDataSize(datatype);
|
||||||
|
|
||||||
|
if (!ibo || elementCount == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLBuffer::Mapper ibomap(*ibo);
|
||||||
|
memcpy(ibomap.get(), data, datasize);
|
||||||
|
|
||||||
|
useIndexBuffer = true;
|
||||||
|
elementDataType = datatype;
|
||||||
|
}
|
||||||
|
|
||||||
void Mesh::setVertexMap()
|
void Mesh::setVertexMap()
|
||||||
{
|
{
|
||||||
useIndexBuffer = false;
|
useIndexBuffer = false;
|
||||||
@@ -476,10 +499,10 @@ bool Mesh::getVertexMap(std::vector<uint32> &map) const
|
|||||||
// Fill the vector from the buffer.
|
// Fill the vector from the buffer.
|
||||||
switch (elementDataType)
|
switch (elementDataType)
|
||||||
{
|
{
|
||||||
case GL_UNSIGNED_SHORT:
|
case INDEX_UINT16:
|
||||||
copyFromIndexBuffer<uint16>(buffer, elementCount, map);
|
copyFromIndexBuffer<uint16>(buffer, elementCount, map);
|
||||||
break;
|
break;
|
||||||
case GL_UNSIGNED_INT:
|
case INDEX_UINT32:
|
||||||
default:
|
default:
|
||||||
copyFromIndexBuffer<uint32>(buffer, elementCount, map);
|
copyFromIndexBuffer<uint32>(buffer, elementCount, map);
|
||||||
break;
|
break;
|
||||||
@@ -626,8 +649,9 @@ void Mesh::draw(Graphics *gfx, const Matrix4 &m)
|
|||||||
|
|
||||||
count = std::min(count, (int) elementCount - start);
|
count = std::min(count, (int) elementCount - start);
|
||||||
|
|
||||||
GLenum type = elementDataType;
|
size_t elementsize = vertex::getIndexDataSize(elementDataType);
|
||||||
const void *indices = ibo->getPointer(start * getGLDataTypeSize(type));
|
const void *indices = ibo->getPointer(start * elementsize);
|
||||||
|
GLenum type = OpenGL::getGLIndexDataType(elementDataType);
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
gl.drawElements(getGLDrawMode(drawMode), count, type, indices);
|
gl.drawElements(getGLDrawMode(drawMode), count, type, indices);
|
||||||
@@ -690,27 +714,12 @@ GLenum Mesh::getGLDataType(DataType type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLenum Mesh::getGLDataTypeFromMax(size_t maxvalue)
|
IndexDataType Mesh::getIndexTypeFromMax(size_t maxvalue)
|
||||||
{
|
{
|
||||||
if (maxvalue > LOVE_UINT16_MAX)
|
if (maxvalue > LOVE_UINT16_MAX)
|
||||||
return GL_UNSIGNED_INT;
|
return INDEX_UINT32;
|
||||||
else
|
else
|
||||||
return GL_UNSIGNED_SHORT;
|
return INDEX_UINT16;
|
||||||
}
|
|
||||||
|
|
||||||
size_t Mesh::getGLDataTypeSize(GLenum datatype)
|
|
||||||
{
|
|
||||||
switch (datatype)
|
|
||||||
{
|
|
||||||
case GL_UNSIGNED_BYTE:
|
|
||||||
return sizeof(uint8);
|
|
||||||
case GL_UNSIGNED_SHORT:
|
|
||||||
return sizeof(uint16);
|
|
||||||
case GL_UNSIGNED_INT:
|
|
||||||
return sizeof(uint32);
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mesh::getConstant(const char *in, Mesh::DrawMode &out)
|
bool Mesh::getConstant(const char *in, Mesh::DrawMode &out)
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ public:
|
|||||||
* {0, 1, 2, 3, 4, ...}
|
* {0, 1, 2, 3, 4, ...}
|
||||||
**/
|
**/
|
||||||
void setVertexMap(const std::vector<uint32> &map);
|
void setVertexMap(const std::vector<uint32> &map);
|
||||||
|
void setVertexMap(IndexDataType datatype, const void *data, size_t datasize);
|
||||||
void setVertexMap();
|
void setVertexMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -215,10 +216,10 @@ private:
|
|||||||
|
|
||||||
static size_t getAttribFormatSize(const AttribFormat &format);
|
static size_t getAttribFormatSize(const AttribFormat &format);
|
||||||
|
|
||||||
|
static IndexDataType getIndexTypeFromMax(size_t maxvalue);
|
||||||
|
|
||||||
static GLenum getGLDrawMode(DrawMode mode);
|
static GLenum getGLDrawMode(DrawMode mode);
|
||||||
static GLenum getGLDataType(DataType type);
|
static GLenum getGLDataType(DataType type);
|
||||||
static GLenum getGLDataTypeFromMax(size_t maxvalue);
|
|
||||||
static size_t getGLDataTypeSize(GLenum datatype);
|
|
||||||
|
|
||||||
std::vector<AttribFormat> vertexFormat;
|
std::vector<AttribFormat> vertexFormat;
|
||||||
std::vector<size_t> attributeSizes;
|
std::vector<size_t> attributeSizes;
|
||||||
@@ -238,7 +239,7 @@ private:
|
|||||||
GLBuffer *ibo;
|
GLBuffer *ibo;
|
||||||
bool useIndexBuffer;
|
bool useIndexBuffer;
|
||||||
size_t elementCount;
|
size_t elementCount;
|
||||||
GLenum elementDataType;
|
IndexDataType elementDataType;
|
||||||
|
|
||||||
DrawMode drawMode;
|
DrawMode drawMode;
|
||||||
|
|
||||||
|
|||||||
@@ -379,6 +379,19 @@ GLenum OpenGL::getGLBufferType(BufferType type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLenum OpenGL::getGLIndexDataType(IndexDataType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case INDEX_UINT16:
|
||||||
|
return GL_UNSIGNED_SHORT;
|
||||||
|
case INDEX_UINT32:
|
||||||
|
return GL_UNSIGNED_INT;
|
||||||
|
default:
|
||||||
|
return GL_ZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GLenum OpenGL::getGLBufferUsage(vertex::Usage usage)
|
GLenum OpenGL::getGLBufferUsage(vertex::Usage usage)
|
||||||
{
|
{
|
||||||
switch (usage)
|
switch (usage)
|
||||||
|
|||||||
@@ -361,6 +361,7 @@ public:
|
|||||||
Vendor getVendor() const;
|
Vendor getVendor() const;
|
||||||
|
|
||||||
static GLenum getGLBufferType(BufferType type);
|
static GLenum getGLBufferType(BufferType type);
|
||||||
|
static GLenum getGLIndexDataType(IndexDataType type);
|
||||||
static GLenum getGLBufferUsage(vertex::Usage usage);
|
static GLenum getGLBufferUsage(vertex::Usage usage);
|
||||||
static GLint getGLWrapMode(Texture::WrapMode wmode);
|
static GLint getGLWrapMode(Texture::WrapMode wmode);
|
||||||
|
|
||||||
|
|||||||
@@ -371,6 +371,26 @@ int w_Mesh_setVertexMap(lua_State *L)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (luax_istype(L, 2, Data::type))
|
||||||
|
{
|
||||||
|
Data *d = luax_totype<Data>(L, 2, Data::type);
|
||||||
|
|
||||||
|
const char *indextypestr = luaL_checkstring(L, 3);
|
||||||
|
IndexDataType indextype;
|
||||||
|
if (!vertex::getConstant(indextypestr, indextype))
|
||||||
|
return luaL_error(L, "Invalid index data type: %s", indextypestr);
|
||||||
|
|
||||||
|
size_t datatypesize = vertex::getIndexDataSize(indextype);
|
||||||
|
|
||||||
|
int indexcount = (int) luaL_optnumber(L, 4, d->getSize() / datatypesize);
|
||||||
|
|
||||||
|
if (indexcount < 1 || indexcount * datatypesize > d->getSize())
|
||||||
|
return luaL_error(L, "Invalid index count: %d", indexcount);
|
||||||
|
|
||||||
|
luax_catchexcept(L, [&]() { t->setVertexMap(indextype, d->getData(), indexcount * datatypesize); });
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_table = lua_istable(L, 2);
|
bool is_table = lua_istable(L, 2);
|
||||||
int nargs = is_table ? (int) luax_objlen(L, 2) : lua_gettop(L) - 1;
|
int nargs = is_table ? (int) luax_objlen(L, 2) : lua_gettop(L) - 1;
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,19 @@ size_t getFormatStride(CommonFormat format)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t getIndexDataSize(IndexDataType type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case INDEX_UINT16:
|
||||||
|
return sizeof(uint16);
|
||||||
|
case INDEX_UINT32:
|
||||||
|
return sizeof(uint32);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int getIndexCount(TriangleIndexMode mode, int vertexCount)
|
int getIndexCount(TriangleIndexMode mode, int vertexCount)
|
||||||
{
|
{
|
||||||
switch (mode)
|
switch (mode)
|
||||||
@@ -130,6 +143,14 @@ void fillIndices(TriangleIndexMode mode, uint32 vertexStart, uint32 vertexCount,
|
|||||||
fillIndicesT(mode, vertexStart, vertexCount, indices);
|
fillIndicesT(mode, vertexStart, vertexCount, indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static StringMap<IndexDataType, INDEX_MAX_ENUM>::Entry indexTypeEntries[] =
|
||||||
|
{
|
||||||
|
{ "uint16", INDEX_UINT16 },
|
||||||
|
{ "uint32", INDEX_UINT32 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static StringMap<IndexDataType, INDEX_MAX_ENUM> indexTypes(indexTypeEntries, sizeof(indexTypeEntries));
|
||||||
|
|
||||||
static StringMap<Usage, USAGE_MAX_ENUM>::Entry usageEntries[] =
|
static StringMap<Usage, USAGE_MAX_ENUM>::Entry usageEntries[] =
|
||||||
{
|
{
|
||||||
{ "stream", USAGE_STREAM },
|
{ "stream", USAGE_STREAM },
|
||||||
@@ -139,6 +160,16 @@ static StringMap<Usage, USAGE_MAX_ENUM>::Entry usageEntries[] =
|
|||||||
|
|
||||||
static StringMap<Usage, USAGE_MAX_ENUM> usages(usageEntries, sizeof(usageEntries));
|
static StringMap<Usage, USAGE_MAX_ENUM> usages(usageEntries, sizeof(usageEntries));
|
||||||
|
|
||||||
|
bool getConstant(const char *in, IndexDataType &out)
|
||||||
|
{
|
||||||
|
return indexTypes.find(in, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getConstant(IndexDataType in, const char *&out)
|
||||||
|
{
|
||||||
|
return indexTypes.find(in, out);
|
||||||
|
}
|
||||||
|
|
||||||
bool getConstant(const char *in, Usage &out)
|
bool getConstant(const char *in, Usage &out)
|
||||||
{
|
{
|
||||||
return usages.find(in, out);
|
return usages.find(in, out);
|
||||||
|
|||||||
@@ -58,6 +58,13 @@ enum BufferType
|
|||||||
BUFFER_MAX_ENUM
|
BUFFER_MAX_ENUM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum IndexDataType
|
||||||
|
{
|
||||||
|
INDEX_UINT16,
|
||||||
|
INDEX_UINT32,
|
||||||
|
INDEX_MAX_ENUM
|
||||||
|
};
|
||||||
|
|
||||||
namespace vertex
|
namespace vertex
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -115,12 +122,16 @@ struct XYf_STus_RGBAub
|
|||||||
};
|
};
|
||||||
|
|
||||||
size_t getFormatStride(CommonFormat format);
|
size_t getFormatStride(CommonFormat format);
|
||||||
|
size_t getIndexDataSize(IndexDataType type);
|
||||||
|
|
||||||
int getIndexCount(TriangleIndexMode mode, int vertexCount);
|
int getIndexCount(TriangleIndexMode mode, int vertexCount);
|
||||||
|
|
||||||
void fillIndices(TriangleIndexMode mode, uint16 vertexStart, uint16 vertexCount, uint16 *indices);
|
void fillIndices(TriangleIndexMode mode, uint16 vertexStart, uint16 vertexCount, uint16 *indices);
|
||||||
void fillIndices(TriangleIndexMode mode, uint32 vertexStart, uint32 vertexCount, uint32 *indices);
|
void fillIndices(TriangleIndexMode mode, uint32 vertexStart, uint32 vertexCount, uint32 *indices);
|
||||||
|
|
||||||
|
bool getConstant(const char *in, IndexDataType &out);
|
||||||
|
bool getConstant(IndexDataType in, const char *&out);
|
||||||
|
|
||||||
bool getConstant(const char *in, Usage &out);
|
bool getConstant(const char *in, Usage &out);
|
||||||
bool getConstant(Usage in, const char *&out);
|
bool getConstant(Usage in, const char *&out);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user