Browse Source

Move some code from Mesh wrapper to Buffer wrapper

Alex Szpakowski 5 years ago
parent
commit
2828761060

+ 3 - 10
src/modules/graphics/Buffer.cpp

@@ -50,10 +50,8 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataDe
 
 	bool supportsGLSL3 = gfx->getCapabilities().features[Graphics::FEATURE_GLSL3];
 
-	bool uniformbuffer = settings.typeFlags & TYPEFLAG_UNIFORM;
 	bool indexbuffer = settings.typeFlags & TYPEFLAG_INDEX;
 	bool vertexbuffer = settings.typeFlags & TYPEFLAG_VERTEX;
-	bool ssbuffer = settings.typeFlags & TYPEFLAG_SHADER_STORAGE;
 
 	size_t offset = 0;
 	size_t stride = 0;
@@ -89,16 +87,11 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataDe
 				throw love::Exception("Integer vertex attribute data types require GLSL 3 support.");
 		}
 
-		if (uniformbuffer)
-		{
-			if (info.componentSize != 4)
-				throw love::Exception("");
-		}
-
-
 		// TODO: alignment
 		member.offset = offset;
-		offset += member.info.size;
+		member.size = member.info.size;
+
+		offset += member.size;
 
 		dataMembers.push_back(member);
 	}

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

@@ -60,8 +60,6 @@ public:
 		TYPEFLAG_NONE = 0,
 		TYPEFLAG_VERTEX = 1 << BUFFERTYPE_VERTEX,
 		TYPEFLAG_INDEX = 1 << BUFFERTYPE_INDEX,
-		TYPEFLAG_UNIFORM = 1 << BUFFERTYPE_UNIFORM,
-		TYPEFLAG_SHADER_STORAGE = 1 << BUFFERTYPE_SHADER_STORAGE,
 	};
 
 	struct DataDeclaration
@@ -82,11 +80,13 @@ public:
 		DataDeclaration decl;
 		DataFormatInfo info;
 		size_t offset;
+		size_t size;
 
 		DataMember(const DataDeclaration &decl)
 			: decl(decl)
 			, info(getDataFormatInfo(decl.format))
 			, offset(0)
+			, size(0)
 		{}
 	};
 

+ 6 - 9
src/modules/graphics/Graphics.cpp

@@ -173,7 +173,9 @@ void Graphics::createQuadIndexBuffer()
 		return;
 
 	size_t size = sizeof(uint16) * (LOVE_UINT16_MAX / 4) * 6;
-	quadIndexBuffer = newIndexBuffer(INDEX_UINT16, nullptr, size, BUFFERUSAGE_STATIC, 0);
+
+	Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, 0, BUFFERUSAGE_STATIC);
+	quadIndexBuffer = newBuffer(settings, DATAFORMAT_UINT16, nullptr, size, 0);
 
 	Buffer::Mapper map(*quadIndexBuffer);
 	fillIndices(TRIANGLEINDEX_QUADS, 0, LOVE_UINT16_MAX, (uint16 *) map.data);
@@ -260,15 +262,10 @@ Shader *Graphics::newShader(const std::string &vertex, const std::string &pixel)
 	return newShaderInternal(vertexstage.get(), pixelstage.get());
 }
 
-Buffer *Graphics::newIndexBuffer(IndexDataType dataType, const void *indices, size_t size, BufferUsage usage, uint32 mapflags)
+Buffer *Graphics::newBuffer(const Buffer::Settings &settings, DataFormat format, const void *data, size_t size, size_t arraylength)
 {
-	Buffer::Settings settings(Buffer::TYPEFLAG_INDEX, mapflags, usage);
-
-	std::vector<Buffer::DataDeclaration> format = {
-		{ "index", getIndexDataFormat(dataType), 0 }
-	};
-
-	return newBuffer(settings, format, indices, size, 0);
+	std::vector<Buffer::DataDeclaration> dataformat = {{"", format, 0}};
+	return newBuffer(settings, format, data, size, arraylength);
 }
 
 Mesh *Graphics::newMesh(const std::vector<Vertex> &vertices, PrimitiveType drawmode, BufferUsage usage)

+ 1 - 2
src/modules/graphics/Graphics.h

@@ -441,8 +441,7 @@ public:
 
 	virtual Buffer *newBuffer(const Buffer::Settings &settings, const void *data, size_t size) = 0;
 	virtual Buffer *newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength) = 0;
-
-	Buffer *newIndexBuffer(IndexDataType dataType, const void *indices, size_t size, BufferUsage usage, uint32 mapflags);
+	virtual Buffer *newBuffer(const Buffer::Settings &settings, DataFormat format, const void *data, size_t size, size_t arraylength);
 
 	Mesh *newMesh(const std::vector<Vertex> &vertices, PrimitiveType drawmode, BufferUsage usage);
 	Mesh *newMesh(int vertexcount, PrimitiveType drawmode, BufferUsage usage);

+ 0 - 5
src/modules/graphics/Shader.h

@@ -33,11 +33,6 @@
 #include <vector>
 #include <stddef.h>
 
-namespace glslang
-{
-class TShader;
-}
-
 namespace love
 {
 namespace graphics

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

@@ -59,10 +59,6 @@ void Buffer::initialize(const void *data)
 		mapType = BUFFERTYPE_VERTEX;
 	else if (typeFlags & TYPEFLAG_INDEX)
 		mapType = BUFFERTYPE_INDEX;
-	else if (typeFlags & TYPEFLAG_UNIFORM)
-		mapType = BUFFERTYPE_UNIFORM;
-	else if (typeFlags & TYPEFLAG_SHADER_STORAGE)
-		mapType = BUFFERTYPE_SHADER_STORAGE;
 
 	target = OpenGL::getGLBufferType(mapType);
 

+ 29 - 62
src/modules/graphics/opengl/OpenGL.cpp

@@ -562,16 +562,11 @@ 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;
+		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;
@@ -581,16 +576,9 @@ GLenum OpenGL::getGLBufferType(BufferType type)
 {
 	switch (type)
 	{
-	case BUFFERTYPE_VERTEX:
-		return GL_ARRAY_BUFFER;
-	case BUFFERTYPE_INDEX:
-		return GL_ELEMENT_ARRAY_BUFFER;
-	case BUFFERTYPE_UNIFORM:
-		return GL_UNIFORM_BUFFER;
-	case BUFFERTYPE_SHADER_STORAGE:
-		return GL_SHADER_STORAGE_BUFFER;
-	case BUFFERTYPE_MAX_ENUM:
-		return GL_ZERO;
+		case BUFFERTYPE_VERTEX: return GL_ARRAY_BUFFER;
+		case BUFFERTYPE_INDEX: return GL_ELEMENT_ARRAY_BUFFER;
+		case BUFFERTYPE_MAX_ENUM: return GL_ZERO;
 	}
 
 	return GL_ZERO;
@@ -600,16 +588,11 @@ GLenum OpenGL::getGLTextureType(TextureType type)
 {
 	switch (type)
 	{
-	case TEXTURE_2D:
-		return GL_TEXTURE_2D;
-	case TEXTURE_VOLUME:
-		return GL_TEXTURE_3D;
-	case TEXTURE_2D_ARRAY:
-		return GL_TEXTURE_2D_ARRAY;
-	case TEXTURE_CUBE:
-		return GL_TEXTURE_CUBE_MAP;
-	case TEXTURE_MAX_ENUM:
-		return GL_ZERO;
+		case TEXTURE_2D: return GL_TEXTURE_2D;
+		case TEXTURE_VOLUME: return GL_TEXTURE_3D;
+		case TEXTURE_2D_ARRAY: return GL_TEXTURE_2D_ARRAY;
+		case TEXTURE_CUBE: return GL_TEXTURE_CUBE_MAP;
+		case TEXTURE_MAX_ENUM: return GL_ZERO;
 	}
 
 	return GL_ZERO;
@@ -619,12 +602,9 @@ GLenum OpenGL::getGLIndexDataType(IndexDataType type)
 {
 	switch (type)
 	{
-	case INDEX_UINT16:
-		return GL_UNSIGNED_SHORT;
-	case INDEX_UINT32:
-		return GL_UNSIGNED_INT;
-	default:
-		return GL_ZERO;
+		case INDEX_UINT16: return GL_UNSIGNED_SHORT;
+		case INDEX_UINT32: return GL_UNSIGNED_INT;
+		default: return GL_ZERO;
 	}
 }
 
@@ -771,14 +751,10 @@ GLenum OpenGL::getGLBufferUsage(BufferUsage usage)
 {
 	switch (usage)
 	{
-	case BUFFERUSAGE_STREAM:
-		return GL_STREAM_DRAW;
-	case BUFFERUSAGE_DYNAMIC:
-		return GL_DYNAMIC_DRAW;
-	case BUFFERUSAGE_STATIC:
-		return GL_STATIC_DRAW;
-	default:
-		return 0;
+		case BUFFERUSAGE_STREAM: return GL_STREAM_DRAW;
+		case BUFFERUSAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
+		case BUFFERUSAGE_STATIC: return GL_STATIC_DRAW;
+		default: return 0;
 	}
 }
 
@@ -1165,24 +1141,15 @@ GLint OpenGL::getGLCompareMode(CompareMode mode)
 {
 	switch (mode)
 	{
-	case COMPARE_LESS:
-		return GL_LESS;
-	case COMPARE_LEQUAL:
-		return GL_LEQUAL;
-	case COMPARE_EQUAL:
-		return GL_EQUAL;
-	case COMPARE_GEQUAL:
-		return GL_GEQUAL;
-	case COMPARE_GREATER:
-		return GL_GREATER;
-	case COMPARE_NOTEQUAL:
-		return GL_NOTEQUAL;
-	case COMPARE_ALWAYS:
-		return GL_ALWAYS;
-	case COMPARE_NEVER:
-		return GL_NEVER;
-	default:
-		return GL_NEVER;
+		case COMPARE_LESS: return GL_LESS;
+		case COMPARE_LEQUAL: return GL_LEQUAL;
+		case COMPARE_EQUAL: return GL_EQUAL;
+		case COMPARE_GEQUAL: return GL_GEQUAL;
+		case COMPARE_GREATER: return GL_GREATER;
+		case COMPARE_NOTEQUAL: return GL_NOTEQUAL;
+		case COMPARE_ALWAYS: return GL_ALWAYS;
+		case COMPARE_NEVER: return GL_NEVER;
+		default: return GL_NEVER;
 	}
 }
 

+ 50 - 50
src/modules/graphics/vertex.cpp

@@ -104,56 +104,56 @@ int getFormatPositionComponents(CommonFormat format)
 // Order here relies on order of DataFormat enum.
 static const DataFormatInfo dataFormatInfo[]
 {
-	// baseType, isMatrix, components, rows, columns, componentSize, align, size
-	{ DATA_BASETYPE_FLOAT, false, 1, 0, 0, 4, 4, 4  }, // DATAFORMAT_FLOAT
-	{ DATA_BASETYPE_FLOAT, false, 2, 0, 0, 4, 4, 8  }, // DATAFORMAT_FLOAT_VEC2
-	{ DATA_BASETYPE_FLOAT, false, 3, 0, 0, 4, 4, 12 }, // DATAFORMAT_FLOAT_VEC3
-	{ DATA_BASETYPE_FLOAT, false, 4, 0, 0, 4, 4, 16 }, // DATAFORMAT_FLOAT_VEC4
-
-	{ DATA_BASETYPE_FLOAT, true, 0, 2, 2, 4, 4, 16 }, // DATAFORMAT_FLOAT_MAT2X2
-	{ DATA_BASETYPE_FLOAT, true, 0, 2, 3, 4, 4, 24 }, // DATAFORMAT_FLOAT_MAT2X3
-	{ DATA_BASETYPE_FLOAT, true, 0, 2, 4, 4, 4, 32 }, // DATAFORMAT_FLOAT_MAT2X4
-
-	{ DATA_BASETYPE_FLOAT, true, 0, 3, 2, 4, 4, 24 }, // DATAFORMAT_FLOAT_MAT3X2
-	{ DATA_BASETYPE_FLOAT, true, 0, 3, 3, 4, 4, 36 }, // DATAFORMAT_FLOAT_MAT3X3
-	{ DATA_BASETYPE_FLOAT, true, 0, 3, 4, 4, 4, 48 }, // DATAFORMAT_FLOAT_MAT3X4
-
-	{ DATA_BASETYPE_FLOAT, true, 0, 4, 2, 4, 4, 32 }, // DATAFORMAT_FLOAT_MAT4X2
-	{ DATA_BASETYPE_FLOAT, true, 0, 4, 3, 4, 4, 48 }, // DATAFORMAT_FLOAT_MAT4X3
-	{ DATA_BASETYPE_FLOAT, true, 0, 4, 4, 4, 4, 64 }, // DATAFORMAT_FLOAT_MAT4X4
-
-	{ DATA_BASETYPE_INT, false, 1, 0, 0, 4, 4, 4  }, // DATAFORMAT_INT32
-	{ DATA_BASETYPE_INT, false, 2, 0, 0, 4, 4, 8  }, // DATAFORMAT_INT32_VEC2
-	{ DATA_BASETYPE_INT, false, 3, 0, 0, 4, 4, 12 }, // DATAFORMAT_INT32_VEC3
-	{ DATA_BASETYPE_INT, false, 4, 0, 0, 4, 4, 16 }, // DATAFORMAT_INT32_VEC4
-
-	{ DATA_BASETYPE_UINT, false, 1, 0, 0, 4, 4, 4  }, // DATAFORMAT_UINT32
-	{ DATA_BASETYPE_UINT, false, 2, 0, 0, 4, 4, 8  }, // DATAFORMAT_UINT32_VEC2
-	{ DATA_BASETYPE_UINT, false, 3, 0, 0, 4, 4, 12 }, // DATAFORMAT_UINT32_VEC3
-	{ DATA_BASETYPE_UINT, false, 4, 0, 0, 4, 4, 16 }, // DATAFORMAT_UINT32_VEC4
-
-	{ DATA_BASETYPE_SNORM, false, 4, 0, 0, 1, 1, 4 }, // DATAFORMAT_SNORM8_VEC4
-	{ DATA_BASETYPE_UNORM, false, 4, 0, 0, 1, 1, 4 }, // DATAFORMAT_UNORM8_VEC4
-	{ DATA_BASETYPE_INT,   false, 4, 0, 0, 1, 1, 4 }, // DATAFORMAT_INT8_VEC4
-	{ DATA_BASETYPE_UINT,  false, 4, 0, 0, 1, 1, 4 }, // DATAFORMAT_UINT8_VEC4
-
-	{ DATA_BASETYPE_SNORM, false, 2, 0, 0, 2, 2, 4 }, // DATAFORMAT_SNORM16_VEC2
-	{ DATA_BASETYPE_SNORM, false, 4, 0, 0, 2, 2, 8 }, // DATAFORMAT_SNORM16_VEC4
-
-	{ DATA_BASETYPE_UNORM, false, 2, 0, 0, 2, 2, 4 }, // DATAFORMAT_UNORM16_VEC2
-	{ DATA_BASETYPE_UNORM, false, 4, 0, 0, 2, 2, 8 }, // DATAFORMAT_UNORM16_VEC4
-
-	{ DATA_BASETYPE_INT, false, 2, 0, 0, 2, 2, 4 }, // DATAFORMAT_INT16_VEC2
-	{ DATA_BASETYPE_INT, false, 4, 0, 0, 2, 2, 8 }, // DATAFORMAT_INT16_VEC4
-
-	{ DATA_BASETYPE_UINT, false, 1, 0, 0, 2, 2, 2 }, // DATAFORMAT_UINT16
-	{ DATA_BASETYPE_UINT, false, 2, 0, 0, 2, 2, 4 }, // DATAFORMAT_UINT16_VEC2
-	{ DATA_BASETYPE_UINT, false, 4, 0, 0, 2, 2, 8 }, // DATAFORMAT_UINT16_VEC4
-
-	{ DATA_BASETYPE_BOOL, false, 1, 0, 0, 4, 4, 4  }, // DATAFORMAT_BOOL
-	{ DATA_BASETYPE_BOOL, false, 2, 0, 0, 4, 4, 8  }, // DATAFORMAT_BOOL_VEC2
-	{ DATA_BASETYPE_BOOL, false, 3, 0, 0, 4, 4, 12 }, // DATAFORMAT_BOOL_VEC3
-	{ DATA_BASETYPE_BOOL, false, 4, 0, 0, 4, 4, 16 }, // DATAFORMAT_BOOL_VEC4
+	// baseType, isMatrix, components, rows, columns, componentSize, size
+	{ DATA_BASETYPE_FLOAT, false, 1, 0, 0, 4, 4  }, // DATAFORMAT_FLOAT
+	{ DATA_BASETYPE_FLOAT, false, 2, 0, 0, 4, 8  }, // DATAFORMAT_FLOAT_VEC2
+	{ DATA_BASETYPE_FLOAT, false, 3, 0, 0, 4, 12 }, // DATAFORMAT_FLOAT_VEC3
+	{ DATA_BASETYPE_FLOAT, false, 4, 0, 0, 4, 16 }, // DATAFORMAT_FLOAT_VEC4
+
+	{ DATA_BASETYPE_FLOAT, true, 0, 2, 2, 4, 16 }, // DATAFORMAT_FLOAT_MAT2X2
+	{ DATA_BASETYPE_FLOAT, true, 0, 2, 3, 4, 24 }, // DATAFORMAT_FLOAT_MAT2X3
+	{ DATA_BASETYPE_FLOAT, true, 0, 2, 4, 4, 32 }, // DATAFORMAT_FLOAT_MAT2X4
+
+	{ DATA_BASETYPE_FLOAT, true, 0, 3, 2, 4, 24 }, // DATAFORMAT_FLOAT_MAT3X2
+	{ DATA_BASETYPE_FLOAT, true, 0, 3, 3, 4, 36 }, // DATAFORMAT_FLOAT_MAT3X3
+	{ DATA_BASETYPE_FLOAT, true, 0, 3, 4, 4, 48 }, // DATAFORMAT_FLOAT_MAT3X4
+
+	{ DATA_BASETYPE_FLOAT, true, 0, 4, 2, 4, 32 }, // DATAFORMAT_FLOAT_MAT4X2
+	{ DATA_BASETYPE_FLOAT, true, 0, 4, 3, 4, 48 }, // DATAFORMAT_FLOAT_MAT4X3
+	{ DATA_BASETYPE_FLOAT, true, 0, 4, 4, 4, 64 }, // DATAFORMAT_FLOAT_MAT4X4
+
+	{ DATA_BASETYPE_INT, false, 1, 0, 0, 4, 4  }, // DATAFORMAT_INT32
+	{ DATA_BASETYPE_INT, false, 2, 0, 0, 4, 8  }, // DATAFORMAT_INT32_VEC2
+	{ DATA_BASETYPE_INT, false, 3, 0, 0, 4, 12 }, // DATAFORMAT_INT32_VEC3
+	{ DATA_BASETYPE_INT, false, 4, 0, 0, 4, 16 }, // DATAFORMAT_INT32_VEC4
+
+	{ DATA_BASETYPE_UINT, false, 1, 0, 0, 4, 4  }, // DATAFORMAT_UINT32
+	{ DATA_BASETYPE_UINT, false, 2, 0, 0, 4, 8  }, // DATAFORMAT_UINT32_VEC2
+	{ DATA_BASETYPE_UINT, false, 3, 0, 0, 4, 12 }, // DATAFORMAT_UINT32_VEC3
+	{ DATA_BASETYPE_UINT, false, 4, 0, 0, 4, 16 }, // DATAFORMAT_UINT32_VEC4
+
+	{ DATA_BASETYPE_SNORM, false, 4, 0, 0, 1, 4 }, // DATAFORMAT_SNORM8_VEC4
+	{ DATA_BASETYPE_UNORM, false, 4, 0, 0, 1, 4 }, // DATAFORMAT_UNORM8_VEC4
+	{ DATA_BASETYPE_INT,   false, 4, 0, 0, 1, 4 }, // DATAFORMAT_INT8_VEC4
+	{ DATA_BASETYPE_UINT,  false, 4, 0, 0, 1, 4 }, // DATAFORMAT_UINT8_VEC4
+
+	{ DATA_BASETYPE_SNORM, false, 2, 0, 0, 2, 4 }, // DATAFORMAT_SNORM16_VEC2
+	{ DATA_BASETYPE_SNORM, false, 4, 0, 0, 2, 8 }, // DATAFORMAT_SNORM16_VEC4
+
+	{ DATA_BASETYPE_UNORM, false, 2, 0, 0, 2, 4 }, // DATAFORMAT_UNORM16_VEC2
+	{ DATA_BASETYPE_UNORM, false, 4, 0, 0, 2, 8 }, // DATAFORMAT_UNORM16_VEC4
+
+	{ DATA_BASETYPE_INT, false, 2, 0, 0, 2, 4 }, // DATAFORMAT_INT16_VEC2
+	{ DATA_BASETYPE_INT, false, 4, 0, 0, 2, 8 }, // DATAFORMAT_INT16_VEC4
+
+	{ DATA_BASETYPE_UINT, false, 1, 0, 0, 2, 2 }, // DATAFORMAT_UINT16
+	{ DATA_BASETYPE_UINT, false, 2, 0, 0, 2, 4 }, // DATAFORMAT_UINT16_VEC2
+	{ DATA_BASETYPE_UINT, false, 4, 0, 0, 2, 8 }, // DATAFORMAT_UINT16_VEC4
+
+	{ DATA_BASETYPE_BOOL, false, 1, 0, 0, 4, 4  }, // DATAFORMAT_BOOL
+	{ DATA_BASETYPE_BOOL, false, 2, 0, 0, 4, 8  }, // DATAFORMAT_BOOL_VEC2
+	{ DATA_BASETYPE_BOOL, false, 3, 0, 0, 4, 12 }, // DATAFORMAT_BOOL_VEC3
+	{ DATA_BASETYPE_BOOL, false, 4, 0, 0, 4, 16 }, // DATAFORMAT_BOOL_VEC4
 };
 
 static_assert((sizeof(dataFormatInfo) / sizeof(DataFormatInfo)) == DATAFORMAT_MAX_ENUM, "dataFormatInfo array size must match number of DataFormat enum values.");

+ 0 - 3
src/modules/graphics/vertex.h

@@ -58,8 +58,6 @@ enum BufferType
 {
 	BUFFERTYPE_VERTEX = 0,
 	BUFFERTYPE_INDEX,
-	BUFFERTYPE_UNIFORM,
-	BUFFERTYPE_SHADER_STORAGE,
 	BUFFERTYPE_MAX_ENUM
 };
 
@@ -218,7 +216,6 @@ struct DataFormatInfo
 	int matrixRows;
 	int matrixColumns;
 	size_t componentSize;
-	size_t alignment;
 	size_t size;
 };
 

+ 154 - 0
src/modules/graphics/wrap_Buffer.cpp

@@ -26,6 +26,160 @@ namespace love
 namespace graphics
 {
 
+static const double defaultComponents[] = {0.0, 0.0, 0.0, 1.0};
+
+template <typename T>
+static inline size_t writeData(lua_State *L, int startidx, int components, char *data)
+{
+	auto componentdata = (T *) data;
+
+	for (int i = 0; i < components; i++)
+		componentdata[i] = (T) (luaL_optnumber(L, startidx + i, defaultComponents[i]));
+
+	return sizeof(T) * components;
+}
+
+template <typename T>
+static inline size_t writeSNormData(lua_State *L, int startidx, int components, char *data)
+{
+	auto componentdata = (T *) data;
+	const auto maxval = std::numeric_limits<T>::max();
+
+	for (int i = 0; i < components; i++)
+		componentdata[i] = (T) (luax_optnumberclamped(L, startidx + i, -1.0, 1.0, defaultComponents[i]) * maxval);
+
+	return sizeof(T) * components;
+}
+
+template <typename T>
+static inline size_t writeUNormData(lua_State *L, int startidx, int components, char *data)
+{
+	auto componentdata = (T *) data;
+	const auto maxval = std::numeric_limits<T>::max();
+
+	for (int i = 0; i < components; i++)
+		componentdata[i] = (T) (luax_optnumberclamped01(L, startidx + i, 1.0) * maxval);
+
+	return sizeof(T) * components;
+}
+
+void luax_writebufferdata(lua_State *L, int startidx, DataFormat format, char *data)
+{
+	switch (format)
+	{
+		case DATAFORMAT_FLOAT:      writeData<float>(L, startidx, 1, data); break;
+		case DATAFORMAT_FLOAT_VEC2: writeData<float>(L, startidx, 2, data); break;
+		case DATAFORMAT_FLOAT_VEC3: writeData<float>(L, startidx, 3, data); break;
+		case DATAFORMAT_FLOAT_VEC4: writeData<float>(L, startidx, 4, data); break;
+
+		case DATAFORMAT_INT32:      writeData<int32>(L, startidx, 1, data); break;
+		case DATAFORMAT_INT32_VEC2: writeData<int32>(L, startidx, 2, data); break;
+		case DATAFORMAT_INT32_VEC3: writeData<int32>(L, startidx, 3, data); break;
+		case DATAFORMAT_INT32_VEC4: writeData<int32>(L, startidx, 4, data); break;
+
+		case DATAFORMAT_UINT32:      writeData<uint32>(L, startidx, 1, data); break;
+		case DATAFORMAT_UINT32_VEC2: writeData<uint32>(L, startidx, 2, data); break;
+		case DATAFORMAT_UINT32_VEC3: writeData<uint32>(L, startidx, 3, data); break;
+		case DATAFORMAT_UINT32_VEC4: writeData<uint32>(L, startidx, 4, data); break;
+
+		case DATAFORMAT_SNORM8_VEC4: writeSNormData<int8>(L, startidx, 4, data); break;
+		case DATAFORMAT_UNORM8_VEC4: writeUNormData<uint8>(L, startidx, 4, data); break;
+		case DATAFORMAT_INT8_VEC4:   writeData<int8>(L, startidx, 4, data); break;
+		case DATAFORMAT_UINT8_VEC4:  writeData<uint8>(L, startidx, 4, data); break;
+
+		case DATAFORMAT_SNORM16_VEC2: writeSNormData<int16>(L, startidx, 2, data); break;
+		case DATAFORMAT_SNORM16_VEC4: writeSNormData<int16>(L, startidx, 4, data); break;
+
+		case DATAFORMAT_UNORM16_VEC2: writeUNormData<uint16>(L, startidx, 2, data); break;
+		case DATAFORMAT_UNORM16_VEC4: writeUNormData<uint16>(L, startidx, 4, data); break;
+
+		case DATAFORMAT_INT16_VEC2: writeData<int16>(L, startidx, 2, data); break;
+		case DATAFORMAT_INT16_VEC4: writeData<int16>(L, startidx, 4, data); break;
+
+		case DATAFORMAT_UINT16:      writeData<uint16>(L, startidx, 1, data); break;
+		case DATAFORMAT_UINT16_VEC2: writeData<uint16>(L, startidx, 2, data); break;
+		case DATAFORMAT_UINT16_VEC4: writeData<uint16>(L, startidx, 4, data); break;
+
+		default: break;
+	}
+}
+
+template <typename T>
+static inline size_t readData(lua_State *L, int components, const char *data)
+{
+	const auto componentdata = (const T *) data;
+
+	for (int i = 0; i < components; i++)
+		lua_pushnumber(L, (lua_Number) componentdata[i]);
+
+	return sizeof(T) * components;
+}
+
+template <typename T>
+static inline size_t readSNormData(lua_State *L, int components, const char *data)
+{
+	const auto componentdata = (const T *) data;
+	const auto maxval = std::numeric_limits<T>::max();
+
+	for (int i = 0; i < components; i++)
+		lua_pushnumber(L, std::max(-1.0, (lua_Number) componentdata[i] / (lua_Number)maxval));
+
+	return sizeof(T) * components;
+}
+
+template <typename T>
+static inline size_t readUNormData(lua_State *L, int components, const char *data)
+{
+	const auto componentdata = (const T *) data;
+	const auto maxval = std::numeric_limits<T>::max();
+
+	for (int i = 0; i < components; i++)
+		lua_pushnumber(L, (lua_Number) componentdata[i] / (lua_Number)maxval);
+
+	return sizeof(T) * components;
+}
+
+void luax_readbufferdata(lua_State *L, DataFormat format, const char *data)
+{
+	switch (format)
+	{
+		case DATAFORMAT_FLOAT:      readData<float>(L, 1, data); break;
+		case DATAFORMAT_FLOAT_VEC2: readData<float>(L, 2, data); break;
+		case DATAFORMAT_FLOAT_VEC3: readData<float>(L, 3, data); break;
+		case DATAFORMAT_FLOAT_VEC4: readData<float>(L, 4, data); break;
+
+		case DATAFORMAT_INT32:      readData<int32>(L, 1, data); break;
+		case DATAFORMAT_INT32_VEC2: readData<int32>(L, 2, data); break;
+		case DATAFORMAT_INT32_VEC3: readData<int32>(L, 3, data); break;
+		case DATAFORMAT_INT32_VEC4: readData<int32>(L, 4, data); break;
+
+		case DATAFORMAT_UINT32:      readData<uint32>(L, 1, data); break;
+		case DATAFORMAT_UINT32_VEC2: readData<uint32>(L, 2, data); break;
+		case DATAFORMAT_UINT32_VEC3: readData<uint32>(L, 3, data); break;
+		case DATAFORMAT_UINT32_VEC4: readData<uint32>(L, 4, data); break;
+
+		case DATAFORMAT_SNORM8_VEC4: readSNormData<int8>(L, 4, data); break;
+		case DATAFORMAT_UNORM8_VEC4: readUNormData<uint8>(L, 4, data); break;
+		case DATAFORMAT_INT8_VEC4:   readData<int8>(L, 4, data); break;
+		case DATAFORMAT_UINT8_VEC4:  readData<uint8>(L, 4, data); break;
+
+		case DATAFORMAT_SNORM16_VEC2: readSNormData<int16>(L, 2, data); break;
+		case DATAFORMAT_SNORM16_VEC4: readSNormData<int16>(L, 4, data); break;
+
+		case DATAFORMAT_UNORM16_VEC2: readUNormData<uint16>(L, 2, data); break;
+		case DATAFORMAT_UNORM16_VEC4: readUNormData<uint16>(L, 4, data); break;
+
+		case DATAFORMAT_INT16_VEC2: readData<int16>(L, 2, data); break;
+		case DATAFORMAT_INT16_VEC4: readData<int16>(L, 4, data); break;
+
+		case DATAFORMAT_UINT16:      readData<uint16>(L, 1, data); break;
+		case DATAFORMAT_UINT16_VEC2: readData<uint16>(L, 2, data); break;
+		case DATAFORMAT_UINT16_VEC4: readData<uint16>(L, 4, data); break;
+
+		default: break;
+	}
+}
+
 Buffer *luax_checkbuffer(lua_State *L, int idx)
 {
 	return luax_checktype<Buffer>(L, idx);

+ 3 - 1
src/modules/graphics/wrap_Buffer.h

@@ -22,13 +22,15 @@
 
 // LOVE
 #include "common/runtime.h"
+#include "Buffer.h"
 
 namespace love
 {
 namespace graphics
 {
 
-class Buffer;
+void luax_writebufferdata(lua_State *L, int startidx, DataFormat format, char *data);
+void luax_readbufferdata(lua_State *L, DataFormat format, const char *data);
 
 Buffer *luax_checkbuffer(lua_State *L, int idx);
 extern "C" int luaopen_graphicsbuffer(lua_State *L);

+ 3 - 4
src/modules/graphics/wrap_Graphics.cpp

@@ -1704,19 +1704,18 @@ static Mesh *newCustomMesh(lua_State *L)
 			for (size_t i = 0; i < vertexformat.size(); i++)
 			{
 				const auto &info = getDataFormatInfo(vertexformat[i].format);
-				int components = info.components;
 
 				// get vertices[vertindex][n]
-				for (int c = 0; c < components; c++)
+				for (int c = 0; c < info.components; c++)
 				{
 					n++;
 					lua_rawgeti(L, -(c + 1), n);
 				}
 
 				// Fetch the values from Lua and store them in data buffer.
-				luax_writeAttributeData(L, -components, vertexformat[i].format, components, data);
+				luax_writebufferdata(L, -info.components, vertexformat[i].format, data);
 
-				lua_pop(L, components);
+				lua_pop(L, info.components);
 
 				luax_catchexcept(L,
 					[&](){ t->setVertexAttribute(vertindex, i, data, sizeof(float) * 4); },

+ 11 - 191
src/modules/graphics/wrap_Mesh.cpp

@@ -20,6 +20,7 @@
 
 // LOVE
 #include "wrap_Mesh.h"
+#include "wrap_Buffer.h"
 #include "Texture.h"
 #include "wrap_Texture.h"
 
@@ -36,184 +37,6 @@ Mesh *luax_checkmesh(lua_State *L, int idx)
 	return luax_checktype<Mesh>(L, idx);
 }
 
-static const double defaultComponents[] = {0.0, 0.0, 0.0, 1.0};
-
-template <typename T>
-static inline size_t writeData(lua_State *L, int startidx, int components, char *data)
-{
-	auto componentdata = (T *) data;
-
-	for (int i = 0; i < components; i++)
-		componentdata[i] = (T) (luaL_optnumber(L, startidx + i, defaultComponents[i]));
-
-	return sizeof(T) * components;
-}
-
-template <typename T>
-static inline size_t writeSNormData(lua_State *L, int startidx, int components, char *data)
-{
-	auto componentdata = (T *) data;
-	const auto maxval = std::numeric_limits<T>::max();
-
-	for (int i = 0; i < components; i++)
-		componentdata[i] = (T) (luax_optnumberclamped(L, startidx + i, -1.0, 1.0, defaultComponents[i]) * maxval);
-
-	return sizeof(T) * components;
-}
-
-template <typename T>
-static inline size_t writeUNormData(lua_State *L, int startidx, int components, char *data)
-{
-	auto componentdata = (T *) data;
-	const auto maxval = std::numeric_limits<T>::max();
-
-	for (int i = 0; i < components; i++)
-		componentdata[i] = (T) (luax_optnumberclamped01(L, startidx + i, 1.0) * maxval);
-
-	return sizeof(T) * components;
-}
-
-char *luax_writeAttributeData(lua_State *L, int startidx, DataFormat format, int components, char *data)
-{
-	switch (format)
-	{
-	case DATAFORMAT_FLOAT:
-	case DATAFORMAT_FLOAT_VEC2:
-	case DATAFORMAT_FLOAT_VEC3:
-	case DATAFORMAT_FLOAT_VEC4:
-		return data + writeData<float>(L, startidx, components, data);
-
-	case DATAFORMAT_INT32:
-	case DATAFORMAT_INT32_VEC2:
-	case DATAFORMAT_INT32_VEC3:
-	case DATAFORMAT_INT32_VEC4:
-		return data + writeData<int32>(L, startidx, components, data);
-
-	case DATAFORMAT_UINT32:
-	case DATAFORMAT_UINT32_VEC2:
-	case DATAFORMAT_UINT32_VEC3:
-	case DATAFORMAT_UINT32_VEC4:
-		return data + writeData<uint32>(L, startidx, components, data);
-
-	case DATAFORMAT_SNORM8_VEC4:
-		return data + writeSNormData<int8>(L, startidx, 4, data);
-	case DATAFORMAT_UNORM8_VEC4:
-		return data + writeUNormData<uint8>(L, startidx, 4, data);
-	case DATAFORMAT_INT8_VEC4:
-		return data + writeData<int8>(L, startidx, 4, data);
-	case DATAFORMAT_UINT8_VEC4:
-		return data + writeData<uint8>(L, startidx, 4, data);
-
-	case DATAFORMAT_SNORM16_VEC2:
-	case DATAFORMAT_SNORM16_VEC4:
-		return data + writeSNormData<int16>(L, startidx, components, data);
-
-	case DATAFORMAT_UNORM16_VEC2:
-	case DATAFORMAT_UNORM16_VEC4:
-		return data + writeUNormData<uint16>(L, startidx, components, data);
-
-	case DATAFORMAT_INT16_VEC2:
-	case DATAFORMAT_INT16_VEC4:
-		return data + writeData<int16>(L, startidx, components, data);
-
-	case DATAFORMAT_UINT16:
-	case DATAFORMAT_UINT16_VEC2:
-	case DATAFORMAT_UINT16_VEC4:
-		return data + writeData<uint16>(L, startidx, components, data);
-
-	default:
-		return data;
-	}
-}
-
-template <typename T>
-static inline size_t readData(lua_State *L, int components, const char *data)
-{
-	const auto componentdata = (const T *) data;
-
-	for (int i = 0; i < components; i++)
-		lua_pushnumber(L, (lua_Number) componentdata[i]);
-
-	return sizeof(T) * components;
-}
-
-template <typename T>
-static inline size_t readSNormData(lua_State *L, int components, const char *data)
-{
-	const auto componentdata = (const T *) data;
-	const auto maxval = std::numeric_limits<T>::max();
-
-	for (int i = 0; i < components; i++)
-		lua_pushnumber(L, std::max(-1.0, (lua_Number) componentdata[i] / (lua_Number)maxval));
-
-	return sizeof(T) * components;
-}
-
-template <typename T>
-static inline size_t readUNormData(lua_State *L, int components, const char *data)
-{
-	const auto componentdata = (const T *) data;
-	const auto maxval = std::numeric_limits<T>::max();
-
-	for (int i = 0; i < components; i++)
-		lua_pushnumber(L, (lua_Number) componentdata[i] / (lua_Number)maxval);
-
-	return sizeof(T) * components;
-}
-
-const char *luax_readAttributeData(lua_State *L, DataFormat format, int components, const char *data)
-{
-	switch (format)
-	{
-	case DATAFORMAT_FLOAT:
-	case DATAFORMAT_FLOAT_VEC2:
-	case DATAFORMAT_FLOAT_VEC3:
-	case DATAFORMAT_FLOAT_VEC4:
-		return data + readData<float>(L, components, data);
-
-	case DATAFORMAT_INT32:
-	case DATAFORMAT_INT32_VEC2:
-	case DATAFORMAT_INT32_VEC3:
-	case DATAFORMAT_INT32_VEC4:
-		return data + readData<int32>(L, components, data);
-
-	case DATAFORMAT_UINT32:
-	case DATAFORMAT_UINT32_VEC2:
-	case DATAFORMAT_UINT32_VEC3:
-	case DATAFORMAT_UINT32_VEC4:
-		return data + readData<uint32>(L, components, data);
-
-	case DATAFORMAT_SNORM8_VEC4:
-		return data + readSNormData<int8>(L, 4, data);
-	case DATAFORMAT_UNORM8_VEC4:
-		return data + readUNormData<uint8>(L, 4, data);
-	case DATAFORMAT_INT8_VEC4:
-		return data + readData<int8>(L, 4, data);
-	case DATAFORMAT_UINT8_VEC4:
-		return data + readData<uint8>(L, 4, data);
-
-	case DATAFORMAT_SNORM16_VEC2:
-	case DATAFORMAT_SNORM16_VEC4:
-		return data + readSNormData<int16>(L, components, data);
-
-	case DATAFORMAT_UNORM16_VEC2:
-	case DATAFORMAT_UNORM16_VEC4:
-		return data + readUNormData<uint16>(L, components, data);
-
-	case DATAFORMAT_INT16_VEC2:
-	case DATAFORMAT_INT16_VEC4:
-		return data + readData<int16>(L, components, data);
-
-	case DATAFORMAT_UINT16:
-	case DATAFORMAT_UINT16_VEC2:
-	case DATAFORMAT_UINT16_VEC4:
-		return data + readData<uint16>(L, components, data);
-
-	default:
-		return data;
-	}
-}
-
 int w_Mesh_setVertices(lua_State *L)
 {
 	Mesh *t = luax_checkmesh(L, 1);
@@ -282,11 +105,13 @@ int w_Mesh_setVertices(lua_State *L)
 		for (const Buffer::DataMember &member : vertexformat)
 		{
 			// Fetch the values from Lua and store them in data buffer.
-			data = luax_writeAttributeData(L, idx, member.decl.format, member.info.components, data);
+			luax_writebufferdata(L, idx, member.decl.format, data + member.offset);
 			idx += member.info.components;
 		}
 
 		lua_pop(L, ncomponents + 1);
+
+		data += stride;
 	}
 
 	t->unmapVertexData(byteoffset, vertcount * stride);
@@ -301,9 +126,7 @@ int w_Mesh_setVertex(lua_State *L)
 	bool istable = lua_istable(L, 3);
 
 	const std::vector<Buffer::DataMember> &vertexformat = t->getVertexFormat();
-
 	char *data = (char *) t->getVertexScratchBuffer();
-	char *writtendata = data;
 
 	int idx = istable ? 1 : 3;
 
@@ -317,7 +140,7 @@ int w_Mesh_setVertex(lua_State *L)
 				lua_rawgeti(L, 3, i);
 
 			// Fetch the values from Lua and store them in data buffer.
-			writtendata = luax_writeAttributeData(L, -components, member.decl.format, components, writtendata);
+			luax_writebufferdata(L, -components, member.decl.format, data + member.offset);
 
 			idx += components;
 			lua_pop(L, components);
@@ -328,9 +151,8 @@ int w_Mesh_setVertex(lua_State *L)
 		for (const Buffer::DataMember &member : vertexformat)
 		{
 			// Fetch the values from Lua and store them in data buffer.
-			int components = member.info.components;
-			writtendata = luax_writeAttributeData(L, idx, member.decl.format, components, writtendata);
-			idx += components;
+			luax_writebufferdata(L, idx, member.decl.format, data + member.offset);
+			idx += member.info.components;
 		}
 	}
 
@@ -346,7 +168,6 @@ int w_Mesh_getVertex(lua_State *L)
 	const std::vector<Buffer::DataMember> &vertexformat = t->getVertexFormat();
 
 	char *data = (char *) t->getVertexScratchBuffer();
-	const char *readdata = data;
 
 	luax_catchexcept(L, [&](){ t->getVertex(index, data, t->getVertexStride()); });
 
@@ -354,9 +175,8 @@ int w_Mesh_getVertex(lua_State *L)
 
 	for (const Buffer::DataMember &member : vertexformat)
 	{
-		int components = member.info.components;
-		readdata = luax_readAttributeData(L, member.decl.format, components, readdata);
-		n += components;
+		luax_readbufferdata(L, member.decl.format, data + member.offset);
+		n += member.info.components;
 	}
 
 	return n;
@@ -379,7 +199,7 @@ int w_Mesh_setVertexAttribute(lua_State *L)
 	char data[sizeof(float) * 4];
 
 	// Fetch the values from Lua and store them in the data buffer.
-	luax_writeAttributeData(L, 4, member.decl.format, member.info.components, data);
+	luax_writebufferdata(L, 4, member.decl.format, data);
 
 	luax_catchexcept(L, [&](){ t->setVertexAttribute(vertindex, attribindex, data, sizeof(float) * 4); });
 	return 0;
@@ -403,7 +223,7 @@ int w_Mesh_getVertexAttribute(lua_State *L)
 
 	luax_catchexcept(L, [&](){ t->getVertexAttribute(vertindex, attribindex, data, sizeof(float) * 4); });
 
-	luax_readAttributeData(L, member.decl.format, member.info.components, data);
+	luax_readbufferdata(L, member.decl.format, data);
 	return member.info.components;
 }
 

+ 0 - 3
src/modules/graphics/wrap_Mesh.h

@@ -30,9 +30,6 @@ namespace love
 namespace graphics
 {
 
-char *luax_writeAttributeData(lua_State *L, int startidx, DataFormat format, int components, char *data);
-const char *luax_readAttributeData(lua_State *L, DataFormat format, int components, const char *data);
-
 Mesh *luax_checkmesh(lua_State *L, int idx);
 extern "C" int luaopen_mesh(lua_State *L);