mirror of
https://github.com/love2d/love.git
synced 2026-08-17 02:58:31 +02:00
Cleaned up some vertex data-related code.
--HG-- branch : minor
This commit is contained in:
@@ -217,11 +217,6 @@ ShaderStage *Graphics::newShaderStage(ShaderStage::StageType stage, const std::s
|
||||
return s;
|
||||
}
|
||||
|
||||
void Graphics::cleanupCachedShaderStage(ShaderStage::StageType type, const std::string &hashkey)
|
||||
{
|
||||
cachedShaderStages[type].erase(hashkey);
|
||||
}
|
||||
|
||||
Shader *Graphics::newShader(const std::string &vertex, const std::string &pixel)
|
||||
{
|
||||
if (vertex.empty() && pixel.empty())
|
||||
@@ -233,6 +228,21 @@ Shader *Graphics::newShader(const std::string &vertex, const std::string &pixel)
|
||||
return newShaderInternal(vertexstage.get(), pixelstage.get());
|
||||
}
|
||||
|
||||
Mesh *Graphics::newMesh(const std::vector<Vertex> &vertices, PrimitiveType drawmode, vertex::Usage usage)
|
||||
{
|
||||
return newMesh(Mesh::getDefaultVertexFormat(), &vertices[0], vertices.size() * sizeof(Vertex), drawmode, usage);
|
||||
}
|
||||
|
||||
Mesh *Graphics::newMesh(int vertexcount, PrimitiveType drawmode, vertex::Usage usage)
|
||||
{
|
||||
return newMesh(Mesh::getDefaultVertexFormat(), vertexcount, drawmode, usage);
|
||||
}
|
||||
|
||||
void Graphics::cleanupCachedShaderStage(ShaderStage::StageType type, const std::string &hashkey)
|
||||
{
|
||||
cachedShaderStages[type].erase(hashkey);
|
||||
}
|
||||
|
||||
bool Graphics::validateShader(bool gles, const std::string &vertex, const std::string &pixel, std::string &err)
|
||||
{
|
||||
if (vertex.empty() && pixel.empty())
|
||||
@@ -1040,7 +1050,7 @@ void Graphics::points(const Vector2 *positions, const Colorf *colors, size_t num
|
||||
bool is2D = t.isAffine2DTransform();
|
||||
|
||||
StreamDrawCommand cmd;
|
||||
cmd.primitiveMode = vertex::PrimitiveMode::POINTS;
|
||||
cmd.primitiveMode = PRIMITIVE_POINTS;
|
||||
cmd.formats[0] = vertex::getSinglePositionFormat(is2D);
|
||||
cmd.formats[1] = vertex::CommonFormat::RGBAub;
|
||||
cmd.vertexCount = (int) numpoints;
|
||||
|
||||
@@ -252,7 +252,7 @@ public:
|
||||
|
||||
struct StreamDrawCommand
|
||||
{
|
||||
vertex::PrimitiveMode primitiveMode = vertex::PrimitiveMode::TRIANGLES;
|
||||
PrimitiveType primitiveMode = PRIMITIVE_TRIANGLES;
|
||||
vertex::CommonFormat formats[2];
|
||||
vertex::TriangleIndexMode indexMode = vertex::TriangleIndexMode::NONE;
|
||||
int vertexCount = 0;
|
||||
@@ -391,11 +391,11 @@ public:
|
||||
|
||||
virtual Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) = 0;
|
||||
|
||||
virtual Mesh *newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode drawmode, vertex::Usage usage) = 0;
|
||||
virtual Mesh *newMesh(int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) = 0;
|
||||
Mesh *newMesh(const std::vector<Vertex> &vertices, PrimitiveType drawmode, vertex::Usage usage);
|
||||
Mesh *newMesh(int vertexcount, PrimitiveType drawmode, vertex::Usage usage);
|
||||
|
||||
virtual Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) = 0;
|
||||
virtual Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, Mesh::DrawMode drawmode, vertex::Usage usage) = 0;
|
||||
virtual Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage) = 0;
|
||||
virtual Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage) = 0;
|
||||
|
||||
virtual Text *newText(Font *font, const std::vector<Font::ColoredString> &text = {}) = 0;
|
||||
|
||||
@@ -861,7 +861,7 @@ protected:
|
||||
StreamBuffer *vb[2];
|
||||
StreamBuffer *indexBuffer = nullptr;
|
||||
|
||||
vertex::PrimitiveMode primitiveMode = vertex::PrimitiveMode::TRIANGLES;
|
||||
PrimitiveType primitiveMode = PRIMITIVE_TRIANGLES;
|
||||
vertex::CommonFormat formats[2];
|
||||
StrongRef<Texture> texture;
|
||||
Shader::StandardShader standardShaderType = Shader::STANDARD_DEFAULT;
|
||||
|
||||
+41
-125
@@ -49,9 +49,9 @@ std::vector<Mesh::AttribFormat> Mesh::getDefaultVertexFormat()
|
||||
{
|
||||
// Corresponds to the love::Vertex struct.
|
||||
std::vector<Mesh::AttribFormat> vertexformat = {
|
||||
{getBuiltinAttribName(ATTRIB_POS), Mesh::DATA_FLOAT, 2},
|
||||
{getBuiltinAttribName(ATTRIB_TEXCOORD), Mesh::DATA_FLOAT, 2},
|
||||
{getBuiltinAttribName(ATTRIB_COLOR), Mesh::DATA_BYTE, 4},
|
||||
{ getBuiltinAttribName(ATTRIB_POS), vertex::DATA_FLOAT, 2 },
|
||||
{ getBuiltinAttribName(ATTRIB_TEXCOORD), vertex::DATA_FLOAT, 2 },
|
||||
{ getBuiltinAttribName(ATTRIB_COLOR), vertex::DATA_UNORM8, 4 },
|
||||
};
|
||||
|
||||
return vertexformat;
|
||||
@@ -59,16 +59,16 @@ std::vector<Mesh::AttribFormat> Mesh::getDefaultVertexFormat()
|
||||
|
||||
love::Type Mesh::type("Mesh", &Drawable::type);
|
||||
|
||||
Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, DrawMode drawmode, vertex::Usage usage)
|
||||
Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage)
|
||||
: vertexFormat(vertexformat)
|
||||
, vbo(nullptr)
|
||||
, vertexCount(0)
|
||||
, vertexStride(0)
|
||||
, ibo(nullptr)
|
||||
, useIndexBuffer(false)
|
||||
, elementCount(0)
|
||||
, elementDataType(INDEX_UINT16)
|
||||
, drawMode(drawmode)
|
||||
, indexCount(0)
|
||||
, indexDataType(INDEX_UINT16)
|
||||
, primitiveType(drawmode)
|
||||
, rangeStart(-1)
|
||||
, rangeCount(-1)
|
||||
{
|
||||
@@ -76,7 +76,7 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexforma
|
||||
calculateAttributeSizes();
|
||||
|
||||
vertexCount = datasize / vertexStride;
|
||||
elementDataType = vertex::getIndexDataTypeFromMax(vertexCount);
|
||||
indexDataType = vertex::getIndexDataTypeFromMax(vertexCount);
|
||||
|
||||
if (vertexCount == 0)
|
||||
throw love::Exception("Data size is too small for specified vertex attribute formats.");
|
||||
@@ -86,16 +86,16 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexforma
|
||||
vertexScratchBuffer = new char[vertexStride];
|
||||
}
|
||||
|
||||
Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, DrawMode drawmode, vertex::Usage usage)
|
||||
Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage)
|
||||
: vertexFormat(vertexformat)
|
||||
, vbo(nullptr)
|
||||
, vertexCount((size_t) vertexcount)
|
||||
, vertexStride(0)
|
||||
, ibo(nullptr)
|
||||
, useIndexBuffer(false)
|
||||
, elementCount(0)
|
||||
, elementDataType(vertex::getIndexDataTypeFromMax(vertexcount))
|
||||
, drawMode(drawmode)
|
||||
, indexCount(0)
|
||||
, indexDataType(vertex::getIndexDataTypeFromMax(vertexcount))
|
||||
, primitiveType(drawmode)
|
||||
, rangeStart(-1)
|
||||
, rangeCount(-1)
|
||||
{
|
||||
@@ -149,16 +149,18 @@ void Mesh::calculateAttributeSizes()
|
||||
|
||||
for (const AttribFormat &format : vertexFormat)
|
||||
{
|
||||
// Hardware really doesn't like attributes that aren't 32 bit-aligned.
|
||||
if (format.type == DATA_BYTE && format.components != 4)
|
||||
throw love::Exception("byte vertex attributes must have 4 components.");
|
||||
size_t size = vertex::getDataTypeSize(format.type) * format.components;
|
||||
|
||||
if (format.components <= 0 || format.components > 4)
|
||||
throw love::Exception("Vertex attributes must have between 1 and 4 components.");
|
||||
|
||||
// Hardware really doesn't like attributes that aren't 32 bit-aligned.
|
||||
if (size % 4 != 0)
|
||||
throw love::Exception("Vertex attributes must have enough components to be a multiple of 32 bits.");
|
||||
|
||||
// Total size in bytes of each attribute in a single vertex.
|
||||
attributeSizes.push_back(getAttribFormatSize(format));
|
||||
stride += attributeSizes.back();
|
||||
attributeSizes.push_back(size);
|
||||
stride += size;
|
||||
}
|
||||
|
||||
vertexStride = stride;
|
||||
@@ -258,15 +260,13 @@ const std::vector<Mesh::AttribFormat> &Mesh::getVertexFormat() const
|
||||
return vertexFormat;
|
||||
}
|
||||
|
||||
Mesh::DataType Mesh::getAttributeInfo(int attribindex, int &components) const
|
||||
vertex::DataType Mesh::getAttributeInfo(int attribindex, int &components) const
|
||||
{
|
||||
if (attribindex < 0 || attribindex >= (int) vertexFormat.size())
|
||||
throw love::Exception("Invalid vertex attribute index: %d", attribindex + 1);
|
||||
|
||||
DataType type = vertexFormat[attribindex].type;
|
||||
components = vertexFormat[attribindex].components;
|
||||
|
||||
return type;
|
||||
return vertexFormat[attribindex].type;
|
||||
}
|
||||
|
||||
int Mesh::getAttributeIndex(const std::string &name) const
|
||||
@@ -417,9 +417,9 @@ void Mesh::setVertexMap(const std::vector<uint32> &map)
|
||||
}
|
||||
|
||||
useIndexBuffer = true;
|
||||
elementCount = map.size();
|
||||
indexCount = map.size();
|
||||
|
||||
if (!ibo || elementCount == 0)
|
||||
if (!ibo || indexCount == 0)
|
||||
return;
|
||||
|
||||
Buffer::Mapper ibomap(*ibo);
|
||||
@@ -436,7 +436,7 @@ void Mesh::setVertexMap(const std::vector<uint32> &map)
|
||||
break;
|
||||
}
|
||||
|
||||
elementDataType = datatype;
|
||||
indexDataType = datatype;
|
||||
}
|
||||
|
||||
void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasize)
|
||||
@@ -453,16 +453,16 @@ void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasiz
|
||||
ibo = gfx->newBuffer(datasize, nullptr, BUFFER_INDEX, vbo->getUsage(), Buffer::MAP_READ);
|
||||
}
|
||||
|
||||
elementCount = datasize / vertex::getIndexDataSize(datatype);
|
||||
indexCount = datasize / vertex::getIndexDataSize(datatype);
|
||||
|
||||
if (!ibo || elementCount == 0)
|
||||
if (!ibo || indexCount == 0)
|
||||
return;
|
||||
|
||||
Buffer::Mapper ibomap(*ibo);
|
||||
memcpy(ibomap.get(), data, datasize);
|
||||
|
||||
useIndexBuffer = true;
|
||||
elementDataType = datatype;
|
||||
indexDataType = datatype;
|
||||
}
|
||||
|
||||
void Mesh::setVertexMap()
|
||||
@@ -487,23 +487,23 @@ bool Mesh::getVertexMap(std::vector<uint32> &map) const
|
||||
return false;
|
||||
|
||||
map.clear();
|
||||
map.reserve(elementCount);
|
||||
map.reserve(indexCount);
|
||||
|
||||
if (!ibo || elementCount == 0)
|
||||
if (!ibo || indexCount == 0)
|
||||
return true;
|
||||
|
||||
// We unmap the buffer in Mesh::draw, Mesh::setVertexMap, and Mesh::flush.
|
||||
void *buffer = ibo->map();
|
||||
|
||||
// Fill the vector from the buffer.
|
||||
switch (elementDataType)
|
||||
switch (indexDataType)
|
||||
{
|
||||
case INDEX_UINT16:
|
||||
copyFromIndexBuffer<uint16>(buffer, elementCount, map);
|
||||
copyFromIndexBuffer<uint16>(buffer, indexCount, map);
|
||||
break;
|
||||
case INDEX_UINT32:
|
||||
default:
|
||||
copyFromIndexBuffer<uint32>(buffer, elementCount, map);
|
||||
copyFromIndexBuffer<uint32>(buffer, indexCount, map);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -512,7 +512,7 @@ bool Mesh::getVertexMap(std::vector<uint32> &map) const
|
||||
|
||||
size_t Mesh::getVertexMapCount() const
|
||||
{
|
||||
return elementCount;
|
||||
return indexCount;
|
||||
}
|
||||
|
||||
void Mesh::setTexture(Texture *tex)
|
||||
@@ -530,14 +530,14 @@ Texture *Mesh::getTexture() const
|
||||
return texture.get();
|
||||
}
|
||||
|
||||
void Mesh::setDrawMode(DrawMode mode)
|
||||
void Mesh::setDrawMode(PrimitiveType mode)
|
||||
{
|
||||
drawMode = mode;
|
||||
primitiveType = mode;
|
||||
}
|
||||
|
||||
Mesh::DrawMode Mesh::getDrawMode() const
|
||||
PrimitiveType Mesh::getDrawMode() const
|
||||
{
|
||||
return drawMode;
|
||||
return primitiveType;
|
||||
}
|
||||
|
||||
void Mesh::setDrawRange(int start, int count)
|
||||
@@ -611,7 +611,7 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
|
||||
if (!(enabledattribs & ATTRIBFLAG_POS))
|
||||
throw love::Exception("Mesh must have an enabled VertexPosition attribute to be drawn.");
|
||||
|
||||
bool useindexbuffer = useIndexBuffer && ibo != nullptr && elementCount > 0;
|
||||
bool useindexbuffer = useIndexBuffer && ibo != nullptr && indexCount > 0;
|
||||
|
||||
int start = 0;
|
||||
int count = 0;
|
||||
@@ -621,13 +621,13 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
|
||||
// Make sure the index buffer isn't mapped (sends data to GPU if needed.)
|
||||
ibo->unmap();
|
||||
|
||||
start = std::min(std::max(0, rangeStart), (int) elementCount - 1);
|
||||
start = std::min(std::max(0, rangeStart), (int) indexCount - 1);
|
||||
|
||||
count = (int) elementCount;
|
||||
count = (int) indexCount;
|
||||
if (rangeCount > 0)
|
||||
count = std::min(count, rangeCount);
|
||||
|
||||
count = std::min(count, (int) elementCount - start);
|
||||
count = std::min(count, (int) indexCount - start);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -646,89 +646,5 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
|
||||
drawInternal(start, count, instancecount, useindexbuffer, enabledattribs, instancedattribs);
|
||||
}
|
||||
|
||||
size_t Mesh::getAttribFormatSize(const AttribFormat &format)
|
||||
{
|
||||
switch (format.type)
|
||||
{
|
||||
case DATA_BYTE:
|
||||
return format.components * sizeof(uint8);
|
||||
case DATA_FLOAT:
|
||||
return format.components * sizeof(float);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Mesh::getConstant(const char *in, DrawMode &out)
|
||||
{
|
||||
return drawModes.find(in, out);
|
||||
}
|
||||
|
||||
bool Mesh::getConstant(DrawMode in, const char *&out)
|
||||
{
|
||||
return drawModes.find(in, out);
|
||||
}
|
||||
|
||||
std::vector<std::string> Mesh::getConstants(DrawMode)
|
||||
{
|
||||
return drawModes.getNames();
|
||||
}
|
||||
|
||||
bool Mesh::getConstant(const char *in, DataType &out)
|
||||
{
|
||||
return dataTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool Mesh::getConstant(DataType in, const char *&out)
|
||||
{
|
||||
return dataTypes.find(in, out);
|
||||
}
|
||||
|
||||
std::vector<std::string> Mesh::getConstants(DataType)
|
||||
{
|
||||
return dataTypes.getNames();
|
||||
}
|
||||
|
||||
bool Mesh::getConstant(const char *in, AttributeStep &out)
|
||||
{
|
||||
return attributeSteps.find(in, out);
|
||||
}
|
||||
|
||||
bool Mesh::getConstant(AttributeStep in, const char *&out)
|
||||
{
|
||||
return attributeSteps.find(in, out);
|
||||
}
|
||||
|
||||
std::vector<std::string> Mesh::getConstants(AttributeStep)
|
||||
{
|
||||
return attributeSteps.getNames();
|
||||
}
|
||||
|
||||
StringMap<Mesh::DrawMode, Mesh::DRAWMODE_MAX_ENUM>::Entry Mesh::drawModeEntries[] =
|
||||
{
|
||||
{ "fan", DRAWMODE_FAN },
|
||||
{ "strip", DRAWMODE_STRIP },
|
||||
{ "triangles", DRAWMODE_TRIANGLES },
|
||||
{ "points", DRAWMODE_POINTS },
|
||||
};
|
||||
|
||||
StringMap<Mesh::DrawMode, Mesh::DRAWMODE_MAX_ENUM> Mesh::drawModes(Mesh::drawModeEntries, sizeof(Mesh::drawModeEntries));
|
||||
|
||||
StringMap<Mesh::DataType, Mesh::DATA_MAX_ENUM>::Entry Mesh::dataTypeEntries[] =
|
||||
{
|
||||
{ "byte", DATA_BYTE },
|
||||
{ "float", DATA_FLOAT },
|
||||
};
|
||||
|
||||
StringMap<Mesh::DataType, Mesh::DATA_MAX_ENUM> Mesh::dataTypes(Mesh::dataTypeEntries, sizeof(Mesh::dataTypeEntries));
|
||||
|
||||
StringMap<Mesh::AttributeStep, Mesh::STEP_MAX_ENUM>::Entry Mesh::attributeStepEntries[] =
|
||||
{
|
||||
{ "pervertex", STEP_PER_VERTEX },
|
||||
{ "perinstance", STEP_PER_INSTANCE },
|
||||
};
|
||||
|
||||
StringMap<Mesh::AttributeStep, Mesh::STEP_MAX_ENUM> Mesh::attributeSteps(Mesh::attributeStepEntries, sizeof(Mesh::attributeStepEntries));
|
||||
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
+14
-64
@@ -52,41 +52,15 @@ public:
|
||||
|
||||
static love::Type type;
|
||||
|
||||
// How the Mesh's vertices are used when drawing.
|
||||
// http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png
|
||||
enum DrawMode
|
||||
{
|
||||
DRAWMODE_FAN,
|
||||
DRAWMODE_STRIP,
|
||||
DRAWMODE_TRIANGLES,
|
||||
DRAWMODE_POINTS,
|
||||
DRAWMODE_MAX_ENUM
|
||||
};
|
||||
|
||||
// The type of data a vertex attribute can store.
|
||||
enum DataType
|
||||
{
|
||||
DATA_BYTE,
|
||||
DATA_FLOAT,
|
||||
DATA_MAX_ENUM
|
||||
};
|
||||
|
||||
enum AttributeStep
|
||||
{
|
||||
STEP_PER_VERTEX,
|
||||
STEP_PER_INSTANCE,
|
||||
STEP_MAX_ENUM
|
||||
};
|
||||
|
||||
struct AttribFormat
|
||||
{
|
||||
std::string name;
|
||||
DataType type;
|
||||
vertex::DataType type;
|
||||
int components; // max 4
|
||||
};
|
||||
|
||||
Mesh(Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, DrawMode drawmode, vertex::Usage usage);
|
||||
Mesh(Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, DrawMode drawmode, vertex::Usage usage);
|
||||
Mesh(Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage);
|
||||
Mesh(Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage);
|
||||
|
||||
virtual ~Mesh();
|
||||
|
||||
@@ -122,7 +96,7 @@ public:
|
||||
* Gets the format of each vertex attribute stored in the Mesh.
|
||||
**/
|
||||
const std::vector<AttribFormat> &getVertexFormat() const;
|
||||
DataType getAttributeInfo(int attribindex, int &components) const;
|
||||
vertex::DataType getAttributeInfo(int attribindex, int &components) const;
|
||||
int getAttributeIndex(const std::string &name) const;
|
||||
|
||||
/**
|
||||
@@ -186,8 +160,8 @@ public:
|
||||
/**
|
||||
* Sets the draw mode used when drawing the Mesh.
|
||||
**/
|
||||
void setDrawMode(DrawMode mode);
|
||||
DrawMode getDrawMode() const;
|
||||
void setDrawMode(PrimitiveType mode);
|
||||
PrimitiveType getDrawMode() const;
|
||||
|
||||
void setDrawRange(int start, int count);
|
||||
void setDrawRange();
|
||||
@@ -200,17 +174,7 @@ public:
|
||||
|
||||
void drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount);
|
||||
|
||||
static bool getConstant(const char *in, DrawMode &out);
|
||||
static bool getConstant(DrawMode in, const char *&out);
|
||||
static std::vector<std::string> getConstants(DrawMode);
|
||||
|
||||
static bool getConstant(const char *in, DataType &out);
|
||||
static bool getConstant(DataType in, const char *&out);
|
||||
static std::vector<std::string> getConstants(DataType);
|
||||
|
||||
static bool getConstant(const char *in, AttributeStep &out);
|
||||
static bool getConstant(AttributeStep in, const char *&out);
|
||||
static std::vector<std::string> getConstants(AttributeStep);
|
||||
static std::vector<AttribFormat> getDefaultVertexFormat();
|
||||
|
||||
protected:
|
||||
|
||||
@@ -228,9 +192,6 @@ protected:
|
||||
|
||||
virtual void drawInternal(int start, int count, int instancecount, bool useindexbuffer, uint32 attribflags, uint32 instancedattribflags) const = 0;
|
||||
|
||||
static size_t getAttribFormatSize(const AttribFormat &format);
|
||||
static std::vector<AttribFormat> getDefaultVertexFormat();
|
||||
|
||||
std::vector<AttribFormat> vertexFormat;
|
||||
std::vector<size_t> attributeSizes;
|
||||
|
||||
@@ -245,30 +206,19 @@ protected:
|
||||
// avoid memory allocations when using Mesh::setVertex etc.
|
||||
char *vertexScratchBuffer;
|
||||
|
||||
// Element (vertex index) buffer, for the vertex map.
|
||||
// Index buffer, for the vertex map.
|
||||
Buffer *ibo;
|
||||
bool useIndexBuffer;
|
||||
size_t elementCount;
|
||||
IndexDataType elementDataType;
|
||||
|
||||
DrawMode drawMode;
|
||||
|
||||
size_t indexCount;
|
||||
IndexDataType indexDataType;
|
||||
|
||||
PrimitiveType primitiveType;
|
||||
|
||||
int rangeStart;
|
||||
int rangeCount;
|
||||
|
||||
|
||||
StrongRef<Texture> texture;
|
||||
|
||||
private:
|
||||
|
||||
static StringMap<DrawMode, DRAWMODE_MAX_ENUM>::Entry drawModeEntries[];
|
||||
static StringMap<DrawMode, DRAWMODE_MAX_ENUM> drawModes;
|
||||
|
||||
static StringMap<DataType, DATA_MAX_ENUM>::Entry dataTypeEntries[];
|
||||
static StringMap<DataType, DATA_MAX_ENUM> dataTypes;
|
||||
|
||||
static StringMap<AttributeStep, STEP_MAX_ENUM>::Entry attributeStepEntries[];
|
||||
static StringMap<AttributeStep, STEP_MAX_ENUM> attributeSteps;
|
||||
|
||||
}; // Mesh
|
||||
|
||||
} // graphics
|
||||
|
||||
@@ -161,6 +161,8 @@ public:
|
||||
**/
|
||||
virtual std::string getWarnings() const = 0;
|
||||
|
||||
virtual int getVertexAttributeIndex(const std::string &name) = 0;
|
||||
|
||||
virtual const UniformInfo *getUniformInfo(const std::string &name) const = 0;
|
||||
virtual const UniformInfo *getUniformInfo(BuiltinUniform builtin) const = 0;
|
||||
|
||||
|
||||
@@ -142,22 +142,12 @@ love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, Buffe
|
||||
return new Buffer(size, data, type, usage, mapflags);
|
||||
}
|
||||
|
||||
love::graphics::Mesh *Graphics::newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode drawmode, vertex::Usage usage)
|
||||
{
|
||||
return new Mesh(this, vertices, drawmode, usage);
|
||||
}
|
||||
|
||||
love::graphics::Mesh *Graphics::newMesh(int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage)
|
||||
{
|
||||
return new Mesh(this, vertexcount, drawmode, usage);
|
||||
}
|
||||
|
||||
love::graphics::Mesh *Graphics::newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage)
|
||||
love::graphics::Mesh *Graphics::newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage)
|
||||
{
|
||||
return new Mesh(this, vertexformat, vertexcount, drawmode, usage);
|
||||
}
|
||||
|
||||
love::graphics::Mesh *Graphics::newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, Mesh::DrawMode drawmode, vertex::Usage usage)
|
||||
love::graphics::Mesh *Graphics::newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage)
|
||||
{
|
||||
return new Mesh(this, vertexformat, data, datasize, drawmode, usage);
|
||||
}
|
||||
@@ -387,17 +377,7 @@ void Graphics::flushStreamDraws()
|
||||
if (attribs == 0)
|
||||
return;
|
||||
|
||||
GLenum glmode = GL_ZERO;
|
||||
|
||||
switch (sbstate.primitiveMode)
|
||||
{
|
||||
case PrimitiveMode::TRIANGLES:
|
||||
glmode = GL_TRIANGLES;
|
||||
break;
|
||||
case PrimitiveMode::POINTS:
|
||||
glmode = GL_POINTS;
|
||||
break;
|
||||
}
|
||||
GLenum glprimitivetype = OpenGL::getGLPrimitiveType(sbstate.primitiveMode);
|
||||
|
||||
Colorf nc = gl.getConstantColor();
|
||||
if (attribs & ATTRIBFLAG_COLOR)
|
||||
@@ -419,10 +399,10 @@ void Graphics::flushStreamDraws()
|
||||
|
||||
sbstate.indexBufferMap = StreamBuffer::MapInfo();
|
||||
|
||||
gl.drawElements(glmode, sbstate.indexCount, GL_UNSIGNED_SHORT, BUFFER_OFFSET(offset));
|
||||
gl.drawElements(glprimitivetype, sbstate.indexCount, GL_UNSIGNED_SHORT, BUFFER_OFFSET(offset));
|
||||
}
|
||||
else
|
||||
gl.drawArrays(glmode, 0, sbstate.vertexCount);
|
||||
gl.drawArrays(glprimitivetype, 0, sbstate.vertexCount);
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
@@ -1266,7 +1246,7 @@ void Graphics::setBlendMode(BlendMode mode, BlendAlpha alphamode)
|
||||
|
||||
void Graphics::setPointSize(float size)
|
||||
{
|
||||
if (streamBufferState.primitiveMode == vertex::PrimitiveMode::POINTS)
|
||||
if (streamBufferState.primitiveMode == PRIMITIVE_POINTS)
|
||||
flushStreamDraws();
|
||||
|
||||
gl.setPointSize(size * getCurrentDPIScale());
|
||||
|
||||
@@ -71,11 +71,8 @@ public:
|
||||
|
||||
love::graphics::Buffer *newBuffer(size_t size, const void *data, BufferType type, vertex::Usage usage, uint32 mapflags) override;
|
||||
|
||||
love::graphics::Mesh *newMesh(const std::vector<Vertex> &vertices, Mesh::DrawMode drawmode, vertex::Usage usage) override;
|
||||
love::graphics::Mesh *newMesh(int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) override;
|
||||
|
||||
love::graphics::Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, Mesh::DrawMode drawmode, vertex::Usage usage) override;
|
||||
love::graphics::Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, Mesh::DrawMode drawmode, vertex::Usage usage) override;
|
||||
love::graphics::Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage) override;
|
||||
love::graphics::Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage) override;
|
||||
|
||||
love::graphics::Text *newText(love::graphics::Font *font, const std::vector<Font::ColoredString> &text = {}) override;
|
||||
|
||||
|
||||
@@ -35,26 +35,16 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, DrawMode drawmode, vertex::Usage usage)
|
||||
Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage)
|
||||
: love::graphics::Mesh(gfx, vertexformat, data, datasize, drawmode, usage)
|
||||
{
|
||||
}
|
||||
|
||||
Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, DrawMode drawmode, vertex::Usage usage)
|
||||
Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage)
|
||||
: love::graphics::Mesh(gfx, vertexformat, vertexcount, drawmode, usage)
|
||||
{
|
||||
}
|
||||
|
||||
Mesh::Mesh(graphics::Graphics *gfx, const std::vector<Vertex> &vertices, DrawMode drawmode, vertex::Usage usage)
|
||||
: Mesh(gfx, getDefaultVertexFormat(), &vertices[0], vertices.size() * sizeof(Vertex), drawmode, usage)
|
||||
{
|
||||
}
|
||||
|
||||
Mesh::Mesh(graphics::Graphics *gfx, int vertexcount, DrawMode drawmode, vertex::Usage usage)
|
||||
: Mesh(gfx, getDefaultVertexFormat(), vertexcount, drawmode, usage)
|
||||
{
|
||||
}
|
||||
|
||||
Mesh::~Mesh()
|
||||
{
|
||||
}
|
||||
@@ -71,7 +61,7 @@ int Mesh::bindAttributeToShaderInput(int attributeindex, const std::string &inpu
|
||||
if (vertex::getConstant(inputname.c_str(), builtinattrib))
|
||||
attriblocation = (GLint) builtinattrib;
|
||||
else if (Shader::current)
|
||||
attriblocation = ((Shader *) Shader::current)->getAttribLocation(inputname);
|
||||
attriblocation = Shader::current->getVertexAttributeIndex(inputname);
|
||||
|
||||
// The active shader might not use this vertex attribute name.
|
||||
if (attriblocation < 0)
|
||||
@@ -81,23 +71,11 @@ int Mesh::bindAttributeToShaderInput(int attributeindex, const std::string &inpu
|
||||
vbo->unmap();
|
||||
|
||||
gl.bindBuffer(BUFFER_VERTEX, (GLuint) vbo->getHandle());
|
||||
|
||||
GLenum datatype = 0;
|
||||
switch (format.type)
|
||||
{
|
||||
case DATA_BYTE:
|
||||
datatype = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case DATA_FLOAT:
|
||||
datatype = GL_FLOAT;
|
||||
break;
|
||||
default:
|
||||
datatype = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
GLboolean normalized = GL_FALSE;
|
||||
GLenum datatype = OpenGL::getGLVertexDataType(format.type, normalized);
|
||||
|
||||
const void *gloffset = BUFFER_OFFSET(getAttributeOffset(attributeindex));
|
||||
GLboolean normalized = (datatype == GL_UNSIGNED_BYTE);
|
||||
|
||||
glVertexAttribPointer(attriblocation, format.components, datatype, normalized, (GLsizei) vertexStride, gloffset);
|
||||
|
||||
@@ -111,37 +89,21 @@ void Mesh::drawInternal(int start, int count, int instancecount, bool useindexbu
|
||||
gl.useVertexAttribArrays(attribflags, instancedattribflags);
|
||||
gl.bindTextureToUnit(texture, 0, false);
|
||||
gl.prepareDraw();
|
||||
|
||||
GLenum gldrawmode = GL_TRIANGLES;
|
||||
switch (drawMode)
|
||||
{
|
||||
case DRAWMODE_FAN:
|
||||
gldrawmode = GL_TRIANGLE_FAN;
|
||||
break;
|
||||
case DRAWMODE_STRIP:
|
||||
gldrawmode = GL_TRIANGLE_STRIP;
|
||||
break;
|
||||
case DRAWMODE_TRIANGLES:
|
||||
default:
|
||||
gldrawmode = GL_TRIANGLES;
|
||||
break;
|
||||
case DRAWMODE_POINTS:
|
||||
gldrawmode = GL_POINTS;
|
||||
break;
|
||||
}
|
||||
|
||||
GLenum glprimitivetype = OpenGL::getGLPrimitiveType(primitiveType);
|
||||
|
||||
if (useindexbuffer)
|
||||
{
|
||||
size_t elementsize = vertex::getIndexDataSize(elementDataType);
|
||||
size_t elementsize = vertex::getIndexDataSize(indexDataType);
|
||||
const void *indices = BUFFER_OFFSET(start * elementsize);
|
||||
GLenum type = OpenGL::getGLIndexDataType(elementDataType);
|
||||
GLenum indextype = OpenGL::getGLIndexDataType(indexDataType);
|
||||
|
||||
gl.bindBuffer(BUFFER_INDEX, (GLuint) ibo->getHandle());
|
||||
gl.drawElements(gldrawmode, count, type, indices, instancecount);
|
||||
gl.drawElements(glprimitivetype, count, indextype, indices, instancecount);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.drawArrays(gldrawmode, start, count, instancecount);
|
||||
gl.drawArrays(glprimitivetype, start, count, instancecount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,11 +35,8 @@ class Mesh final : public love::graphics::Mesh
|
||||
{
|
||||
public:
|
||||
|
||||
Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, DrawMode drawmode, vertex::Usage usage);
|
||||
Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, DrawMode drawmode, vertex::Usage usage);
|
||||
|
||||
Mesh(graphics::Graphics *gfx, const std::vector<Vertex> &vertices, DrawMode drawmode, vertex::Usage usage);
|
||||
Mesh(graphics::Graphics *gfx, int vertexcount, DrawMode drawmode, vertex::Usage usage);
|
||||
Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage);
|
||||
Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage);
|
||||
|
||||
virtual ~Mesh();
|
||||
|
||||
|
||||
@@ -504,6 +504,25 @@ void OpenGL::prepareDraw()
|
||||
}
|
||||
}
|
||||
|
||||
GLenum OpenGL::getGLPrimitiveType(PrimitiveType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PRIMITIVE_TRIANGLES:
|
||||
return GL_TRIANGLES;
|
||||
case PRIMITIVE_TRIANGLE_STRIP:
|
||||
return GL_TRIANGLE_STRIP;
|
||||
case PRIMITIVE_TRIANGLE_FAN:
|
||||
return GL_TRIANGLE_FAN;
|
||||
case PRIMITIVE_POINTS:
|
||||
return GL_POINTS;
|
||||
case PRIMITIVE_MAX_ENUM:
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
GLenum OpenGL::getGLBufferType(BufferType type)
|
||||
{
|
||||
switch (type)
|
||||
@@ -551,6 +570,28 @@ GLenum OpenGL::getGLIndexDataType(IndexDataType type)
|
||||
}
|
||||
}
|
||||
|
||||
GLenum OpenGL::getGLVertexDataType(vertex::DataType type, GLboolean &normalized)
|
||||
{
|
||||
normalized = GL_FALSE;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case vertex::DATA_UNORM8:
|
||||
normalized = GL_TRUE;
|
||||
return GL_UNSIGNED_BYTE;
|
||||
case vertex::DATA_UNORM16:
|
||||
normalized = GL_TRUE;
|
||||
return GL_UNSIGNED_SHORT;
|
||||
case vertex::DATA_FLOAT:
|
||||
normalized = GL_FALSE;
|
||||
return GL_FLOAT;
|
||||
case vertex::DATA_MAX_ENUM:
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
GLenum OpenGL::getGLBufferUsage(vertex::Usage usage)
|
||||
{
|
||||
switch (usage)
|
||||
|
||||
@@ -380,8 +380,10 @@ public:
|
||||
**/
|
||||
Vendor getVendor() const;
|
||||
|
||||
static GLenum getGLPrimitiveType(PrimitiveType type);
|
||||
static GLenum getGLBufferType(BufferType type);
|
||||
static GLenum getGLIndexDataType(IndexDataType type);
|
||||
static GLenum getGLVertexDataType(vertex::DataType type, GLboolean &normalized);
|
||||
static GLenum getGLBufferUsage(vertex::Usage usage);
|
||||
static GLenum getGLTextureType(TextureType type);
|
||||
static GLint getGLWrapMode(Texture::WrapMode wmode);
|
||||
|
||||
@@ -669,7 +669,7 @@ ptrdiff_t Shader::getHandle() const
|
||||
return program;
|
||||
}
|
||||
|
||||
GLint Shader::getAttribLocation(const std::string &name)
|
||||
int Shader::getVertexAttributeIndex(const std::string &name)
|
||||
{
|
||||
auto it = attributes.find(name);
|
||||
if (it != attributes.end())
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
// Implements Shader.
|
||||
void attach() override;
|
||||
std::string getWarnings() const override;
|
||||
int getVertexAttributeIndex(const std::string &name) override;
|
||||
const UniformInfo *getUniformInfo(const std::string &name) const override;
|
||||
const UniformInfo *getUniformInfo(BuiltinUniform builtin) const override;
|
||||
void updateUniform(const UniformInfo *info, int count) override;
|
||||
@@ -65,8 +66,6 @@ public:
|
||||
ptrdiff_t getHandle() const override;
|
||||
void setVideoTextures(Texture *ytexture, Texture *cbtexture, Texture *crtexture) override;
|
||||
|
||||
GLint getAttribLocation(const std::string &name);
|
||||
|
||||
void updateScreenParams();
|
||||
void updatePointSize(float size);
|
||||
void updateBuiltinUniforms();
|
||||
|
||||
@@ -124,6 +124,21 @@ size_t getIndexDataSize(IndexDataType type)
|
||||
}
|
||||
}
|
||||
|
||||
size_t getDataTypeSize(DataType datatype)
|
||||
{
|
||||
switch (datatype)
|
||||
{
|
||||
case DATA_UNORM8:
|
||||
return sizeof(uint8);
|
||||
case DATA_UNORM16:
|
||||
return sizeof(uint16);
|
||||
case DATA_FLOAT:
|
||||
return sizeof(float);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
IndexDataType getIndexDataTypeFromMax(size_t maxvalue)
|
||||
{
|
||||
IndexDataType types[] = {INDEX_UINT16, INDEX_UINT32};
|
||||
@@ -234,6 +249,33 @@ static StringMap<Usage, USAGE_MAX_ENUM>::Entry usageEntries[] =
|
||||
|
||||
static StringMap<Usage, USAGE_MAX_ENUM> usages(usageEntries, sizeof(usageEntries));
|
||||
|
||||
static StringMap<PrimitiveType, PRIMITIVE_MAX_ENUM>::Entry primitiveTypeEntries[] =
|
||||
{
|
||||
{ "fan", PRIMITIVE_TRIANGLE_FAN },
|
||||
{ "strip", PRIMITIVE_TRIANGLE_STRIP },
|
||||
{ "triangles", PRIMITIVE_TRIANGLES },
|
||||
{ "points", PRIMITIVE_POINTS },
|
||||
};
|
||||
|
||||
static StringMap<PrimitiveType, PRIMITIVE_MAX_ENUM> primitiveTypes(primitiveTypeEntries, sizeof(primitiveTypeEntries));
|
||||
|
||||
static StringMap<AttributeStep, STEP_MAX_ENUM>::Entry attributeStepEntries[] =
|
||||
{
|
||||
{ "pervertex", STEP_PER_VERTEX },
|
||||
{ "perinstance", STEP_PER_INSTANCE },
|
||||
};
|
||||
|
||||
static StringMap<AttributeStep, STEP_MAX_ENUM> attributeSteps(attributeStepEntries, sizeof(attributeStepEntries));
|
||||
|
||||
static StringMap<DataType, DATA_MAX_ENUM>::Entry dataTypeEntries[] =
|
||||
{
|
||||
{ "byte", DATA_UNORM8 }, // Legacy / more user-friendly name...
|
||||
{ "unorm16", DATA_UNORM16 },
|
||||
{ "float", DATA_FLOAT },
|
||||
};
|
||||
|
||||
static StringMap<DataType, DATA_MAX_ENUM> dataTypes(dataTypeEntries, sizeof(dataTypeEntries));
|
||||
|
||||
bool getConstant(const char *in, VertexAttribID &out)
|
||||
{
|
||||
return attribNames.find(in, out);
|
||||
@@ -274,6 +316,36 @@ std::vector<std::string> getConstants(Usage)
|
||||
return usages.getNames();
|
||||
}
|
||||
|
||||
bool getConstant(const char *in, PrimitiveType &out)
|
||||
{
|
||||
return primitiveTypes.find(in, out);
|
||||
}
|
||||
|
||||
bool getConstant(PrimitiveType in, const char *&out)
|
||||
{
|
||||
return primitiveTypes.find(in, out);
|
||||
}
|
||||
|
||||
std::vector<std::string> getConstants(PrimitiveType)
|
||||
{
|
||||
return primitiveTypes.getNames();
|
||||
}
|
||||
|
||||
bool getConstant(const char *in, AttributeStep &out)
|
||||
{
|
||||
return attributeSteps.find(in, out);
|
||||
}
|
||||
|
||||
bool getConstant(AttributeStep in, const char *&out)
|
||||
{
|
||||
return attributeSteps.find(in, out);
|
||||
}
|
||||
|
||||
std::vector<std::string> getConstants(AttributeStep)
|
||||
{
|
||||
return attributeSteps.getNames();
|
||||
}
|
||||
|
||||
} // vertex
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -67,6 +67,23 @@ enum IndexDataType
|
||||
INDEX_MAX_ENUM
|
||||
};
|
||||
|
||||
// http://escience.anu.edu.au/lecture/cg/surfaceModeling/image/surfaceModeling015.png
|
||||
enum PrimitiveType
|
||||
{
|
||||
PRIMITIVE_TRIANGLES,
|
||||
PRIMITIVE_TRIANGLE_STRIP,
|
||||
PRIMITIVE_TRIANGLE_FAN,
|
||||
PRIMITIVE_POINTS,
|
||||
PRIMITIVE_MAX_ENUM
|
||||
};
|
||||
|
||||
enum AttributeStep
|
||||
{
|
||||
STEP_PER_VERTEX,
|
||||
STEP_PER_INSTANCE,
|
||||
STEP_MAX_ENUM
|
||||
};
|
||||
|
||||
namespace vertex
|
||||
{
|
||||
|
||||
@@ -79,10 +96,12 @@ enum Usage
|
||||
USAGE_MAX_ENUM
|
||||
};
|
||||
|
||||
enum class PrimitiveMode
|
||||
enum DataType
|
||||
{
|
||||
TRIANGLES,
|
||||
POINTS,
|
||||
DATA_UNORM8,
|
||||
DATA_UNORM16,
|
||||
DATA_FLOAT,
|
||||
DATA_MAX_ENUM
|
||||
};
|
||||
|
||||
enum class TriangleIndexMode
|
||||
@@ -165,6 +184,7 @@ inline CommonFormat getSinglePositionFormat(bool is2D)
|
||||
}
|
||||
|
||||
size_t getIndexDataSize(IndexDataType type);
|
||||
size_t getDataTypeSize(DataType datatype);
|
||||
|
||||
IndexDataType getIndexDataTypeFromMax(size_t maxvalue);
|
||||
|
||||
@@ -184,6 +204,18 @@ bool getConstant(const char *in, Usage &out);
|
||||
bool getConstant(Usage in, const char *&out);
|
||||
std::vector<std::string> getConstants(Usage);
|
||||
|
||||
bool getConstant(const char *in, PrimitiveType &out);
|
||||
bool getConstant(PrimitiveType in, const char *&out);
|
||||
std::vector<std::string> getConstants(PrimitiveType);
|
||||
|
||||
bool getConstant(const char *in, AttributeStep &out);
|
||||
bool getConstant(AttributeStep in, const char *&out);
|
||||
std::vector<std::string> getConstants(AttributeStep);
|
||||
|
||||
bool getConstant(const char *in, DataType &out);
|
||||
bool getConstant(DataType in, const char *&out);
|
||||
std::vector<std::string> getConstants(DataType);
|
||||
|
||||
} // vertex
|
||||
|
||||
typedef vertex::XYf_STf_RGBAub Vertex;
|
||||
|
||||
@@ -1408,12 +1408,12 @@ static vertex::Usage luax_optmeshusage(lua_State *L, int idx, vertex::Usage def)
|
||||
return def;
|
||||
}
|
||||
|
||||
static Mesh::DrawMode luax_optmeshdrawmode(lua_State *L, int idx, Mesh::DrawMode def)
|
||||
static PrimitiveType luax_optmeshdrawmode(lua_State *L, int idx, PrimitiveType def)
|
||||
{
|
||||
const char *modestr = lua_isnoneornil(L, idx) ? nullptr : luaL_checkstring(L, idx);
|
||||
|
||||
if (modestr && !Mesh::getConstant(modestr, def))
|
||||
luax_enumerror(L, "mesh draw mode", Mesh::getConstants(def), modestr);
|
||||
if (modestr && !vertex::getConstant(modestr, def))
|
||||
luax_enumerror(L, "mesh draw mode", vertex::getConstants(def), modestr);
|
||||
|
||||
return def;
|
||||
}
|
||||
@@ -1422,7 +1422,7 @@ static Mesh *newStandardMesh(lua_State *L)
|
||||
{
|
||||
Mesh *t = nullptr;
|
||||
|
||||
Mesh::DrawMode drawmode = luax_optmeshdrawmode(L, 2, Mesh::DRAWMODE_FAN);
|
||||
PrimitiveType drawmode = luax_optmeshdrawmode(L, 2, PRIMITIVE_TRIANGLE_FAN);
|
||||
vertex::Usage usage = luax_optmeshusage(L, 3, vertex::USAGE_DYNAMIC);
|
||||
|
||||
// First argument is a table of standard vertices, or the number of
|
||||
@@ -1482,7 +1482,7 @@ static Mesh *newCustomMesh(lua_State *L)
|
||||
// the number of vertices.
|
||||
std::vector<Mesh::AttribFormat> vertexformat;
|
||||
|
||||
Mesh::DrawMode drawmode = luax_optmeshdrawmode(L, 3, Mesh::DRAWMODE_FAN);
|
||||
PrimitiveType drawmode = luax_optmeshdrawmode(L, 3, PRIMITIVE_TRIANGLE_FAN);
|
||||
vertex::Usage usage = luax_optmeshusage(L, 4, vertex::USAGE_DYNAMIC);
|
||||
|
||||
lua_rawgeti(L, 1, 1);
|
||||
@@ -1506,9 +1506,9 @@ static Mesh *newCustomMesh(lua_State *L)
|
||||
format.name = luaL_checkstring(L, -3);
|
||||
|
||||
const char *tname = luaL_checkstring(L, -2);
|
||||
if (!Mesh::getConstant(tname, format.type))
|
||||
if (!vertex::getConstant(tname, format.type))
|
||||
{
|
||||
luax_enumerror(L, "Mesh vertex data type name", Mesh::getConstants(format.type), tname);
|
||||
luax_enumerror(L, "Mesh vertex data type name", vertex::getConstants(format.type), tname);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ Mesh *luax_checkmesh(lua_State *L, int idx)
|
||||
return luax_checktype<Mesh>(L, idx);
|
||||
}
|
||||
|
||||
static inline size_t writeByteData(lua_State *L, int startidx, int components, char *data)
|
||||
static inline size_t writeUnorm8Data(lua_State *L, int startidx, int components, char *data)
|
||||
{
|
||||
uint8 *componentdata = (uint8 *) data;
|
||||
|
||||
@@ -47,6 +47,16 @@ static inline size_t writeByteData(lua_State *L, int startidx, int components, c
|
||||
return sizeof(uint8) * components;
|
||||
}
|
||||
|
||||
static inline size_t writeUnorm16Data(lua_State *L, int startidx, int components, char *data)
|
||||
{
|
||||
uint16 *componentdata = (uint16 *) data;
|
||||
|
||||
for (int i = 0; i < components; i++)
|
||||
componentdata[i] = (uint16) (luaL_optnumber(L, startidx + i, 1.0) * 65535.0);
|
||||
|
||||
return sizeof(uint16) * components;
|
||||
}
|
||||
|
||||
static inline size_t writeFloatData(lua_State *L, int startidx, int components, char *data)
|
||||
{
|
||||
float *componentdata = (float *) data;
|
||||
@@ -57,20 +67,22 @@ static inline size_t writeFloatData(lua_State *L, int startidx, int components,
|
||||
return sizeof(float) * components;
|
||||
}
|
||||
|
||||
char *luax_writeAttributeData(lua_State *L, int startidx, Mesh::DataType type, int components, char *data)
|
||||
char *luax_writeAttributeData(lua_State *L, int startidx, vertex::DataType type, int components, char *data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Mesh::DATA_BYTE:
|
||||
return data + writeByteData(L, startidx, components, data);
|
||||
case Mesh::DATA_FLOAT:
|
||||
case vertex::DATA_UNORM8:
|
||||
return data + writeUnorm8Data(L, startidx, components, data);
|
||||
case vertex::DATA_UNORM16:
|
||||
return data + writeUnorm16Data(L, startidx, components, data);
|
||||
case vertex::DATA_FLOAT:
|
||||
return data + writeFloatData(L, startidx, components, data);
|
||||
default:
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
static inline size_t readByteData(lua_State *L, int components, const char *data)
|
||||
static inline size_t readUnorm8Data(lua_State *L, int components, const char *data)
|
||||
{
|
||||
const uint8 *componentdata = (const uint8 *) data;
|
||||
|
||||
@@ -80,6 +92,16 @@ static inline size_t readByteData(lua_State *L, int components, const char *data
|
||||
return sizeof(uint8) * components;
|
||||
}
|
||||
|
||||
static inline size_t readUnorm16Data(lua_State *L, int components, const char *data)
|
||||
{
|
||||
const uint16 *componentdata = (const uint16 *) data;
|
||||
|
||||
for (int i = 0; i < components; i++)
|
||||
lua_pushnumber(L, (lua_Number) componentdata[i] / 65535.0);
|
||||
|
||||
return sizeof(uint16) * components;
|
||||
}
|
||||
|
||||
static inline size_t readFloatData(lua_State *L, int components, const char *data)
|
||||
{
|
||||
const float *componentdata = (const float *) data;
|
||||
@@ -90,13 +112,15 @@ static inline size_t readFloatData(lua_State *L, int components, const char *dat
|
||||
return sizeof(float) * components;
|
||||
}
|
||||
|
||||
const char *luax_readAttributeData(lua_State *L, Mesh::DataType type, int components, const char *data)
|
||||
const char *luax_readAttributeData(lua_State *L, vertex::DataType type, int components, const char *data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case Mesh::DATA_BYTE:
|
||||
return data + readByteData(L, components, data);
|
||||
case Mesh::DATA_FLOAT:
|
||||
case vertex::DATA_UNORM8:
|
||||
return data + readUnorm8Data(L, components, data);
|
||||
case vertex::DATA_UNORM16:
|
||||
return data + readUnorm16Data(L, components, data);
|
||||
case vertex::DATA_FLOAT:
|
||||
return data + readFloatData(L, components, data);
|
||||
default:
|
||||
return data;
|
||||
@@ -239,7 +263,7 @@ int w_Mesh_setVertexAttribute(lua_State *L)
|
||||
size_t vertindex = (size_t) luaL_checkinteger(L, 2) - 1;
|
||||
int attribindex = (int) luaL_checkinteger(L, 3) - 1;
|
||||
|
||||
Mesh::DataType type;
|
||||
vertex::DataType type;
|
||||
int components;
|
||||
luax_catchexcept(L, [&](){ type = t->getAttributeInfo(attribindex, components); });
|
||||
|
||||
@@ -259,7 +283,7 @@ int w_Mesh_getVertexAttribute(lua_State *L)
|
||||
size_t vertindex = (size_t) luaL_checkinteger(L, 2) - 1;
|
||||
int attribindex = (int) luaL_checkinteger(L, 3) - 1;
|
||||
|
||||
Mesh::DataType type;
|
||||
vertex::DataType type;
|
||||
int components;
|
||||
luax_catchexcept(L, [&](){ type = t->getAttributeInfo(attribindex, components); });
|
||||
|
||||
@@ -290,8 +314,8 @@ int w_Mesh_getVertexFormat(lua_State *L)
|
||||
|
||||
for (size_t i = 0; i < vertexformat.size(); i++)
|
||||
{
|
||||
if (!Mesh::getConstant(vertexformat[i].type, tname))
|
||||
return luax_enumerror(L, "vertex attribute data type", Mesh::getConstants(vertexformat[i].type), tname);
|
||||
if (!vertex::getConstant(vertexformat[i].type, tname))
|
||||
return luax_enumerror(L, "vertex attribute data type", vertex::getConstants(vertexformat[i].type), tname);
|
||||
|
||||
lua_createtable(L, 3, 0);
|
||||
|
||||
@@ -336,10 +360,10 @@ int w_Mesh_attachAttribute(lua_State *L)
|
||||
const char *name = luaL_checkstring(L, 2);
|
||||
Mesh *mesh = luax_checkmesh(L, 3);
|
||||
|
||||
Mesh::AttributeStep step = Mesh::STEP_PER_VERTEX;
|
||||
AttributeStep step = STEP_PER_VERTEX;
|
||||
const char *stepstr = lua_isnoneornil(L, 4) ? nullptr : luaL_checkstring(L, 4);
|
||||
if (stepstr != nullptr && !Mesh::getConstant(stepstr, step))
|
||||
return luax_enumerror(L, "vertex attribute step", Mesh::getConstants(step), stepstr);
|
||||
if (stepstr != nullptr && !vertex::getConstant(stepstr, step))
|
||||
return luax_enumerror(L, "vertex attribute step", vertex::getConstants(step), stepstr);
|
||||
|
||||
const char *attachname = luaL_optstring(L, 5, name);
|
||||
|
||||
@@ -485,10 +509,10 @@ int w_Mesh_setDrawMode(lua_State *L)
|
||||
{
|
||||
Mesh *t = luax_checkmesh(L, 1);
|
||||
const char *str = luaL_checkstring(L, 2);
|
||||
Mesh::DrawMode mode;
|
||||
PrimitiveType mode;
|
||||
|
||||
if (!Mesh::getConstant(str, mode))
|
||||
return luax_enumerror(L, "mesh draw mode", Mesh::getConstants(mode), str);
|
||||
if (!vertex::getConstant(str, mode))
|
||||
return luax_enumerror(L, "mesh draw mode", vertex::getConstants(mode), str);
|
||||
|
||||
t->setDrawMode(mode);
|
||||
return 0;
|
||||
@@ -497,10 +521,10 @@ int w_Mesh_setDrawMode(lua_State *L)
|
||||
int w_Mesh_getDrawMode(lua_State *L)
|
||||
{
|
||||
Mesh *t = luax_checkmesh(L, 1);
|
||||
Mesh::DrawMode mode = t->getDrawMode();
|
||||
PrimitiveType mode = t->getDrawMode();
|
||||
const char *str;
|
||||
|
||||
if (!Mesh::getConstant(mode, str))
|
||||
if (!vertex::getConstant(mode, str))
|
||||
return luaL_error(L, "Unknown mesh draw mode.");
|
||||
|
||||
lua_pushstring(L, str);
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace love
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
char *luax_writeAttributeData(lua_State *L, int startidx, Mesh::DataType type, int components, char *data);
|
||||
const char *luax_readAttributeData(lua_State *L, Mesh::DataType type, int components, const char *data);
|
||||
char *luax_writeAttributeData(lua_State *L, int startidx, vertex::DataType type, int components, char *data);
|
||||
const char *luax_readAttributeData(lua_State *L, vertex::DataType type, int components, const char *data);
|
||||
|
||||
Mesh *luax_checkmesh(lua_State *L, int idx);
|
||||
extern "C" int luaopen_mesh(lua_State *L);
|
||||
|
||||
Reference in New Issue
Block a user