From fccd9965ee5b91ca49da3a1ed637173e6e45ff7b Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 19 Sep 2013 22:44:38 +0000 Subject: [PATCH] support for using the mat3 type in a shader. make p3d_NormalMatrix a mat3. --- .../glstuff/glGraphicsStateGuardian_src.cxx | 3 ++ .../src/glstuff/glGraphicsStateGuardian_src.h | 2 + panda/src/glstuff/glShaderContext_src.cxx | 42 +++++++++++++++++-- panda/src/gobj/shader.cxx | 13 +++++- panda/src/gobj/shader.h | 4 +- 5 files changed, 59 insertions(+), 5 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index d684c4a105..95f4144e41 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1059,6 +1059,8 @@ reset() { get_extension_func(GLPREFIX_QUOTED, "Uniform3fv"); _glUniform4fv = (PFNGLUNIFORM4FVPROC) get_extension_func(GLPREFIX_QUOTED, "Uniform4fv"); + _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) + get_extension_func(GLPREFIX_QUOTED, "UniformMatrix3fv"); _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) get_extension_func(GLPREFIX_QUOTED, "UniformMatrix4fv"); _glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) @@ -1112,6 +1114,7 @@ reset() { _glUniform2fv = glUniform2fv; _glUniform3fv = glUniform3fv; _glUniform4fv = glUniform4fv; + _glUniformMatrix3fv = glUniformMatrix3fv; _glUniformMatrix4fv = glUniformMatrix4fv; _glValidateProgram = glValidateProgram; _glVertexAttribPointer = glVertexAttribPointer; diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 661162ad43..c1aa99f2aa 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -161,6 +161,7 @@ typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, con typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *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); typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); @@ -677,6 +678,7 @@ public: PFNGLUNIFORM2FVPROC _glUniform2fv; PFNGLUNIFORM3FVPROC _glUniform3fv; PFNGLUNIFORM4FVPROC _glUniform4fv; + PFNGLUNIFORMMATRIX3FVPROC _glUniformMatrix3fv; PFNGLUNIFORMMATRIX4FVPROC _glUniformMatrix4fv; PFNGLVALIDATEPROGRAMPROC _glValidateProgram; PFNGLVERTEXATTRIBPOINTERPROC _glVertexAttribPointer; diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index 225b5cbd73..281ab0cef9 100755 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -389,9 +389,9 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) { bind._dep[1] = Shader::SSD_general | Shader::SSD_transform; if (transpose) { - bind._piece = Shader::SMP_whole; + bind._piece = Shader::SMP_upper3x3; } else { - bind._piece = Shader::SMP_transpose; + bind._piece = Shader::SMP_transpose3x3; } } else { @@ -495,7 +495,6 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) { s->_tex_spec.push_back(bind); continue; } case GL_FLOAT_MAT2: - case GL_FLOAT_MAT3: #ifndef OPENGLES case GL_FLOAT_MAT2x3: case GL_FLOAT_MAT2x4: @@ -506,6 +505,19 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) { #endif GLCAT.warning() << "GLSL shader requested an unrecognized matrix type\n"; continue; + case GL_FLOAT_MAT3: { + Shader::ShaderMatSpec bind; + bind._id = arg_id; + bind._piece = Shader::SMP_upper3x3; + bind._func = Shader::SMF_first; + bind._part[0] = Shader::SMO_mat_constant_x; + bind._arg[0] = InternalName::make(param_name); + bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs; + bind._part[1] = Shader::SMO_identity; + bind._arg[1] = NULL; + bind._dep[1] = Shader::SSD_NONE; + s->_mat_spec.push_back(bind); + continue; } case GL_FLOAT_MAT4: { Shader::ShaderMatSpec bind; bind._id = arg_id; @@ -1023,6 +1035,18 @@ issue_parameters(GSG *gsg, int altered) { case Shader::SMP_row3x1: gsg->_glUniform1fv(p, 1, data+12); continue; case Shader::SMP_row3x2: gsg->_glUniform2fv(p, 1, data+12); continue; case Shader::SMP_row3x3: gsg->_glUniform3fv(p, 1, data+12); continue; + case Shader::SMP_upper3x3: + { + LMatrix3f upper3 = val->get_upper_3(); + gsg->_glUniformMatrix3fv(p, 1, false, upper3.get_data()); + continue; + } + case Shader::SMP_transpose3x3: + { + LMatrix3f upper3 = val->get_upper_3(); + gsg->_glUniformMatrix3fv(p, 1, true, upper3.get_data()); + continue; + } } } #if defined(HAVE_CG) && !defined(OPENGLES) @@ -1042,6 +1066,18 @@ issue_parameters(GSG *gsg, int altered) { case Shader::SMP_row3x1: GLfv(cgGLSetParameter1)(p, data+12); continue; case Shader::SMP_row3x2: GLfv(cgGLSetParameter2)(p, data+12); continue; case Shader::SMP_row3x3: GLfv(cgGLSetParameter3)(p, data+12); continue; + case Shader::SMP_upper3x3: + { + LMatrix3f upper3 = val->get_upper_3(); + GLfc(cgGLSetMatrixParameter)(p, upper3.get_data()); + continue; + } + case Shader::SMP_transpose3x3: + { + LMatrix3f upper3 = val->get_upper_3(); + GLfr(cgGLSetMatrixParameter)(p, upper3.get_data()); + continue; + } } } #endif diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx index b0a7f64455..8807206409 100755 --- a/panda/src/gobj/shader.cxx +++ b/panda/src/gobj/shader.cxx @@ -188,6 +188,7 @@ cp_errchk_parameter_float(ShaderArgInfo &p, int lo, int hi) case SAT_vec2: nfloat = 2; break; case SAT_vec3: nfloat = 3; break; case SAT_vec4: nfloat = 4; break; + case SAT_mat3x3: nfloat = 9; break; case SAT_mat4x4: nfloat = 16; break; default: nfloat = 0; break; } @@ -737,7 +738,17 @@ compile_parameter(const ShaderArgId &arg_id, else if (pieces[0]=="col2") bind._piece = SMP_col2; else if (pieces[0]=="col3") bind._piece = SMP_col3; if ((bind._piece == SMP_whole)||(bind._piece == SMP_transpose)) { - if (!cp_errchk_parameter_float(p, 16, 16)) return false; + if (p._type == SAT_mat3x3) { + if (!cp_errchk_parameter_float(p, 9, 9)) return false; + + if (bind._piece == SMP_transpose) { + bind._piece = SMP_transpose3x3; + } else { + bind._piece = SMP_upper3x3; + } + } else if (!cp_errchk_parameter_float(p, 16, 16)) { + return false; + } } else { if (!cp_errchk_parameter_float(p, 4, 4)) return false; } diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 7969b6e995..420fc0ab8f 100755 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -225,8 +225,10 @@ public: SMP_row3x1, SMP_row3x2, SMP_row3x3, + SMP_upper3x3, + SMP_transpose3x3, }; - + enum ShaderStateDep { SSD_NONE = 0, SSD_general = 1,