Browse Source

Remove vertex namespace

Alex Szpakowski 5 years ago
parent
commit
ee5304ba53

+ 37 - 4
src/modules/graphics/Buffer.cpp

@@ -26,7 +26,16 @@ namespace love
 namespace graphics
 {
 
-Buffer::Buffer(size_t size, BufferTypeFlags typeflags, vertex::Usage usage, uint32 mapflags)
+static const Buffer::DataTypeInfo dataTypeInfo[]
+{
+	// baseType, isMatrix, components, rows, columns, componentSize, packedAlign, packedSize
+	{ Buffer::DATA_BASE_FLOAT, false, 1, 0, 0, sizeof(float), 4, 4 }, // DATA_FLOAT
+
+};
+
+love::Type Buffer::type("GraphicsBuffer", &Object::type);
+
+Buffer::Buffer(size_t size, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags)
 	: size(size)
 	, typeFlags(typeflags)
 	, usage(usage)
@@ -38,6 +47,11 @@ Buffer::Buffer(size_t size, BufferTypeFlags typeflags, vertex::Usage usage, uint
 Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataMember> &format, size_t arraylength)
 	: Buffer(0, settings.typeFlags, settings.usage, settings.mapFlags)
 {
+	if (format.size() == 0)
+		throw love::Exception("Data format must contain values.");
+
+	bool supportsGLSL3 = gfx->getCapabilities().features[Graphics::FEATURE_GLSL3];
+
 	bool uniformbuffer = settings.typeFlags & BUFFERFLAG_UNIFORM;
 	bool indexbuffer = settings.typeFlags & BUFFERFLAG_INDEX;
 	bool vertexbuffer = settings.typeFlags & BUFFERFLAG_VERTEX;
@@ -46,17 +60,36 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataMe
 	if (indexbuffer && format.size() > 1)
 		throw love::Exception("test");
 
+	size_t offset = 0;
+	size_t stride = 0;
+
 	for (const auto &member : format)
 	{
+		DataType type = member.type;
+		const DataTypeInfo &info = getDataTypeInfo(type);
+
 		if (indexbuffer)
 		{
-			if (member.type != DATA_UINT16 && member.type != DATA_UINT32)
-				throw love::Exception("test");
+			if (type != DATA_UINT16 && type != DATA_UINT32)
+				throw love::Exception("Index buffers only support uint16 and uint32 data types.");
+		}
+
+		if (vertexbuffer)
+		{
+			if (info.isMatrix)
+				throw love::Exception("matrix types are not supported in vertex buffers.");
+
+			if (info.baseType == DATA_BASE_BOOL)
+				throw love::Exception("bool types are not supported in vertex buffers.");
+
+			if ((info.baseType == DATA_BASE_INT || info.baseType == DATA_BASE_UINT) && !supportsGLSL3)
+				throw love::Exception("Integer vertex attribute data types require GLSL 3 support.");
 		}
 
 		if (uniformbuffer)
 		{
-			
+			if (info.componentSize != 4)
+				throw love::Exception("");
 		}
 	}
 }

+ 36 - 5
src/modules/graphics/Buffer.h

@@ -23,6 +23,7 @@
 // LOVE
 #include "common/config.h"
 #include "common/int.h"
+#include "common/Object.h"
 #include "vertex.h"
 #include "Resource.h"
 
@@ -41,10 +42,12 @@ class Graphics;
 /**
  * A block of GPU-owned memory. Currently meant for internal use.
  **/
-class Buffer : public Resource
+class Buffer : public love::Object, public Resource
 {
 public:
 
+	static love::Type type;
+
 	enum MapFlags
 	{
 		MAP_EXPLICIT_RANGE_MODIFY = (1 << 0), // see setMappedRangeModified.
@@ -112,6 +115,28 @@ public:
 		DATA_MAX_ENUM
 	};
 
+	enum DataTypeBase
+	{
+		DATA_BASE_FLOAT,
+		DATA_BASE_INT,
+		DATA_BASE_UINT,
+		DATA_BASE_SNORM,
+		DATA_BASE_UNORM,
+		DATA_BASE_BOOL,
+	};
+
+	struct DataTypeInfo
+	{
+		DataTypeBase baseType;
+		bool isMatrix;
+		int components;
+		int matrixRows;
+		int matrixColumns;
+		size_t componentSize;
+		size_t packedAlignment;
+		size_t packedSize;
+	};
+
 	struct DataMember
 	{
 		std::string name;
@@ -123,16 +148,16 @@ public:
 	{
 		BufferTypeFlags typeFlags;
 		MapFlags mapFlags;
-		vertex::Usage usage;
+		BufferUsage usage;
 	};
 
-	Buffer(size_t size, BufferTypeFlags typeflags, vertex::Usage usage, uint32 mapflags);
+	Buffer(size_t size, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags);
 	Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataMember> &format, size_t arraylength);
 	virtual ~Buffer();
 
 	size_t getSize() const { return size; }
 	BufferTypeFlags getTypeFlags() const { return typeFlags; }
-	vertex::Usage getUsage() const { return usage; }
+	BufferUsage getUsage() const { return usage; }
 	bool isMapped() const { return mapped; }
 	uint32 getMapFlags() const { return mapFlags; }
 
@@ -196,8 +221,14 @@ public:
 
 //	static size_t getDataTypeSize(DataType type, bool uniform)
 
+	const DataTypeInfo &getDataTypeInfo(DataType type);
+
 protected:
 
+	std::vector<DataMember> format;
+	std::vector<size_t> memberOffsets;
+	size_t arrayStride;
+
 	// The size of the buffer, in bytes.
 	size_t size;
 
@@ -205,7 +236,7 @@ protected:
 	BufferTypeFlags typeFlags;
 
 	// Usage hint. GL_[DYNAMIC, STATIC, STREAM]_DRAW.
-	vertex::Usage usage;
+	BufferUsage usage;
 	
 	uint32 mapFlags;
 

+ 2 - 2
src/modules/graphics/Font.cpp

@@ -45,7 +45,7 @@ static inline uint16 normToUint16(double n)
 love::Type Font::type("Font", &Object::type);
 int Font::fontCount = 0;
 
-const vertex::CommonFormat Font::vertexFormat = vertex::CommonFormat::XYf_STus_RGBAub;
+const CommonFormat Font::vertexFormat = CommonFormat::XYf_STus_RGBAub;
 
 Font::Font(love::font::Rasterizer *r, const Texture::Filter &f)
 	: rasterizers({r})
@@ -642,7 +642,7 @@ void Font::printv(graphics::Graphics *gfx, const Matrix4 &t, const std::vector<D
 	{
 		Graphics::StreamDrawCommand streamcmd;
 		streamcmd.formats[0] = vertexFormat;
-		streamcmd.indexMode = vertex::TriangleIndexMode::QUADS;
+		streamcmd.indexMode = TriangleIndexMode::QUADS;
 		streamcmd.vertexCount = cmd.vertexcount;
 		streamcmd.texture = cmd.texture;
 

+ 2 - 2
src/modules/graphics/Font.h

@@ -51,9 +51,9 @@ public:
 	static love::Type type;
 
 	typedef std::vector<uint32> Codepoints;
-	typedef vertex::XYf_STus_RGBAub GlyphVertex;
+	typedef XYf_STus_RGBAub GlyphVertex;
 
-	static const vertex::CommonFormat vertexFormat;
+	static const CommonFormat vertexFormat;
 
 	enum AlignMode
 	{

+ 13 - 17
src/modules/graphics/Graphics.cpp

@@ -173,10 +173,10 @@ void Graphics::createQuadIndexBuffer()
 		return;
 
 	size_t size = sizeof(uint16) * (LOVE_UINT16_MAX / 4) * 6;
-	quadIndexBuffer = newBuffer(size, nullptr, BUFFERFLAG_INDEX, vertex::USAGE_STATIC, 0);
+	quadIndexBuffer = newBuffer(size, nullptr, BUFFERFLAG_INDEX, BUFFERUSAGE_STATIC, 0);
 
 	Buffer::Mapper map(*quadIndexBuffer);
-	vertex::fillIndices(vertex::TriangleIndexMode::QUADS, 0, LOVE_UINT16_MAX, (uint16 *) map.get());
+	fillIndices(TriangleIndexMode::QUADS, 0, LOVE_UINT16_MAX, (uint16 *) map.get());
 }
 
 Quad *Graphics::newQuad(Quad::Viewport v, double sw, double sh)
@@ -204,7 +204,7 @@ Video *Graphics::newVideo(love::video::VideoStream *stream, float dpiscale)
 	return new Video(this, stream, dpiscale);
 }
 
-love::graphics::SpriteBatch *Graphics::newSpriteBatch(Texture *texture, int size, vertex::Usage usage)
+love::graphics::SpriteBatch *Graphics::newSpriteBatch(Texture *texture, int size, BufferUsage usage)
 {
 	return new SpriteBatch(this, texture, size, usage);
 }
@@ -260,22 +260,22 @@ 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)
+Mesh *Graphics::newMesh(const std::vector<Vertex> &vertices, PrimitiveType drawmode, BufferUsage usage)
 {
 	return newMesh(Mesh::getDefaultVertexFormat(), &vertices[0], vertices.size() * sizeof(Vertex), drawmode, usage);
 }
 
-Mesh *Graphics::newMesh(int vertexcount, PrimitiveType drawmode, vertex::Usage usage)
+Mesh *Graphics::newMesh(int vertexcount, PrimitiveType drawmode, BufferUsage usage)
 {
 	return newMesh(Mesh::getDefaultVertexFormat(), vertexcount, drawmode, usage);
 }
 
-love::graphics::Mesh *Graphics::newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage)
+love::graphics::Mesh *Graphics::newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, BufferUsage 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, PrimitiveType drawmode, vertex::Usage usage)
+love::graphics::Mesh *Graphics::newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferUsage usage)
 {
 	return new Mesh(this, vertexformat, data, datasize, drawmode, usage);
 }
@@ -891,7 +891,7 @@ CullMode Graphics::getMeshCullMode() const
 	return states.back().meshCullMode;
 }
 
-vertex::Winding Graphics::getFrontFaceWinding() const
+Winding Graphics::getFrontFaceWinding() const
 {
 	return states.back().winding;
 }
@@ -996,8 +996,6 @@ void Graphics::captureScreenshot(const ScreenshotInfo &info)
 
 Graphics::StreamVertexData Graphics::requestStreamDraw(const StreamDrawCommand &cmd)
 {
-	using namespace vertex;
-
 	StreamBufferState &state = streamBufferState;
 
 	bool shouldflush = false;
@@ -1130,8 +1128,6 @@ Graphics::StreamVertexData Graphics::requestStreamDraw(const StreamDrawCommand &
 
 void Graphics::flushStreamDraws()
 {
-	using namespace vertex;
-
 	auto &sbstate = streamBufferState;
 
 	if (sbstate.vertexCount == 0 && sbstate.indexCount == 0)
@@ -1280,8 +1276,8 @@ void Graphics::points(const Vector2 *positions, const Colorf *colors, size_t num
 
 	StreamDrawCommand cmd;
 	cmd.primitiveMode = PRIMITIVE_POINTS;
-	cmd.formats[0] = vertex::getSinglePositionFormat(is2D);
-	cmd.formats[1] = vertex::CommonFormat::RGBAub;
+	cmd.formats[0] = getSinglePositionFormat(is2D);
+	cmd.formats[1] = CommonFormat::RGBAub;
 	cmd.vertexCount = (int) numpoints;
 
 	StreamVertexData data = requestStreamDraw(cmd);
@@ -1575,9 +1571,9 @@ void Graphics::polygon(DrawMode mode, const Vector2 *coords, size_t count, bool
 		bool is2D = t.isAffine2DTransform();
 
 		StreamDrawCommand cmd;
-		cmd.formats[0] = vertex::getSinglePositionFormat(is2D);
-		cmd.formats[1] = vertex::CommonFormat::RGBAub;
-		cmd.indexMode = vertex::TriangleIndexMode::FAN;
+		cmd.formats[0] = getSinglePositionFormat(is2D);
+		cmd.formats[1] = CommonFormat::RGBAub;
+		cmd.indexMode = TriangleIndexMode::FAN;
 		cmd.vertexCount = (int)count - (skipLastFilledVertex ? 1 : 0);
 
 		StreamVertexData data = requestStreamDraw(cmd);

+ 21 - 21
src/modules/graphics/Graphics.h

@@ -212,8 +212,8 @@ public:
 	{
 		PrimitiveType primitiveType = PRIMITIVE_TRIANGLES;
 
-		const vertex::Attributes *attributes;
-		const vertex::BufferBindings *buffers;
+		const Attributes *attributes;
+		const BufferBindings *buffers;
 
 		int vertexStart = 0;
 		int vertexCount = 0;
@@ -224,7 +224,7 @@ public:
 		// TODO: This should be moved out to a state transition API?
 		CullMode cullMode = CULL_NONE;
 
-		DrawCommand(const vertex::Attributes *attribs, const vertex::BufferBindings *buffers)
+		DrawCommand(const Attributes *attribs, const BufferBindings *buffers)
 			: attributes(attribs)
 			, buffers(buffers)
 		{}
@@ -234,8 +234,8 @@ public:
 	{
 		PrimitiveType primitiveType = PRIMITIVE_TRIANGLES;
 
-		const vertex::Attributes *attributes;
-		const vertex::BufferBindings *buffers;
+		const Attributes *attributes;
+		const BufferBindings *buffers;
 
 		int indexCount = 0;
 		int instanceCount = 1;
@@ -249,7 +249,7 @@ public:
 		// TODO: This should be moved out to a state transition API?
 		CullMode cullMode = CULL_NONE;
 
-		DrawIndexedCommand(const vertex::Attributes *attribs, const vertex::BufferBindings *buffers, Resource *indexbuffer)
+		DrawIndexedCommand(const Attributes *attribs, const BufferBindings *buffers, Resource *indexbuffer)
 			: attributes(attribs)
 			, buffers(buffers)
 			, indexBuffer(indexbuffer)
@@ -259,8 +259,8 @@ public:
 	struct StreamDrawCommand
 	{
 		PrimitiveType primitiveMode = PRIMITIVE_TRIANGLES;
-		vertex::CommonFormat formats[2];
-		vertex::TriangleIndexMode indexMode = vertex::TriangleIndexMode::NONE;
+		CommonFormat formats[2];
+		TriangleIndexMode indexMode = TriangleIndexMode::NONE;
 		int vertexCount = 0;
 		Texture *texture = nullptr;
 		Shader::StandardShader standardShaderType = Shader::STANDARD_DEFAULT;
@@ -268,7 +268,7 @@ public:
 		StreamDrawCommand()
 		{
 			// VS2013 can't initialize arrays in the above manner...
-			formats[1] = formats[0] = vertex::CommonFormat::NONE;
+			formats[1] = formats[0] = CommonFormat::NONE;
 		}
 	};
 
@@ -437,7 +437,7 @@ public:
 	Font *newDefaultFont(int size, font::TrueTypeRasterizer::Hinting hinting, const Texture::Filter &filter = Texture::defaultFilter);
 	Video *newVideo(love::video::VideoStream *stream, float dpiscale);
 
-	SpriteBatch *newSpriteBatch(Texture *texture, int size, vertex::Usage usage);
+	SpriteBatch *newSpriteBatch(Texture *texture, int size, BufferUsage usage);
 	ParticleSystem *newParticleSystem(Texture *texture, int size);
 
 	virtual Canvas *newCanvas(const Canvas::Settings &settings) = 0;
@@ -445,15 +445,15 @@ public:
 	ShaderStage *newShaderStage(ShaderStage::StageType stage, const std::string &source);
 	Shader *newShader(const std::string &vertex, const std::string &pixel);
 
-	virtual Buffer *newBuffer(size_t size, const void *data, BufferTypeFlags typeflags, vertex::Usage usage, uint32 mapflags) = 0;
+	virtual Buffer *newBuffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags) = 0;
 	virtual Buffer *newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataMember> &format, size_t arraylength) = 0;
 
 //	Buffer *newIndexBuffer(IndexDataType dataType, const void *indices, size_t bytesize, vertex::Usage usage, uint32 mapflags) = 0;
 
-	Mesh *newMesh(const std::vector<Vertex> &vertices, PrimitiveType drawmode, vertex::Usage usage);
-	Mesh *newMesh(int vertexcount, PrimitiveType drawmode, vertex::Usage usage);
-	Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage);
-	Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, vertex::Usage usage);
+	Mesh *newMesh(const std::vector<Vertex> &vertices, PrimitiveType drawmode, BufferUsage usage);
+	Mesh *newMesh(int vertexcount, PrimitiveType drawmode, BufferUsage usage);
+	Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, BufferUsage usage);
+	Mesh *newMesh(const std::vector<Mesh::AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferUsage usage);
 
 	Text *newText(Font *font, const std::vector<Font::ColoredString> &text = {});
 
@@ -597,8 +597,8 @@ public:
 	void setMeshCullMode(CullMode cull);
 	CullMode getMeshCullMode() const;
 
-	virtual void setFrontFaceWinding(vertex::Winding winding) = 0;
-	vertex::Winding getFrontFaceWinding() const;
+	virtual void setFrontFaceWinding(Winding winding) = 0;
+	Winding getFrontFaceWinding() const;
 
 	/**
 	 * Sets the enabled color components when rendering.
@@ -833,7 +833,7 @@ public:
 
 	virtual void draw(const DrawCommand &cmd) = 0;
 	virtual void draw(const DrawIndexedCommand &cmd) = 0;
-	virtual void drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::BufferBindings &buffers, Texture *texture) = 0;
+	virtual void drawQuads(int start, int count, const Attributes &attributes, const BufferBindings &buffers, Texture *texture) = 0;
 
 	void flushStreamDraws();
 	StreamVertexData requestStreamDraw(const StreamDrawCommand &command);
@@ -910,7 +910,7 @@ protected:
 		bool depthWrite = false;
 
 		CullMode meshCullMode = CULL_NONE;
-		vertex::Winding winding = vertex::WINDING_CCW;
+		Winding winding = WINDING_CCW;
 
 		StrongRef<Font> font;
 		StrongRef<Shader> shader;
@@ -933,7 +933,7 @@ protected:
 		StreamBuffer *indexBuffer = nullptr;
 
 		PrimitiveType primitiveMode = PRIMITIVE_TRIANGLES;
-		vertex::CommonFormat formats[2];
+		CommonFormat formats[2];
 		StrongRef<Texture> texture;
 		Shader::StandardShader standardShaderType = Shader::STANDARD_DEFAULT;
 		int vertexCount = 0;
@@ -945,7 +945,7 @@ protected:
 		StreamBufferState()
 		{
 			vb[0] = vb[1] = nullptr;
-			formats[0] = formats[1] = vertex::CommonFormat::NONE;
+			formats[0] = formats[1] = CommonFormat::NONE;
 			vbMap[0] = vbMap[1] = StreamBuffer::MapInfo();
 		}
 	};

+ 28 - 40
src/modules/graphics/Mesh.cpp

@@ -37,7 +37,7 @@ namespace graphics
 static const char *getBuiltinAttribName(BuiltinVertexAttribute attribid)
 {
 	const char *name = "";
-	vertex::getConstant(attribid, name);
+	getConstant(attribid, name);
 	return name;
 }
 
@@ -49,9 +49,9 @@ std::vector<Mesh::AttribFormat> Mesh::getDefaultVertexFormat()
 {
 	// Corresponds to the love::Vertex struct.
 	std::vector<Mesh::AttribFormat> vertexformat = {
-		{ getBuiltinAttribName(ATTRIB_POS),      vertex::DATA_FLOAT,  2 },
-		{ getBuiltinAttribName(ATTRIB_TEXCOORD), vertex::DATA_FLOAT,  2 },
-		{ getBuiltinAttribName(ATTRIB_COLOR),    vertex::DATA_UNORM8, 4 },
+		{ getBuiltinAttribName(ATTRIB_POS),      DATA_FLOAT,  2 },
+		{ getBuiltinAttribName(ATTRIB_TEXCOORD), DATA_FLOAT,  2 },
+		{ getBuiltinAttribName(ATTRIB_COLOR),    DATA_UNORM8, 4 },
 	};
 
 	return vertexformat;
@@ -59,7 +59,7 @@ 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, PrimitiveType drawmode, vertex::Usage usage)
+Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferUsage usage)
 	: vertexFormat(vertexformat)
 	, vertexBuffer(nullptr)
 	, vertexCount(0)
@@ -76,17 +76,18 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexforma
 	calculateAttributeSizes(gfx);
 
 	vertexCount = datasize / vertexStride;
-	indexDataType = vertex::getIndexDataTypeFromMax(vertexCount);
+	indexDataType = getIndexDataTypeFromMax(vertexCount);
 
 	if (vertexCount == 0)
 		throw love::Exception("Data size is too small for specified vertex attribute formats.");
 
-	vertexBuffer = gfx->newBuffer(datasize, data, BUFFERFLAG_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ);
+	auto buffer = gfx->newBuffer(datasize, data, BUFFERFLAG_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ);
+	vertexBuffer.set(buffer, Acquire::NORETAIN);
 
 	vertexScratchBuffer = new char[vertexStride];
 }
 
-Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, vertex::Usage usage)
+Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, BufferUsage usage)
 	: vertexFormat(vertexformat)
 	, vertexBuffer(nullptr)
 	, vertexCount((size_t) vertexcount)
@@ -94,7 +95,7 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexforma
 	, indexBuffer(nullptr)
 	, useIndexBuffer(false)
 	, indexCount(0)
-	, indexDataType(vertex::getIndexDataTypeFromMax(vertexcount))
+	, indexDataType(getIndexDataTypeFromMax(vertexcount))
 	, primitiveType(drawmode)
 	, rangeStart(-1)
 	, rangeCount(-1)
@@ -107,7 +108,8 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexforma
 
 	size_t buffersize = vertexCount * vertexStride;
 
-	vertexBuffer = gfx->newBuffer(buffersize, nullptr, BUFFERFLAG_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ);
+	auto buffer = gfx->newBuffer(buffersize, nullptr, BUFFERFLAG_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY | Buffer::MAP_READ);
+	vertexBuffer.set(buffer, Acquire::NORETAIN);
 
 	// Initialize the buffer's contents to 0.
 	memset(vertexBuffer->map(), 0, buffersize);
@@ -119,8 +121,6 @@ Mesh::Mesh(graphics::Graphics *gfx, const std::vector<AttribFormat> &vertexforma
 
 Mesh::~Mesh()
 {
-	delete vertexBuffer;
-	delete indexBuffer;
 	delete vertexScratchBuffer;
 
 	for (const auto &attrib : attachedAttributes)
@@ -151,7 +151,7 @@ void Mesh::calculateAttributeSizes(Graphics *gfx)
 
 	for (const AttribFormat &format : vertexFormat)
 	{
-		size_t size = vertex::getDataTypeSize(format.type) * format.components;
+		size_t size = getDataTypeSize(format.type) * format.components;
 
 		if (format.components <= 0 || format.components > 4)
 			throw love::Exception("Vertex attributes must have between 1 and 4 components.");
@@ -160,7 +160,7 @@ void Mesh::calculateAttributeSizes(Graphics *gfx)
 		if (size % 4 != 0)
 			throw love::Exception("Vertex attributes must have enough components to be a multiple of 32 bits.");
 
-		if (vertex::isDataTypeInteger(format.type) && !supportsGLSL3)
+		if (isDataTypeInteger(format.type) && !supportsGLSL3)
 			throw love::Exception("Integer vertex attribute data types require GLSL 3 support.");
 
 		// Total size in bytes of each attribute in a single vertex.
@@ -265,7 +265,7 @@ const std::vector<Mesh::AttribFormat> &Mesh::getVertexFormat() const
 	return vertexFormat;
 }
 
-vertex::DataType Mesh::getAttributeInfo(int attribindex, int &components) const
+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);
@@ -328,8 +328,8 @@ void Mesh::attachAttribute(const std::string &name, Mesh *mesh, const std::strin
 	auto it = attachedAttributes.find(name);
 	if (it != attachedAttributes.end())
 		oldattrib = it->second;
-	else if (attachedAttributes.size() + 1 > vertex::Attributes::MAX)
-		throw love::Exception("A maximum of %d attributes can be attached at once.", vertex::Attributes::MAX);
+	else if (attachedAttributes.size() + 1 > Attributes::MAX)
+		throw love::Exception("A maximum of %d attributes can be attached at once.", Attributes::MAX);
 
 	newattrib.mesh = mesh;
 	newattrib.enabled = oldattrib.mesh ? oldattrib.enabled : true;
@@ -406,21 +406,15 @@ void Mesh::setVertexMap(const std::vector<uint32> &map)
 {
 	size_t maxval = getVertexCount();
 
-	IndexDataType datatype = vertex::getIndexDataTypeFromMax(maxval);
+	IndexDataType datatype = getIndexDataTypeFromMax(maxval);
 
 	// Calculate the size in bytes of the index buffer data.
-	size_t size = map.size() * vertex::getIndexDataSize(datatype);
+	size_t size = map.size() * getIndexDataSize(datatype);
 
-	if (indexBuffer && size > indexBuffer->getSize())
-	{
-		delete indexBuffer;
-		indexBuffer = nullptr;
-	}
-
-	if (!indexBuffer && size > 0)
+	if (indexBuffer.get() == nullptr || size > indexBuffer->getSize())
 	{
 		auto gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
-		indexBuffer = gfx->newBuffer(size, nullptr, BUFFERFLAG_INDEX, vertexBuffer->getUsage(), Buffer::MAP_READ);
+		indexBuffer.set(gfx->newBuffer(size, nullptr, BUFFERFLAG_INDEX, vertexBuffer->getUsage(), Buffer::MAP_READ), Acquire::NORETAIN);
 	}
 
 	useIndexBuffer = true;
@@ -448,19 +442,13 @@ void Mesh::setVertexMap(const std::vector<uint32> &map)
 
 void Mesh::setVertexMap(IndexDataType datatype, const void *data, size_t datasize)
 {
-	if (indexBuffer && datasize > indexBuffer->getSize())
-	{
-		delete indexBuffer;
-		indexBuffer = nullptr;
-	}
-
-	if (!indexBuffer && datasize > 0)
+	if (indexBuffer.get() == nullptr || datasize > indexBuffer->getSize())
 	{
 		auto gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
-		indexBuffer = gfx->newBuffer(datasize, nullptr, BUFFERFLAG_INDEX, vertexBuffer->getUsage(), Buffer::MAP_READ);
+		indexBuffer.set(gfx->newBuffer(datasize, nullptr, BUFFERFLAG_INDEX, vertexBuffer->getUsage(), Buffer::MAP_READ), Acquire::NORETAIN);
 	}
 
-	indexCount = datasize / vertex::getIndexDataSize(datatype);
+	indexCount = datasize / getIndexDataSize(datatype);
 
 	if (!indexBuffer || indexCount == 0)
 		return;
@@ -592,8 +580,8 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
 	if (Shader::current && texture.get())
 		Shader::current->checkMainTexture(texture);
 
-	vertex::Attributes attributes;
-	vertex::BufferBindings buffers;
+	Attributes attributes;
+	BufferBindings buffers;
 
 	int activebuffers = 0;
 
@@ -608,7 +596,7 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
 		// If the attribute is one of the LOVE-defined ones, use the constant
 		// attribute index for it, otherwise query the index from the shader.
 		BuiltinVertexAttribute builtinattrib;
-		if (vertex::getConstant(attrib.first.c_str(), builtinattrib))
+		if (getConstant(attrib.first.c_str(), builtinattrib))
 			attributeindex = (int) builtinattrib;
 		else if (Shader::current)
 			attributeindex = Shader::current->getVertexAttributeIndex(attrib.first);
@@ -653,7 +641,7 @@ void Mesh::drawInstanced(Graphics *gfx, const Matrix4 &m, int instancecount)
 		cmd.cullMode = gfx->getMeshCullMode();
 
 		int start = std::min(std::max(0, rangeStart), (int) indexCount - 1);
-		cmd.indexBufferOffset = start * vertex::getIndexDataSize(indexDataType);
+		cmd.indexBufferOffset = start * getIndexDataSize(indexDataType);
 
 		cmd.indexCount = (int) indexCount;
 		if (rangeCount > 0)

+ 6 - 6
src/modules/graphics/Mesh.h

@@ -55,12 +55,12 @@ public:
 	struct AttribFormat
 	{
 		std::string name;
-		vertex::DataType type;
+		DataType type;
 		int components; // max 4
 	};
 
-	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);
+	Mesh(Graphics *gfx, const std::vector<AttribFormat> &vertexformat, const void *data, size_t datasize, PrimitiveType drawmode, BufferUsage usage);
+	Mesh(Graphics *gfx, const std::vector<AttribFormat> &vertexformat, int vertexcount, PrimitiveType drawmode, BufferUsage usage);
 
 	virtual ~Mesh();
 
@@ -96,7 +96,7 @@ public:
 	 * Gets the format of each vertex attribute stored in the Mesh.
 	 **/
 	const std::vector<AttribFormat> &getVertexFormat() const;
-	vertex::DataType getAttributeInfo(int attribindex, int &components) const;
+	DataType getAttributeInfo(int attribindex, int &components) const;
 	int getAttributeIndex(const std::string &name) const;
 
 	/**
@@ -196,7 +196,7 @@ private:
 	std::unordered_map<std::string, AttachedAttribute> attachedAttributes;
 
 	// Vertex buffer, for the vertex data.
-	Buffer *vertexBuffer;
+	StrongRef<Buffer> vertexBuffer;
 	size_t vertexCount;
 	size_t vertexStride;
 
@@ -205,7 +205,7 @@ private:
 	char *vertexScratchBuffer;
 
 	// Index buffer, for the vertex map.
-	Buffer *indexBuffer;
+	StrongRef<Buffer> indexBuffer;
 	bool useIndexBuffer;
 	size_t indexCount;
 	IndexDataType indexDataType;

+ 4 - 4
src/modules/graphics/ParticleSystem.cpp

@@ -93,7 +93,7 @@ ParticleSystem::ParticleSystem(Texture *texture, uint32 size)
 	, offset(float(texture->getWidth())*0.5f, float(texture->getHeight())*0.5f)
 	, defaultOffset(true)
 	, relativeRotation(false)
-	, vertexAttributes(vertex::CommonFormat::XYf_STf_RGBAub, 0)
+	, vertexAttributes(CommonFormat::XYf_STf_RGBAub, 0)
 	, buffer(nullptr)
 {
 	if (size == 0 || size > MAX_PARTICLES)
@@ -191,7 +191,7 @@ void ParticleSystem::createBuffers(size_t size)
 		auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
 
 		size_t bytes = sizeof(Vertex) * size * 4;
-		buffer = gfx->newBuffer(bytes, nullptr, BUFFERFLAG_VERTEX, vertex::USAGE_STREAM, 0);
+		buffer = gfx->newBuffer(bytes, nullptr, BUFFERFLAG_VERTEX, BUFFERUSAGE_STREAM, 0);
 	}
 	catch (std::bad_alloc &)
 	{
@@ -203,7 +203,7 @@ void ParticleSystem::createBuffers(size_t size)
 void ParticleSystem::deleteBuffers()
 {
 	delete[] pMem;
-	delete buffer;
+	buffer->release();
 
 	pMem = nullptr;
 	buffer = nullptr;
@@ -1080,7 +1080,7 @@ void ParticleSystem::draw(Graphics *gfx, const Matrix4 &m)
 
 	Graphics::TempTransform transform(gfx, m);
 
-	vertex::BufferBindings vertexbuffers;
+	BufferBindings vertexbuffers;
 	vertexbuffers.set(0, buffer, 0);
 
 	gfx->drawQuads(0, pCount, vertexAttributes, vertexbuffers, texture);

+ 72 - 1
src/modules/graphics/ParticleSystem.h

@@ -558,6 +558,77 @@ private:
 		int quadIndex;
 	};
 
+	struct Emitter
+	{
+		// Pointer to the beginning of the allocated memory.
+		Particle *pMem;
+
+		// Pointer to a free particle.
+		Particle *pFree;
+
+		// Pointer to the start of the linked list.
+		Particle *pHead;
+
+		// Pointer to the end of the linked list.
+		Particle *pTail;
+
+		// Whether the particle emitter is active.
+		bool active;
+
+		// Insert mode of new particles.
+		InsertMode insertMode;
+
+		// The number of active particles.
+		uint32 activeParticles;
+
+		// The emission rate (particles/sec).
+		float emissionRate;
+
+		// Used to determine when a particle should be emitted.
+		float emitCounter;
+
+		// The relative position of the particle emitter.
+		love::Vector2 position;
+		love::Vector2 prevPosition;
+
+		// Emission area spread.
+		AreaSpreadDistribution emissionAreaDistribution;
+		love::Vector2 emissionArea;
+		float emissionAreaAngle;
+		bool directionRelativeToEmissionCenter;
+
+		// The lifetime of the particle emitter (-1 means infinite) and the life it has left.
+		float lifetime;
+		float life;
+
+		// The particle life.
+		float particleLifeMin;
+		float particleLifeMax;
+
+		// The direction (and spread) the particles will be emitted in. Measured in radians.
+		float direction;
+		float spread;
+
+		// The speed.
+		float speedMin;
+		float speedMax;
+
+		// Acceleration along the x and y axes.
+		love::Vector2 linearAccelerationMin;
+		love::Vector2 linearAccelerationMax;
+
+		// Acceleration towards the emitter's center
+		float radialAccelerationMin;
+		float radialAccelerationMax;
+
+		// Acceleration perpendicular to the particle's direction.
+		float tangentialAccelerationMin;
+		float tangentialAccelerationMax;
+
+		float linearDampingMin;
+		float linearDampingMax;
+	};
+
 	void resetOffset();
 
 	void createBuffers(size_t size);
@@ -673,7 +744,7 @@ private:
 
 	bool relativeRotation;
 
-	const vertex::Attributes vertexAttributes;
+	const Attributes vertexAttributes;
 	Buffer *buffer;
 
 	static StringMap<AreaSpreadDistribution, DISTRIBUTION_MAX_ENUM>::Entry distributionsEntries[];

+ 4 - 4
src/modules/graphics/Polyline.cpp

@@ -82,7 +82,7 @@ void Polyline::render(const Vector2 *coords, size_t count, size_t size_hint, flo
 		// extra degenerate triangle in between the core line and the overdraw
 		// line in order to break up the strip into two. This will let us draw
 		// everything in one draw call.
-		if (triangle_mode == vertex::TriangleIndexMode::STRIP)
+		if (triangle_mode == TriangleIndexMode::STRIP)
 			extra_vertices = 2;
 	}
 
@@ -383,7 +383,7 @@ void Polyline::draw(love::graphics::Graphics *gfx)
 	int maxvertices = LOVE_UINT16_MAX - 3;
 
 	int advance = maxvertices;
-	if (triangle_mode == vertex::TriangleIndexMode::STRIP)
+	if (triangle_mode == TriangleIndexMode::STRIP)
 		advance -= 2;
 
 	for (int vertex_start = 0; vertex_start < total_vertex_count; vertex_start += advance)
@@ -391,8 +391,8 @@ void Polyline::draw(love::graphics::Graphics *gfx)
 		const Vector2 *verts = vertices + vertex_start;
 
 		Graphics::StreamDrawCommand cmd;
-		cmd.formats[0] = vertex::getSinglePositionFormat(is2D);
-		cmd.formats[1] = vertex::CommonFormat::RGBAub;
+		cmd.formats[0] = getSinglePositionFormat(is2D);
+		cmd.formats[1] = CommonFormat::RGBAub;
 		cmd.indexMode = triangle_mode;
 		cmd.vertexCount = std::min(maxvertices, total_vertex_count - vertex_start);
 

+ 3 - 3
src/modules/graphics/Polyline.h

@@ -44,7 +44,7 @@ class Polyline
 {
 public:
 
-	Polyline(vertex::TriangleIndexMode mode = vertex::TriangleIndexMode::STRIP)
+	Polyline(TriangleIndexMode mode = TriangleIndexMode::STRIP)
 		: vertices(nullptr)
 		, overdraw(nullptr)
 		, vertex_count(0)
@@ -94,7 +94,7 @@ protected:
 	Vector2 *overdraw;
 	size_t vertex_count;
 	size_t overdraw_vertex_count;
-	vertex::TriangleIndexMode triangle_mode;
+	TriangleIndexMode triangle_mode;
 	size_t overdraw_vertex_start;
 
 }; // Polyline
@@ -109,7 +109,7 @@ class NoneJoinPolyline : public Polyline
 public:
 
 	NoneJoinPolyline()
-		: Polyline(vertex::TriangleIndexMode::QUADS)
+		: Polyline(TriangleIndexMode::QUADS)
 	{}
 
 	void render(const Vector2 *vertices, size_t count, float halfwidth, float pixel_size, bool draw_overdraw)

+ 5 - 11
src/modules/graphics/SpriteBatch.cpp

@@ -40,7 +40,7 @@ namespace graphics
 
 love::Type SpriteBatch::type("SpriteBatch", &Drawable::type);
 
-SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usage usage)
+SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, BufferUsage usage)
 	: texture(texture)
 	, size(size)
 	, next(0)
@@ -57,11 +57,11 @@ SpriteBatch::SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usag
 		throw love::Exception("A texture must be used when creating a SpriteBatch.");
 
 	if (texture->getTextureType() == TEXTURE_2D_ARRAY)
-		vertex_format = vertex::CommonFormat::XYf_STPf_RGBAub;
+		vertex_format = CommonFormat::XYf_STPf_RGBAub;
 	else
-		vertex_format = vertex::CommonFormat::XYf_STf_RGBAub;
+		vertex_format = CommonFormat::XYf_STf_RGBAub;
 
-	vertex_stride = vertex::getFormatStride(vertex_format);
+	vertex_stride = getFormatStride(vertex_format);
 
 	size_t vertex_size = vertex_stride * 4 * size;
 	array_buf = gfx->newBuffer(vertex_size, nullptr, BUFFERFLAG_VERTEX, usage, Buffer::MAP_EXPLICIT_RANGE_MODIFY);
@@ -79,8 +79,6 @@ int SpriteBatch::add(const Matrix4 &m, int index /*= -1*/)
 
 int SpriteBatch::add(Quad *quad, const Matrix4 &m, int index /*= -1*/)
 {
-	using namespace vertex;
-
 	if (vertex_format == CommonFormat::XYf_STPf_RGBAub)
 		return addLayer(quad->getLayer(), quad, m, index);
 
@@ -122,8 +120,6 @@ int SpriteBatch::addLayer(int layer, const Matrix4 &m, int index)
 
 int SpriteBatch::addLayer(int layer, Quad *quad, const Matrix4 &m, int index)
 {
-	using namespace vertex;
-
 	if (vertex_format != CommonFormat::XYf_STPf_RGBAub)
 		throw love::Exception("addLayer can only be called on a SpriteBatch that uses an Array Texture!");
 
@@ -296,8 +292,6 @@ bool SpriteBatch::getDrawRange(int &start, int &count) const
 
 void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m)
 {
-	using namespace vertex;
-
 	if (next == 0)
 		return;
 
@@ -345,7 +339,7 @@ void SpriteBatch::draw(Graphics *gfx, const Matrix4 &m)
 		// If the attribute is one of the LOVE-defined ones, use the constant
 		// attribute index for it, otherwise query the index from the shader.
 		BuiltinVertexAttribute builtinattrib;
-		if (vertex::getConstant(it.first.c_str(), builtinattrib))
+		if (getConstant(it.first.c_str(), builtinattrib))
 			attributeindex = (int) builtinattrib;
 		else if (Shader::current)
 			attributeindex = Shader::current->getVertexAttributeIndex(it.first);

+ 2 - 2
src/modules/graphics/SpriteBatch.h

@@ -51,7 +51,7 @@ public:
 
 	static love::Type type;
 
-	SpriteBatch(Graphics *gfx, Texture *texture, int size, vertex::Usage usage);
+	SpriteBatch(Graphics *gfx, Texture *texture, int size, BufferUsage usage);
 	virtual ~SpriteBatch();
 
 	int add(const Matrix4 &m, int index = -1);
@@ -128,7 +128,7 @@ private:
 	Color32 color;
 	Colorf colorf;
 
-	vertex::CommonFormat vertex_format;
+	CommonFormat vertex_format;
 	size_t vertex_stride;
 	
 	love::graphics::Buffer *array_buf;

+ 1 - 1
src/modules/graphics/Text.cpp

@@ -60,7 +60,7 @@ void Text::uploadVertices(const std::vector<Font::GlyphVertex> &vertices, size_t
 			newsize = std::max(size_t(vertex_buffer->getSize() * 1.5), newsize);
 
 		auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
-		Buffer *new_buffer = gfx->newBuffer(newsize, nullptr, BUFFERFLAG_VERTEX, vertex::USAGE_DYNAMIC, 0);
+		Buffer *new_buffer = gfx->newBuffer(newsize, nullptr, BUFFERFLAG_VERTEX, BUFFERUSAGE_DYNAMIC, 0);
 
 		if (vertex_buffer != nullptr)
 			vertex_buffer->copyTo(0, vertex_buffer->getSize(), new_buffer, 0);

+ 2 - 2
src/modules/graphics/Text.h

@@ -85,8 +85,8 @@ private:
 
 	StrongRef<Font> font;
 
-	vertex::Attributes vertexAttributes;
-	vertex::BufferBindings vertexBuffers;
+	Attributes vertexAttributes;
+	BufferBindings vertexBuffers;
 
 	Buffer *vertex_buffer;
 

+ 4 - 8
src/modules/graphics/Texture.cpp

@@ -117,8 +117,6 @@ void Texture::draw(Graphics *gfx, const Matrix4 &m)
 
 void Texture::draw(Graphics *gfx, Quad *q, const Matrix4 &localTransform)
 {
-	using namespace vertex;
-
 	if (!readable)
 		throw love::Exception("Textures with non-readable formats cannot be drawn.");
 
@@ -132,7 +130,7 @@ void Texture::draw(Graphics *gfx, Quad *q, const Matrix4 &localTransform)
 	bool is2D = tm.isAffine2DTransform();
 
 	Graphics::StreamDrawCommand cmd;
-	cmd.formats[0] = vertex::getSinglePositionFormat(is2D);
+	cmd.formats[0] = getSinglePositionFormat(is2D);
 	cmd.formats[1] = CommonFormat::STf_RGBAub;
 	cmd.indexMode = TriangleIndexMode::QUADS;
 	cmd.vertexCount = 4;
@@ -148,7 +146,7 @@ void Texture::draw(Graphics *gfx, Quad *q, const Matrix4 &localTransform)
 		t.transformXY0((Vector3 *) data.stream[0], q->getVertexPositions(), 4);
 
 	const Vector2 *texcoords = q->getVertexTexCoords();
-	vertex::STf_RGBAub *vertexdata = (vertex::STf_RGBAub *) data.stream[1];
+	STf_RGBAub *vertexdata = (STf_RGBAub *) data.stream[1];
 
 	Color32 c = toColor32(gfx->getColor());
 
@@ -167,8 +165,6 @@ void Texture::drawLayer(Graphics *gfx, int layer, const Matrix4 &m)
 
 void Texture::drawLayer(Graphics *gfx, int layer, Quad *q, const Matrix4 &m)
 {
-	using namespace vertex;
-
 	if (!readable)
 		throw love::Exception("Textures with non-readable formats cannot be drawn.");
 
@@ -186,7 +182,7 @@ void Texture::drawLayer(Graphics *gfx, int layer, Quad *q, const Matrix4 &m)
 	Matrix4 t(tm, m);
 
 	Graphics::StreamDrawCommand cmd;
-	cmd.formats[0] = vertex::getSinglePositionFormat(is2D);
+	cmd.formats[0] = getSinglePositionFormat(is2D);
 	cmd.formats[1] = CommonFormat::STPf_RGBAub;
 	cmd.indexMode = TriangleIndexMode::QUADS;
 	cmd.vertexCount = 4;
@@ -201,7 +197,7 @@ void Texture::drawLayer(Graphics *gfx, int layer, Quad *q, const Matrix4 &m)
 		t.transformXY0((Vector3 *) data.stream[0], q->getVertexPositions(), 4);
 
 	const Vector2 *texcoords = q->getVertexTexCoords();
-	vertex::STPf_RGBAub *vertexdata = (vertex::STPf_RGBAub *) data.stream[1];
+	STPf_RGBAub *vertexdata = (STPf_RGBAub *) data.stream[1];
 
 	for (int i = 0; i < 4; i++)
 	{

+ 4 - 4
src/modules/graphics/Video.cpp

@@ -115,9 +115,9 @@ void Video::draw(Graphics *gfx, const Matrix4 &m)
 	Matrix4 t(tm, m);
 
 	Graphics::StreamDrawCommand cmd;
-	cmd.formats[0] = vertex::getSinglePositionFormat(is2D);
-	cmd.formats[1] = vertex::CommonFormat::STf_RGBAub;
-	cmd.indexMode = vertex::TriangleIndexMode::QUADS;
+	cmd.formats[0] = getSinglePositionFormat(is2D);
+	cmd.formats[1] = CommonFormat::STf_RGBAub;
+	cmd.indexMode = TriangleIndexMode::QUADS;
 	cmd.vertexCount = 4;
 	cmd.standardShaderType = Shader::STANDARD_VIDEO;
 
@@ -128,7 +128,7 @@ void Video::draw(Graphics *gfx, const Matrix4 &m)
 	else
 		t.transformXY0((Vector3 *) data.stream[0], vertices, 4);
 
-	vertex::STf_RGBAub *verts = (vertex::STf_RGBAub *) data.stream[1];
+	STf_RGBAub *verts = (STf_RGBAub *) data.stream[1];
 
 	Color32 c = toColor32(gfx->getColor());
 

+ 4 - 4
src/modules/graphics/opengl/Buffer.cpp

@@ -35,7 +35,7 @@ namespace graphics
 namespace opengl
 {
 
-Buffer::Buffer(size_t size, const void *data, BufferTypeFlags typeflags, vertex::Usage usage, uint32 mapflags)
+Buffer::Buffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags)
 	: love::graphics::Buffer(size, typeflags, usage, mapflags)
 	, vbo(0)
 	, memoryMap(nullptr)
@@ -141,13 +141,13 @@ void Buffer::unmap()
 	{
 		switch (getUsage())
 		{
-		case vertex::USAGE_STATIC:
+		case BUFFERUSAGE_STATIC:
 			unmapStatic(modifiedOffset, modifiedSize);
 			break;
-		case vertex::USAGE_STREAM:
+		case BUFFERUSAGE_STREAM:
 			unmapStream();
 			break;
-		case vertex::USAGE_DYNAMIC:
+		case BUFFERUSAGE_DYNAMIC:
 		default:
 			// It's probably more efficient to treat it like a streaming buffer if
 			// at least a third of its contents have been modified during the map().

+ 1 - 1
src/modules/graphics/opengl/Buffer.h

@@ -39,7 +39,7 @@ class Buffer final : public love::graphics::Buffer, public Volatile
 {
 public:
 
-	Buffer(size_t size, const void *data, BufferTypeFlags typeflags, vertex::Usage usage, uint32 mapflags);
+	Buffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags);
 	virtual ~Buffer();
 
 	void *map() override;

+ 11 - 11
src/modules/graphics/opengl/Graphics.cpp

@@ -155,7 +155,7 @@ love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage
 	return new Shader(vertex, pixel);
 }
 
-love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, BufferTypeFlags typeflags, vertex::Usage usage, uint32 mapflags)
+love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags)
 {
 	return new Buffer(size, data, typeflags, usage, mapflags);
 }
@@ -385,13 +385,13 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
 	++drawCalls;
 }
 
-static inline void advanceVertexOffsets(const vertex::Attributes &attributes, vertex::BufferBindings &buffers, int vertexcount)
+static inline void advanceVertexOffsets(const Attributes &attributes, BufferBindings &buffers, int vertexcount)
 {
 	// TODO: Figure out a better way to avoid touching the same buffer multiple
 	// times, if multiple attributes share the buffer.
 	uint32 touchedbuffers = 0;
 
-	for (unsigned int i = 0; i < vertex::Attributes::MAX; i++)
+	for (unsigned int i = 0; i < Attributes::MAX; i++)
 	{
 		if (!attributes.isEnabled(i))
 			continue;
@@ -408,7 +408,7 @@ static inline void advanceVertexOffsets(const vertex::Attributes &attributes, ve
 	}
 }
 
-void Graphics::drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::BufferBindings &buffers, love::graphics::Texture *texture)
+void Graphics::drawQuads(int start, int count, const Attributes &attributes, const BufferBindings &buffers, love::graphics::Texture *texture)
 {
 	const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
 	const int MAX_QUADS_PER_DRAW    = MAX_VERTICES_PER_DRAW / 4;
@@ -437,7 +437,7 @@ void Graphics::drawQuads(int start, int count, const vertex::Attributes &attribu
 	}
 	else
 	{
-		vertex::BufferBindings bufferscopy = buffers;
+		BufferBindings bufferscopy = buffers;
 		if (start > 0)
 			advanceVertexOffsets(attributes, bufferscopy, start * 4);
 
@@ -525,7 +525,7 @@ void Graphics::setCanvasInternal(const RenderTargets &rts, int w, int h, int pix
 	endPass();
 
 	bool iswindow = rts.getFirstTarget().canvas == nullptr;
-	vertex::Winding vertexwinding = state.winding;
+	Winding vertexwinding = state.winding;
 
 	if (iswindow)
 	{
@@ -543,10 +543,10 @@ void Graphics::setCanvasInternal(const RenderTargets &rts, int w, int h, int pix
 
 		// Flip front face winding when rendering to a canvas, since our
 		// projection matrix is flipped.
-		vertexwinding = vertexwinding == vertex::WINDING_CW ? vertex::WINDING_CCW : vertex::WINDING_CW;
+		vertexwinding = vertexwinding == WINDING_CW ? WINDING_CCW : WINDING_CW;
 	}
 
-	glFrontFace(vertexwinding == vertex::WINDING_CW ? GL_CW : GL_CCW);
+	glFrontFace(vertexwinding == WINDING_CW ? GL_CW : GL_CCW);
 
 	gl.setViewport({0, 0, pixelw, pixelh});
 
@@ -1241,7 +1241,7 @@ void Graphics::setDepthMode(CompareMode compare, bool write)
 	}
 }
 
-void Graphics::setFrontFaceWinding(vertex::Winding winding)
+void Graphics::setFrontFaceWinding(Winding winding)
 {
 	DisplayState &state = states.back();
 
@@ -1251,9 +1251,9 @@ void Graphics::setFrontFaceWinding(vertex::Winding winding)
 	state.winding = winding;
 
 	if (isCanvasActive())
-		winding = winding == vertex::WINDING_CW ? vertex::WINDING_CCW : vertex::WINDING_CW;
+		winding = winding == WINDING_CW ? WINDING_CCW : WINDING_CW;
 
-	glFrontFace(winding == vertex::WINDING_CW ? GL_CW : GL_CCW);
+	glFrontFace(winding == WINDING_CW ? GL_CW : GL_CCW);
 }
 
 void Graphics::setColor(Colorf c)

+ 3 - 3
src/modules/graphics/opengl/Graphics.h

@@ -63,7 +63,7 @@ public:
 	love::graphics::Image *newImage(const Image::Slices &data, const Image::Settings &settings) override;
 	love::graphics::Image *newImage(TextureType textype, PixelFormat format, int width, int height, int slices, const Image::Settings &settings) override;
 	love::graphics::Canvas *newCanvas(const Canvas::Settings &settings) override;
-	love::graphics::Buffer *newBuffer(size_t size, const void *data, BufferTypeFlags typeflags, vertex::Usage usage, uint32 mapflags) override;
+	love::graphics::Buffer *newBuffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags) override;
 	love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataMember> &format, size_t arraylength) override;
 
 	void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
@@ -74,7 +74,7 @@ public:
 
 	void draw(const DrawCommand &cmd) override;
 	void draw(const DrawIndexedCommand &cmd) override;
-	void drawQuads(int start, int count, const vertex::Attributes &attributes, const vertex::BufferBindings &buffers, Texture *texture) override;
+	void drawQuads(int start, int count, const Attributes &attributes, const BufferBindings &buffers, Texture *texture) override;
 
 	void clear(OptionalColorf color, OptionalInt stencil, OptionalDouble depth) override;
 	void clear(const std::vector<OptionalColorf> &colors, OptionalInt stencil, OptionalDouble depth) override;
@@ -95,7 +95,7 @@ public:
 
 	void setDepthMode(CompareMode compare, bool write) override;
 
-	void setFrontFaceWinding(vertex::Winding winding) override;
+	void setFrontFaceWinding(Winding winding) override;
 
 	void setColorMask(ColorChannelMask mask) override;
 

+ 19 - 19
src/modules/graphics/opengl/OpenGL.cpp

@@ -186,7 +186,7 @@ void OpenGL::setupContext()
 	state.enabledAttribArrays = (uint32) ((1ull << uint32(maxvertexattribs)) - 1);
 	state.instancedAttribArrays = 0;
 
-	setVertexAttributes(vertex::Attributes(), vertex::BufferBindings());
+	setVertexAttributes(Attributes(), BufferBindings());
 
 	// Get the current viewport.
 	glGetIntegerv(GL_VIEWPORT, (GLint *) &state.viewport.x);
@@ -631,62 +631,62 @@ GLenum OpenGL::getGLIndexDataType(IndexDataType type)
 	}
 }
 
-GLenum OpenGL::getGLVertexDataType(vertex::DataType type, GLboolean &normalized, bool &intformat)
+GLenum OpenGL::getGLVertexDataType(DataType type, GLboolean &normalized, bool &intformat)
 {
 	normalized = GL_FALSE;
 	intformat = false;
 
 	switch (type)
 	{
-	case vertex::DATA_SNORM8:
+	case DATA_SNORM8:
 		normalized = GL_TRUE;
 		return GL_BYTE;
-	case vertex::DATA_UNORM8:
+	case DATA_UNORM8:
 		normalized = GL_TRUE;
 		return GL_UNSIGNED_BYTE;
-	case vertex::DATA_INT8:
+	case DATA_INT8:
 		intformat = true;
 		return GL_BYTE;
-	case vertex::DATA_UINT8:
+	case DATA_UINT8:
 		intformat = true;
 		return GL_UNSIGNED_BYTE;
-	case vertex::DATA_SNORM16:
+	case DATA_SNORM16:
 		normalized = GL_TRUE;
 		return GL_SHORT;
-	case vertex::DATA_UNORM16:
+	case DATA_UNORM16:
 		normalized = GL_TRUE;
 		return GL_UNSIGNED_SHORT;
-	case vertex::DATA_INT16:
+	case DATA_INT16:
 		intformat = true;
 		return GL_SHORT;
-	case vertex::DATA_UINT16:
+	case DATA_UINT16:
 		intformat = true;
 		return GL_UNSIGNED_SHORT;
-	case vertex::DATA_INT32:
+	case DATA_INT32:
 		intformat = true;
 		return GL_INT;
-	case vertex::DATA_UINT32:
+	case DATA_UINT32:
 		intformat = true;
 		return GL_UNSIGNED_INT;
-	case vertex::DATA_FLOAT:
+	case DATA_FLOAT:
 		normalized = GL_FALSE;
 		return GL_FLOAT;
-	case vertex::DATA_MAX_ENUM:
+	case DATA_MAX_ENUM:
 		return GL_ZERO;
 	}
 
 	return GL_ZERO;
 }
 
-GLenum OpenGL::getGLBufferUsage(vertex::Usage usage)
+GLenum OpenGL::getGLBufferUsage(BufferUsage usage)
 {
 	switch (usage)
 	{
-	case vertex::USAGE_STREAM:
+	case BUFFERUSAGE_STREAM:
 		return GL_STREAM_DRAW;
-	case vertex::USAGE_DYNAMIC:
+	case BUFFERUSAGE_DYNAMIC:
 		return GL_DYNAMIC_DRAW;
-	case vertex::USAGE_STATIC:
+	case BUFFERUSAGE_STATIC:
 		return GL_STATIC_DRAW;
 	default:
 		return 0;
@@ -713,7 +713,7 @@ void OpenGL::deleteBuffer(GLuint buffer)
 	}
 }
 
-void OpenGL::setVertexAttributes(const vertex::Attributes &attributes, const vertex::BufferBindings &buffers)
+void OpenGL::setVertexAttributes(const Attributes &attributes, const BufferBindings &buffers)
 {
 	uint32 enablediff = attributes.enableBits ^ state.enabledAttribArrays;
 	uint32 instanceattribbits = 0;

+ 3 - 3
src/modules/graphics/opengl/OpenGL.h

@@ -238,7 +238,7 @@ public:
 	/**
 	 * Set all vertex attribute state.
 	 **/
-	void setVertexAttributes(const vertex::Attributes &attributes, const vertex::BufferBindings &buffers);
+	void setVertexAttributes(const Attributes &attributes, const BufferBindings &buffers);
 
 	/**
 	 * Wrapper for glCullFace which eliminates redundant state setting.
@@ -404,8 +404,8 @@ public:
 	static GLenum getGLPrimitiveType(PrimitiveType type);
 	static GLenum getGLBufferType(BufferType type);
 	static GLenum getGLIndexDataType(IndexDataType type);
-	static GLenum getGLVertexDataType(vertex::DataType type, GLboolean &normalized, bool &intformat);
-	static GLenum getGLBufferUsage(vertex::Usage usage);
+	static GLenum getGLVertexDataType(DataType type, GLboolean &normalized, bool &intformat);
+	static GLenum getGLBufferUsage(BufferUsage usage);
 	static GLenum getGLTextureType(TextureType type);
 	static GLint getGLWrapMode(Texture::WrapMode wmode);
 	static GLint getGLCompareMode(CompareMode mode);

+ 3 - 2
src/modules/graphics/opengl/Shader.cpp

@@ -23,6 +23,7 @@
 
 #include "Shader.h"
 #include "Graphics.h"
+#include "graphics/vertex.h"
 
 // C++
 #include <algorithm>
@@ -322,7 +323,7 @@ bool Shader::loadVolatile()
 	for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++)
 	{
 		const char *name = nullptr;
-		if (vertex::getConstant((BuiltinVertexAttribute) i, name))
+		if (graphics::getConstant((BuiltinVertexAttribute) i, name))
 			glBindAttribLocation(program, i, (const GLchar *) name);
 	}
 
@@ -345,7 +346,7 @@ bool Shader::loadVolatile()
 	for (int i = 0; i < int(ATTRIB_MAX_ENUM); i++)
 	{
 		const char *name = nullptr;
-		if (vertex::getConstant(BuiltinVertexAttribute(i), name))
+		if (graphics::getConstant(BuiltinVertexAttribute(i), name))
 			builtinAttributes[i] = glGetAttribLocation(program, name);
 		else
 			builtinAttributes[i] = -1;

+ 8 - 11
src/modules/graphics/vertex.cpp

@@ -25,8 +25,6 @@ namespace love
 {
 namespace graphics
 {
-namespace vertex
-{
 
 static_assert(sizeof(Color32) == 4, "sizeof(Color32) incorrect!");
 static_assert(sizeof(STf_RGBAub) == sizeof(float)*2 + sizeof(Color32), "sizeof(STf_RGBAub) incorrect!");
@@ -306,14 +304,14 @@ static StringMap<IndexDataType, INDEX_MAX_ENUM>::Entry indexTypeEntries[] =
 
 static StringMap<IndexDataType, INDEX_MAX_ENUM> indexTypes(indexTypeEntries, sizeof(indexTypeEntries));
 
-static StringMap<Usage, USAGE_MAX_ENUM>::Entry usageEntries[] =
+static StringMap<BufferUsage, BUFFERUSAGE_MAX_ENUM>::Entry usageEntries[] =
 {
-	{ "stream",  USAGE_STREAM  },
-	{ "dynamic", USAGE_DYNAMIC },
-	{ "static",  USAGE_STATIC  },
+	{ "stream",  BUFFERUSAGE_STREAM  },
+	{ "dynamic", BUFFERUSAGE_DYNAMIC },
+	{ "static",  BUFFERUSAGE_STATIC  },
 };
 
-static StringMap<Usage, USAGE_MAX_ENUM> usages(usageEntries, sizeof(usageEntries));
+static StringMap<BufferUsage, BUFFERUSAGE_MAX_ENUM> usages(usageEntries, sizeof(usageEntries));
 
 static StringMap<PrimitiveType, PRIMITIVE_MAX_ENUM>::Entry primitiveTypeEntries[] =
 {
@@ -392,17 +390,17 @@ std::vector<std::string> getConstants(IndexDataType)
 	return indexTypes.getNames();
 }
 
-bool getConstant(const char *in, Usage &out)
+bool getConstant(const char *in, BufferUsage &out)
 {
 	return usages.find(in, out);
 }
 
-bool getConstant(Usage in, const char *&out)
+bool getConstant(BufferUsage in, const char *&out)
 {
 	return usages.find(in, out);
 }
 
-std::vector<std::string> getConstants(Usage)
+std::vector<std::string> getConstants(BufferUsage)
 {
 	return usages.getNames();
 }
@@ -482,6 +480,5 @@ std::vector<std::string> getConstants(Winding)
 	return windings.getNames();
 }
 
-} // vertex
 } // graphics
 } // love

+ 11 - 16
src/modules/graphics/vertex.h

@@ -102,16 +102,13 @@ enum CullMode
 	CULL_MAX_ENUM
 };
 
-namespace vertex
+// The expected usage pattern of buffer data.
+enum BufferUsage
 {
-
-// The expected usage pattern of vertex data.
-enum Usage
-{
-	USAGE_STREAM,
-	USAGE_DYNAMIC,
-	USAGE_STATIC,
-	USAGE_MAX_ENUM
+	BUFFERUSAGE_STREAM,
+	BUFFERUSAGE_DYNAMIC,
+	BUFFERUSAGE_STATIC,
+	BUFFERUSAGE_MAX_ENUM
 };
 
 enum DataType
@@ -195,6 +192,8 @@ struct XYf_STf_RGBAub
 	Color32 color;
 };
 
+typedef XYf_STf_RGBAub Vertex;
+
 struct XYf_STus_RGBAub
 {
 	float  x, y;
@@ -334,9 +333,9 @@ bool getConstant(const char *in, IndexDataType &out);
 bool getConstant(IndexDataType in, const char *&out);
 std::vector<std::string> getConstants(IndexDataType);
 
-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, BufferUsage &out);
+bool getConstant(BufferUsage in, const char *&out);
+std::vector<std::string> getConstants(BufferUsage);
 
 bool getConstant(const char *in, PrimitiveType &out);
 bool getConstant(PrimitiveType in, const char *&out);
@@ -358,9 +357,5 @@ bool getConstant(const char *in, Winding &out);
 bool getConstant(Winding in, const char *&out);
 std::vector<std::string> getConstants(Winding);
 
-} // vertex
-
-typedef vertex::XYf_STf_RGBAub Vertex;
-
 } // graphics
 } // love

+ 21 - 21
src/modules/graphics/wrap_Graphics.cpp

@@ -1147,12 +1147,12 @@ int w_newSpriteBatch(lua_State *L)
 
 	Texture *texture = luax_checktexture(L, 1);
 	int size = (int) luaL_optinteger(L, 2, 1000);
-	vertex::Usage usage = vertex::USAGE_DYNAMIC;
+	BufferUsage usage = BUFFERUSAGE_DYNAMIC;
 	if (lua_gettop(L) > 2)
 	{
 		const char *usagestr = luaL_checkstring(L, 3);
-		if (!vertex::getConstant(usagestr, usage))
-			return luax_enumerror(L, "usage hint", vertex::getConstants(usage), usagestr);
+		if (!getConstant(usagestr, usage))
+			return luax_enumerror(L, "usage hint", getConstants(usage), usagestr);
 	}
 
 	SpriteBatch *t = nullptr;
@@ -1421,12 +1421,12 @@ int w_validateShader(lua_State *L)
 	return 1;
 }
 
-static vertex::Usage luax_optmeshusage(lua_State *L, int idx, vertex::Usage def)
+static BufferUsage luax_optmeshusage(lua_State *L, int idx, BufferUsage def)
 {
 	const char *usagestr = lua_isnoneornil(L, idx) ? nullptr : luaL_checkstring(L, idx);
 
-	if (usagestr && !vertex::getConstant(usagestr, def))
-		luax_enumerror(L, "usage hint", vertex::getConstants(def), usagestr);
+	if (usagestr && !getConstant(usagestr, def))
+		luax_enumerror(L, "usage hint", getConstants(def), usagestr);
 
 	return def;
 }
@@ -1435,8 +1435,8 @@ static PrimitiveType luax_optmeshdrawmode(lua_State *L, int idx, PrimitiveType d
 {
 	const char *modestr = lua_isnoneornil(L, idx) ? nullptr : luaL_checkstring(L, idx);
 
-	if (modestr && !vertex::getConstant(modestr, def))
-		luax_enumerror(L, "mesh draw mode", vertex::getConstants(def), modestr);
+	if (modestr && !getConstant(modestr, def))
+		luax_enumerror(L, "mesh draw mode", getConstants(def), modestr);
 
 	return def;
 }
@@ -1446,7 +1446,7 @@ static Mesh *newStandardMesh(lua_State *L)
 	Mesh *t = nullptr;
 
 	PrimitiveType drawmode = luax_optmeshdrawmode(L, 2, PRIMITIVE_TRIANGLE_FAN);
-	vertex::Usage usage = luax_optmeshusage(L, 3, vertex::USAGE_DYNAMIC);
+	BufferUsage usage = luax_optmeshusage(L, 3, BUFFERUSAGE_DYNAMIC);
 
 	// First argument is a table of standard vertices, or the number of
 	// standard vertices.
@@ -1506,7 +1506,7 @@ static Mesh *newCustomMesh(lua_State *L)
 	std::vector<Mesh::AttribFormat> vertexformat;
 
 	PrimitiveType drawmode = luax_optmeshdrawmode(L, 3, PRIMITIVE_TRIANGLE_FAN);
-	vertex::Usage usage = luax_optmeshusage(L, 4, vertex::USAGE_DYNAMIC);
+	BufferUsage usage = luax_optmeshusage(L, 4, BUFFERUSAGE_DYNAMIC);
 
 	lua_rawgeti(L, 1, 1);
 	if (!lua_istable(L, -1))
@@ -1530,10 +1530,10 @@ static Mesh *newCustomMesh(lua_State *L)
 
 		const char *tname = luaL_checkstring(L, -2);
 		if (strcmp(tname, "byte") == 0) // Legacy name.
-			format.type = vertex::DATA_UNORM8;
-		else if (!vertex::getConstant(tname, format.type))
+			format.type = DATA_UNORM8;
+		else if (!getConstant(tname, format.type))
 		{
-			luax_enumerror(L, "Mesh vertex data type name", vertex::getConstants(format.type), tname);
+			luax_enumerror(L, "Mesh vertex data type name", getConstants(format.type), tname);
 			return nullptr;
 		}
 
@@ -2109,8 +2109,8 @@ int w_setMeshCullMode(lua_State *L)
 	const char *str = luaL_checkstring(L, 1);
 	CullMode mode;
 
-	if (!vertex::getConstant(str, mode))
-		return luax_enumerror(L, "cull mode", vertex::getConstants(mode), str);
+	if (!getConstant(str, mode))
+		return luax_enumerror(L, "cull mode", getConstants(mode), str);
 
 	luax_catchexcept(L, [&]() { instance()->setMeshCullMode(mode); });
 	return 0;
@@ -2120,7 +2120,7 @@ int w_getMeshCullMode(lua_State *L)
 {
 	CullMode mode = instance()->getMeshCullMode();
 	const char *str;
-	if (!vertex::getConstant(mode, str))
+	if (!getConstant(mode, str))
 		return luaL_error(L, "Unknown cull mode");
 	lua_pushstring(L, str);
 	return 1;
@@ -2129,10 +2129,10 @@ int w_getMeshCullMode(lua_State *L)
 int w_setFrontFaceWinding(lua_State *L)
 {
 	const char *str = luaL_checkstring(L, 1);
-	vertex::Winding winding;
+	Winding winding;
 
-	if (!vertex::getConstant(str, winding))
-		return luax_enumerror(L, "vertex winding", vertex::getConstants(winding), str);
+	if (!getConstant(str, winding))
+		return luax_enumerror(L, "vertex winding", getConstants(winding), str);
 
 	luax_catchexcept(L, [&]() { instance()->setFrontFaceWinding(winding); });
 	return 0;
@@ -2140,9 +2140,9 @@ int w_setFrontFaceWinding(lua_State *L)
 
 int w_getFrontFaceWinding(lua_State *L)
 {
-	vertex::Winding winding = instance()->getFrontFaceWinding();
+	Winding winding = instance()->getFrontFaceWinding();
 	const char *str;
-	if (!vertex::getConstant(winding, str))
+	if (!getConstant(winding, str))
 		return luaL_error(L, "Unknown vertex winding");
 	lua_pushstring(L, str);
 	return 1;

+ 30 - 0
src/modules/graphics/wrap_GraphicsShader.lua

@@ -380,6 +380,36 @@ local function isPixelCode(code)
 	end
 end
 
+local function includeShader(path, dir, global)
+
+end
+
+local function preprocessIncludes(code, dir, level)
+	local output = {}
+
+	local linecount = 0
+	for line in code:gmatch("[^\r\n]+") do
+		linecount = linecount + 1
+
+		if line:match("^%s*#include") then
+			local localpath = line:match("^%s*#include%s*\"(.*)\"")
+			local globalpath = line:match("^%s*#include%s*<(.*)>")
+			--local
+			if localpath then
+				--table_insert(output, )
+			elseif globalpath then
+
+			else
+
+			end
+		else
+			table_insert(output, line)
+		end
+	end
+
+	return table_concat(output, "\n")
+end
+
 function love.graphics._shaderCodeToGLSL(gles, arg1, arg2)
 	local vertexcode, pixelcode
 	local is_custompixel = false -- whether pixel code has "effects" function instead of "effect"

+ 36 - 36
src/modules/graphics/wrap_Mesh.cpp

@@ -74,31 +74,31 @@ static inline size_t writeUNormData(lua_State *L, int startidx, int components,
 	return sizeof(T) * components;
 }
 
-char *luax_writeAttributeData(lua_State *L, int startidx, vertex::DataType type, int components, char *data)
+char *luax_writeAttributeData(lua_State *L, int startidx, DataType type, int components, char *data)
 {
 	switch (type)
 	{
-	case vertex::DATA_SNORM8:
+	case DATA_SNORM8:
 		return data + writeSNormData<int8>(L, startidx, components, data);
-	case vertex::DATA_UNORM8:
+	case DATA_UNORM8:
 		return data + writeUNormData<uint8>(L, startidx, components, data);
-	case vertex::DATA_INT8:
+	case DATA_INT8:
 		return data + writeData<int8>(L, startidx, components, data);
-	case vertex::DATA_UINT8:
+	case DATA_UINT8:
 		return data + writeData<uint8>(L, startidx, components, data);
-	case vertex::DATA_SNORM16:
+	case DATA_SNORM16:
 		return data + writeSNormData<int16>(L, startidx, components, data);
-	case vertex::DATA_UNORM16:
+	case DATA_UNORM16:
 		return data + writeUNormData<uint16>(L, startidx, components, data);
-	case vertex::DATA_INT16:
+	case DATA_INT16:
 		return data + writeData<int16>(L, startidx, components, data);
-	case vertex::DATA_UINT16:
+	case DATA_UINT16:
 		return data + writeData<uint16>(L, startidx, components, data);
-	case vertex::DATA_INT32:
+	case DATA_INT32:
 		return data + writeData<int32>(L, startidx, components, data);
-	case vertex::DATA_UINT32:
+	case DATA_UINT32:
 		return data + writeData<uint32>(L, startidx, components, data);
-	case vertex::DATA_FLOAT:
+	case DATA_FLOAT:
 		return data + writeData<float>(L, startidx, components, data);
 	default:
 		return data;
@@ -140,31 +140,31 @@ static inline size_t readUNormData(lua_State *L, int components, const char *dat
 	return sizeof(T) * components;
 }
 
-const char *luax_readAttributeData(lua_State *L, vertex::DataType type, int components, const char *data)
+const char *luax_readAttributeData(lua_State *L, DataType type, int components, const char *data)
 {
 	switch (type)
 	{
-	case vertex::DATA_SNORM8:
+	case DATA_SNORM8:
 		return data + readSNormData<int8>(L, components, data);
-	case vertex::DATA_UNORM8:
+	case DATA_UNORM8:
 		return data + readUNormData<uint8>(L, components, data);
-	case vertex::DATA_INT8:
+	case DATA_INT8:
 		return data + readData<int8>(L, components, data);
-	case vertex::DATA_UINT8:
+	case DATA_UINT8:
 		return data + readData<uint8>(L, components, data);
-	case vertex::DATA_SNORM16:
+	case DATA_SNORM16:
 		return data + readSNormData<int16>(L, components, data);
-	case vertex::DATA_UNORM16:
+	case DATA_UNORM16:
 		return data + readUNormData<uint16>(L, components, data);
-	case vertex::DATA_INT16:
+	case DATA_INT16:
 		return data + readData<int16>(L, components, data);
-	case vertex::DATA_UINT16:
+	case DATA_UINT16:
 		return data + readData<uint16>(L, components, data);
-	case vertex::DATA_INT32:
+	case DATA_INT32:
 		return data + readData<int32>(L, components, data);
-	case vertex::DATA_UINT32:
+	case DATA_UINT32:
 		return data + readData<uint32>(L, components, data);
-	case vertex::DATA_FLOAT:
+	case DATA_FLOAT:
 		return data + readData<float>(L, components, data);
 	default:
 		return data;
@@ -321,7 +321,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;
 
-	vertex::DataType type;
+	DataType type;
 	int components;
 	luax_catchexcept(L, [&](){ type = t->getAttributeInfo(attribindex, components); });
 
@@ -341,7 +341,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;
 
-	vertex::DataType type;
+	DataType type;
 	int components;
 	luax_catchexcept(L, [&](){ type = t->getAttributeInfo(attribindex, components); });
 
@@ -372,8 +372,8 @@ int w_Mesh_getVertexFormat(lua_State *L)
 
 	for (size_t i = 0; i < vertexformat.size(); i++)
 	{
-		if (!vertex::getConstant(vertexformat[i].type, tname))
-			return luax_enumerror(L, "vertex attribute data type", vertex::getConstants(vertexformat[i].type), tname);
+		if (!getConstant(vertexformat[i].type, tname))
+			return luax_enumerror(L, "vertex attribute data type", getConstants(vertexformat[i].type), tname);
 
 		lua_createtable(L, 3, 0);
 
@@ -420,8 +420,8 @@ int w_Mesh_attachAttribute(lua_State *L)
 
 	AttributeStep step = STEP_PER_VERTEX;
 	const char *stepstr = lua_isnoneornil(L, 4) ? nullptr : luaL_checkstring(L, 4);
-	if (stepstr != nullptr && !vertex::getConstant(stepstr, step))
-		return luax_enumerror(L, "vertex attribute step", vertex::getConstants(step), stepstr);
+	if (stepstr != nullptr && !getConstant(stepstr, step))
+		return luax_enumerror(L, "vertex attribute step", getConstants(step), stepstr);
 
 	const char *attachname = luaL_optstring(L, 5, name);
 
@@ -463,10 +463,10 @@ int w_Mesh_setVertexMap(lua_State *L)
 
 		const char *indextypestr = luaL_checkstring(L, 3);
 		IndexDataType indextype;
-		if (!vertex::getConstant(indextypestr, indextype))
-			return luax_enumerror(L, "index data type", vertex::getConstants(indextype), indextypestr);
+		if (!getConstant(indextypestr, indextype))
+			return luax_enumerror(L, "index data type", getConstants(indextype), indextypestr);
 
-		size_t datatypesize = vertex::getIndexDataSize(indextype);
+		size_t datatypesize = getIndexDataSize(indextype);
 
 		int indexcount = (int) luaL_optinteger(L, 4, d->getSize() / datatypesize);
 
@@ -569,8 +569,8 @@ int w_Mesh_setDrawMode(lua_State *L)
 	const char *str = luaL_checkstring(L, 2);
 	PrimitiveType mode;
 
-	if (!vertex::getConstant(str, mode))
-		return luax_enumerror(L, "mesh draw mode", vertex::getConstants(mode), str);
+	if (!getConstant(str, mode))
+		return luax_enumerror(L, "mesh draw mode", getConstants(mode), str);
 
 	t->setDrawMode(mode);
 	return 0;
@@ -582,7 +582,7 @@ int w_Mesh_getDrawMode(lua_State *L)
 	PrimitiveType mode = t->getDrawMode();
 	const char *str;
 
-	if (!vertex::getConstant(mode, str))
+	if (!getConstant(mode, str))
 		return luaL_error(L, "Unknown mesh draw mode.");
 
 	lua_pushstring(L, str);

+ 2 - 2
src/modules/graphics/wrap_Mesh.h

@@ -30,8 +30,8 @@ namespace love
 namespace graphics
 {
 
-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);
+char *luax_writeAttributeData(lua_State *L, int startidx, DataType type, int components, char *data);
+const char *luax_readAttributeData(lua_State *L, DataType type, int components, const char *data);
 
 Mesh *luax_checkmesh(lua_State *L, int idx);
 extern "C" int luaopen_mesh(lua_State *L);