Cleaned up some vertex data-related code.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2017-10-22 12:33:47 -03:00
parent 4f8e04d391
commit 7a2e52b12d
18 changed files with 308 additions and 324 deletions
+16 -6
View File
@@ -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;
+6 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
+2
View File
@@ -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;
+6 -26
View File
@@ -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());
+2 -5
View File
@@ -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;
+12 -50
View File
@@ -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);
}
}
+2 -5
View File
@@ -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();
+41
View File
@@ -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)
+2
View File
@@ -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);
+1 -1
View File
@@ -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())
+1 -2
View File
@@ -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();
+72
View File
@@ -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
+35 -3
View File
@@ -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;
+7 -7
View File
@@ -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;
}
+46 -22
View File
@@ -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);
+2 -2
View File
@@ -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);