Browse Source

Add C++ side support for unsigned int shader uniforms. Note that the shader languages love currently supports (glsl 1.20, glsl es 1.00) don’t support uints at the moment.

--HG--
branch : minor
Alex Szpakowski 8 years ago
parent
commit
8899c03651

+ 1 - 1
src/modules/graphics/Color.h

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2006-2011 LOVE Development Team
+ * Copyright (c) 2006-2017 LOVE Development Team
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the authors be held liable for any damages

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

@@ -49,7 +49,7 @@ class Reference;
 namespace graphics
 {
 
-const int MAX_COLOR_RENDER_TARGETS = 16;
+const int MAX_COLOR_RENDER_TARGETS = 8;
 
 /**
  * Globally sets whether gamma correction is enabled. Ideally this should be set

+ 1 - 0
src/modules/graphics/Shader.cpp

@@ -109,6 +109,7 @@ StringMap<Shader::UniformType, Shader::UNIFORM_MAX_ENUM>::Entry Shader::uniformT
 	{"float", Shader::UNIFORM_FLOAT},
 	{"matrix", Shader::UNIFORM_MATRIX},
 	{"int", Shader::UNIFORM_INT},
+	{"uint", Shader::UNIFORM_UINT},
 	{"bool", Shader::UNIFORM_BOOL},
 	{"image", Shader::UNIFORM_SAMPLER},
 	{"unknown", Shader::UNIFORM_UNKNOWN},

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

@@ -71,6 +71,7 @@ public:
 		UNIFORM_FLOAT,
 		UNIFORM_MATRIX,
 		UNIFORM_INT,
+		UNIFORM_UINT,
 		UNIFORM_BOOL,
 		UNIFORM_SAMPLER,
 		UNIFORM_UNKNOWN,
@@ -108,6 +109,7 @@ public:
 			void *data;
 			float *floats;
 			int *ints;
+			unsigned int *uints;
 		};
 
 		Texture **textures;

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

@@ -340,7 +340,7 @@ void OpenGL::prepareDraw()
 
 	// Make sure the active shader's love-provided uniforms are up to date.
 	if (Shader::current != nullptr)
-		((Shader *)Shader::current)->checkSetBuiltinUniforms();
+		((Shader *)Shader::current)->updateBuiltinUniforms();
 
 	if (state.constantColor != state.lastConstantColor)
 	{

+ 41 - 6
src/modules/graphics/opengl/Shader.cpp

@@ -237,6 +237,10 @@ void Shader::mapActiveUniforms()
 				datasize = sizeof(int) * u.components * u.count;
 				u.data = malloc(datasize);
 				break;
+			case UNIFORM_UINT:
+				datasize = sizeof(unsigned int) * u.components * u.count;
+				u.data = malloc(datasize);
+				break;
 			case UNIFORM_MATRIX:
 				datasize = sizeof(float) * (u.matrix.rows * u.matrix.columns) * u.count;
 				u.data = malloc(datasize);
@@ -291,6 +295,10 @@ void Shader::mapActiveUniforms()
 					glGetUniformiv(program, location, &u.ints[offset]);
 					offset += u.components;
 					break;
+				case UNIFORM_UINT:
+					glGetUniformuiv(program, location, &u.uints[offset]);
+					offset += u.components;
+					break;
 				case UNIFORM_MATRIX:
 					glGetUniformfv(program, location, &u.floats[offset]);
 					offset += u.matrix.rows * u.matrix.columns;
@@ -427,7 +435,7 @@ bool Shader::loadVolatile()
 		// make sure glUseProgram gets called.
 		current = nullptr;
 		attach();
-		checkSetBuiltinUniforms();
+		updateBuiltinUniforms();
 	}
 
 	return true;
@@ -581,6 +589,24 @@ void Shader::updateUniform(const UniformInfo *info, int count, bool internalUpda
 			break;
 		}
 	}
+	else if (type == UNIFORM_UINT)
+	{
+		switch (info->components)
+		{
+		case 1:
+			glUniform1uiv(location, count, info->uints);
+			break;
+		case 2:
+			glUniform2uiv(location, count, info->uints);
+			break;
+		case 3:
+			glUniform3uiv(location, count, info->uints);
+			break;
+		case 4:
+			glUniform4uiv(location, count, info->uints);
+			break;
+		}
+	}
 	else if (type == UNIFORM_MATRIX)
 	{
 		int columns = info->matrix.columns;
@@ -764,7 +790,7 @@ void Shader::setVideoTextures(ptrdiff_t ytexture, ptrdiff_t cbtexture, ptrdiff_t
 	}
 }
 
-void Shader::checkSetScreenParams()
+void Shader::updateScreenParams()
 {
 	Rect view = gl.getViewport();
 
@@ -804,7 +830,7 @@ void Shader::checkSetScreenParams()
 	lastViewport = view;
 }
 
-void Shader::checkSetPointSize(float size)
+void Shader::updatePointSize(float size)
 {
 	if (size == lastPointSize || current != this)
 		return;
@@ -816,15 +842,15 @@ void Shader::checkSetPointSize(float size)
 	lastPointSize = size;
 }
 
-void Shader::checkSetBuiltinUniforms()
+void Shader::updateBuiltinUniforms()
 {
 	if (current != this)
 		return;
 
-	checkSetScreenParams();
+	updateScreenParams();
 
 	if (GLAD_ES_VERSION_2_0)
-		checkSetPointSize(gl.getPointSize());
+		updatePointSize(gl.getPointSize());
 
 	auto gfx = Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS);
 
@@ -902,6 +928,7 @@ int Shader::getUniformTypeComponents(GLenum type) const
 	switch (type)
 	{
 	case GL_INT:
+	case GL_UNSIGNED_INT:
 	case GL_FLOAT:
 	case GL_BOOL:
 	case GL_SAMPLER_1D:
@@ -909,16 +936,19 @@ int Shader::getUniformTypeComponents(GLenum type) const
 	case GL_SAMPLER_3D:
 		return 1;
 	case GL_INT_VEC2:
+	case GL_UNSIGNED_INT_VEC2:
 	case GL_FLOAT_VEC2:
 	case GL_FLOAT_MAT2:
 	case GL_BOOL_VEC2:
 		return 2;
 	case GL_INT_VEC3:
+	case GL_UNSIGNED_INT_VEC3:
 	case GL_FLOAT_VEC3:
 	case GL_FLOAT_MAT3:
 	case GL_BOOL_VEC3:
 		return 3;
 	case GL_INT_VEC4:
+	case GL_UNSIGNED_INT_VEC4:
 	case GL_FLOAT_VEC4:
 	case GL_FLOAT_MAT4:
 	case GL_BOOL_VEC4:
@@ -981,6 +1011,11 @@ Shader::UniformType Shader::getUniformBaseType(GLenum type) const
 	case GL_INT_VEC3:
 	case GL_INT_VEC4:
 		return UNIFORM_INT;
+	case GL_UNSIGNED_INT:
+	case GL_UNSIGNED_INT_VEC2:
+	case GL_UNSIGNED_INT_VEC3:
+	case GL_UNSIGNED_INT_VEC4:
+		return UNIFORM_UINT;
 	case GL_FLOAT:
 	case GL_FLOAT_VEC2:
 	case GL_FLOAT_VEC3:

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

@@ -66,9 +66,9 @@ public:
 
 	GLint getAttribLocation(const std::string &name);
 
-	void checkSetScreenParams();
-	void checkSetPointSize(float size);
-	void checkSetBuiltinUniforms();
+	void updateScreenParams();
+	void updatePointSize(float size);
+	void updateBuiltinUniforms();
 
 	GLuint getProgram() const
 	{

+ 10 - 0
src/modules/graphics/wrap_Shader.cpp

@@ -108,6 +108,14 @@ int w_Shader_sendInts(lua_State *L, int startidx, Shader *shader, const Shader::
 	return 0;
 }
 
+int w_Shader_sendUnsignedInts(lua_State *L, int startidx, Shader *shader, const Shader::UniformInfo *info)
+{
+	int count = _getCount(L, startidx, info);
+	_updateNumbers(L, startidx, info->uints, info->components, count);
+	luax_catchexcept(L, [&]() { shader->updateUniform(info, count); });
+	return 0;
+}
+
 int w_Shader_sendBooleans(lua_State *L, int startidx, Shader *shader, const Shader::UniformInfo *info)
 {
 	int count = _getCount(L, startidx, info);
@@ -284,6 +292,8 @@ int w_Shader_send(lua_State *L)
 		return w_Shader_sendMatrices(L, startidx, shader, info);
 	case Shader::UNIFORM_INT:
 		return w_Shader_sendInts(L, startidx, shader, info);
+	case Shader::UNIFORM_UINT:
+		return w_Shader_sendUnsignedInts(L, startidx, shader, info);
 	case Shader::UNIFORM_BOOL:
 		return w_Shader_sendBooleans(L, startidx, shader, info);
 	case Shader::UNIFORM_SAMPLER: