diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index c7ba6ad3e7..fc1dac82ca 100644 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -648,6 +648,7 @@ issue_parameters(int altered) { continue; case Shader::SPT_int: + case Shader::SPT_uint: switch (spec._info._class) { case Shader::SAC_scalar: cgSetParameter1iv(p, (int*)ptr_data->_ptr); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 90bbaecf40..7ca4bd21e8 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1699,6 +1699,14 @@ reset() { get_extension_func("glUniform3iv"); _glUniform4iv = (PFNGLUNIFORM4IVPROC) get_extension_func("glUniform4iv"); + _glUniform1uiv = (PFNGLUNIFORM1UIVPROC) + get_extension_func("glUniform1uiv"); + _glUniform2uiv = (PFNGLUNIFORM2UIVPROC) + get_extension_func("glUniform2uiv"); + _glUniform3uiv = (PFNGLUNIFORM3UIVPROC) + get_extension_func("glUniform3uiv"); + _glUniform4uiv = (PFNGLUNIFORM4UIVPROC) + get_extension_func("glUniform4uiv"); _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) get_extension_func("glUniformMatrix3fv"); _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) @@ -1777,6 +1785,10 @@ reset() { _glUniform2fv = glUniform2fv; _glUniform3fv = glUniform3fv; _glUniform4fv = glUniform4fv; + _glUniform1iv = glUniform1iv; + _glUniform2iv = glUniform2iv; + _glUniform3iv = glUniform3iv; + _glUniform4iv = glUniform4iv; _glUniformMatrix3fv = glUniformMatrix3fv; _glUniformMatrix4fv = glUniformMatrix4fv; _glValidateProgram = glValidateProgram; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index d00478a58d..67de9ac54c 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -175,6 +175,10 @@ typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, con typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); +typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); +typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); @@ -984,6 +988,10 @@ public: PFNGLUNIFORM2IVPROC _glUniform2iv; PFNGLUNIFORM3IVPROC _glUniform3iv; PFNGLUNIFORM4IVPROC _glUniform4iv; + PFNGLUNIFORM1UIVPROC _glUniform1uiv; + PFNGLUNIFORM2UIVPROC _glUniform2uiv; + PFNGLUNIFORM3UIVPROC _glUniform3uiv; + PFNGLUNIFORM4UIVPROC _glUniform4uiv; PFNGLUNIFORMMATRIX3FVPROC _glUniformMatrix3fv; PFNGLUNIFORMMATRIX4FVPROC _glUniformMatrix4fv; PFNGLVALIDATEPROGRAMPROC _glValidateProgram; diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 94adf2f6a8..979c6dada1 100644 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -1501,21 +1501,29 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_INT: case GL_INT_VEC2: case GL_INT_VEC3: - case GL_INT_VEC4: { + case GL_INT_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: { Shader::ShaderPtrSpec bind; bind._id = arg_id; switch (param_type) { case GL_BOOL: case GL_INT: + case GL_UNSIGNED_INT: case GL_FLOAT: bind._dim[1] = 1; break; case GL_BOOL_VEC2: case GL_INT_VEC2: + case GL_UNSIGNED_INT_VEC2: case GL_FLOAT_VEC2: bind._dim[1] = 2; break; case GL_BOOL_VEC3: case GL_INT_VEC3: + case GL_UNSIGNED_INT_VEC3: case GL_FLOAT_VEC3: bind._dim[1] = 3; break; case GL_BOOL_VEC4: case GL_INT_VEC4: + case GL_UNSIGNED_INT_VEC4: case GL_FLOAT_VEC4: bind._dim[1] = 4; break; case GL_FLOAT_MAT3: bind._dim[1] = 9; break; case GL_FLOAT_MAT4: bind._dim[1] = 16; break; @@ -1525,6 +1533,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_BOOL_VEC2: case GL_BOOL_VEC3: case GL_BOOL_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: + bind._type = Shader::SPT_uint; + break; case GL_INT: case GL_INT_VEC2: case GL_INT_VEC3: @@ -1604,6 +1618,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_INT_VEC2: case GL_INT_VEC3: case GL_INT_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: case GL_FLOAT: case GL_FLOAT_VEC2: case GL_FLOAT_VEC3: @@ -1633,6 +1651,12 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) { case GL_BOOL_VEC2: case GL_BOOL_VEC3: case GL_BOOL_VEC4: + case GL_UNSIGNED_INT: + case GL_UNSIGNED_INT_VEC2: + case GL_UNSIGNED_INT_VEC3: + case GL_UNSIGNED_INT_VEC4: + bind._type = Shader::SPT_uint; + break; case GL_INT: case GL_INT_VEC2: case GL_INT_VEC3: @@ -2003,6 +2027,8 @@ issue_parameters(int altered) { return; } + nassertd(spec._dim[1] > 0) continue; + GLint p = spec._id._seqno; int array_size = min(spec._dim[0], (int)ptr_data->_size / spec._dim[1]); switch (spec._type) { @@ -2019,6 +2045,14 @@ issue_parameters(int altered) { } break; + case Shader::SPT_uint: + // Convert unsigned int data to float data. + data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]); + for (int i = 0; i < (array_size * spec._dim[1]); ++i) { + data[i] = (float)(((unsigned int*)ptr_data->_ptr)[i]); + } + break; + case Shader::SPT_double: // Downgrade double data to float data. data = (float*) alloca(sizeof(float) * array_size * spec._dim[1]); @@ -2048,7 +2082,8 @@ issue_parameters(int altered) { break; case Shader::SPT_int: - if (ptr_data->_type != Shader::SPT_int) { + if (ptr_data->_type != Shader::SPT_int && + ptr_data->_type != Shader::SPT_uint) { GLCAT.error() << "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n"; @@ -2068,6 +2103,28 @@ issue_parameters(int altered) { } break; + case Shader::SPT_uint: + if (ptr_data->_type != Shader::SPT_uint && + ptr_data->_type != Shader::SPT_int) { + GLCAT.error() + << "Cannot pass floating-point data to integer shader input '" << spec._id._name << "'\n"; + + // Deactivate it to make sure the user doesn't get flooded with this + // error. + spec._dep[0] = 0; + spec._dep[1] = 0; + + } else { + switch (spec._dim[1]) { + case 1: _glgsg->_glUniform1uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue; + case 2: _glgsg->_glUniform2uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue; + case 3: _glgsg->_glUniform3uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue; + case 4: _glgsg->_glUniform4uiv(p, array_size, (GLuint *)ptr_data->_ptr); continue; + } + nassertd(false) continue; + } + break; + case Shader::SPT_double: GLCAT.error() << "Passing double-precision shader inputs to GLSL shaders is not currently supported\n"; diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 8e65c005e9..1cc6533044 100644 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -346,6 +346,7 @@ public: SPT_float, SPT_double, SPT_int, + SPT_uint, SPT_unknown }; diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py index c13e99e92e..0c9c9e8e95 100644 --- a/tests/display/test_glsl_shader.py +++ b/tests/display/test_glsl_shader.py @@ -183,7 +183,6 @@ def test_glsl_int(gsg): run_glsl_test(gsg, code, preamble, inputs) -@pytest.mark.xfail def test_glsl_uint(gsg): #TODO: fix passing uints greater than intmax inputs = dict( @@ -191,8 +190,8 @@ def test_glsl_uint(gsg): intmax=0x7fffffff, ) preamble = """ - uniform unsigned int zero; - uniform unsigned int intmax; + uniform uint zero; + uniform uint intmax; """ code = """ assert(zero == 0);