From 8899c03651029d1958330803d997d40bd0cc0b02 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Mon, 2 Jan 2017 20:41:07 -0400 Subject: [PATCH] =?UTF-8?q?Add=20C++=20side=20support=20for=20unsigned=20i?= =?UTF-8?q?nt=20shader=20uniforms.=20Note=20that=20the=20shader=20language?= =?UTF-8?q?s=20love=20currently=20supports=20(glsl=201.20,=20glsl=20es=201?= =?UTF-8?q?.00)=20don=E2=80=99t=20support=20uints=20at=20the=20moment.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --HG-- branch : minor --- src/modules/graphics/Color.h | 2 +- src/modules/graphics/Graphics.h | 2 +- src/modules/graphics/Shader.cpp | 1 + src/modules/graphics/Shader.h | 2 ++ src/modules/graphics/opengl/OpenGL.cpp | 2 +- src/modules/graphics/opengl/Shader.cpp | 47 ++++++++++++++++++++++---- src/modules/graphics/opengl/Shader.h | 6 ++-- src/modules/graphics/wrap_Shader.cpp | 10 ++++++ 8 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/modules/graphics/Color.h b/src/modules/graphics/Color.h index 3671bf21b..16d7db990 100644 --- a/src/modules/graphics/Color.h +++ b/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 diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 55f067ed9..0d45d71e2 100644 --- a/src/modules/graphics/Graphics.h +++ b/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 diff --git a/src/modules/graphics/Shader.cpp b/src/modules/graphics/Shader.cpp index 7a5ebd986..afdf8ec41 100644 --- a/src/modules/graphics/Shader.cpp +++ b/src/modules/graphics/Shader.cpp @@ -109,6 +109,7 @@ StringMap::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}, diff --git a/src/modules/graphics/Shader.h b/src/modules/graphics/Shader.h index 0773c4c5e..6677cbbce 100644 --- a/src/modules/graphics/Shader.h +++ b/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; diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index b731881e2..61ce4d7da 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/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) { diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index aa2aaba81..1edb874b8 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/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(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: diff --git a/src/modules/graphics/opengl/Shader.h b/src/modules/graphics/opengl/Shader.h index aea2111b9..dff221fef 100644 --- a/src/modules/graphics/opengl/Shader.h +++ b/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 { diff --git a/src/modules/graphics/wrap_Shader.cpp b/src/modules/graphics/wrap_Shader.cpp index 913b287fc..7d457bb08 100644 --- a/src/modules/graphics/wrap_Shader.cpp +++ b/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: