Browse Source

Add uniform mat4 p3d_TextureMatrix[] input to GLSL

rdb 10 years ago
parent
commit
96a9e22395

+ 18 - 6
panda/src/display/graphicsStateGuardian.cxx

@@ -1190,14 +1190,26 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
     }
     return &t;
   }
-  case Shader::SMO_texmat_x: {
-    const TexMatrixAttrib *tma = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
-    const TextureAttrib *ta = DCAST(TextureAttrib, _target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
-    int stagenr = atoi(name->get_name().c_str());
-    if (stagenr >= ta->get_num_on_stages()) {
+  case Shader::SMO_texmat_i: {
+    const TexMatrixAttrib *tma;
+    const TextureAttrib *ta;
+    if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
+        index < ta->get_num_on_stages()) {
+      return &tma->get_mat(ta->get_on_stage(index));
+    } else {
+      return &LMatrix4::ident_mat();
+    }
+  }
+  case Shader::SMO_inv_texmat_i: {
+    const TexMatrixAttrib *tma;
+    const TextureAttrib *ta;
+    if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
+        index < ta->get_num_on_stages()) {
+      t = tma->get_transform(ta->get_on_stage(index))->get_inverse()->get_mat();
+      return &t;
+    } else {
       return &LMatrix4::ident_mat();
     }
-    return &tma->get_mat(ta->get_on_stage(stagenr));
   }
   case Shader::SMO_plane_x: {
     const NodePath &np = _target_shader->get_shader_input_nodepath(name);

+ 7 - 2
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -9217,7 +9217,6 @@ set_state_and_transform(const RenderState *target,
   // If one of the previously-loaded TexGen modes modified the texture
   // matrix, then if either state changed, we have to change both of
   // them now.
-#ifdef SUPPORT_FIXED_FUNCTION
   if (_tex_gen_modifies_mat) {
     int tex_gen_slot = TexGenAttrib::get_class_slot();
     int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
@@ -9234,10 +9233,16 @@ set_state_and_transform(const RenderState *target,
   if (_target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
       !_state_mask.get_bit(tex_matrix_slot)) {
     //PStatGPUTimer timer(this, _draw_set_state_tex_matrix_pcollector);
+#ifdef SUPPORT_FIXED_FUNCTION
     do_issue_tex_matrix();
+#endif
     _state_mask.set_bit(tex_matrix_slot);
-  }
+#ifndef OPENGLES_1
+    if (_current_shader_context) {
+      _current_shader_context->issue_parameters(Shader::SSD_tex_matrix);
+    }
 #endif
+  }
 
 #ifdef SUPPORT_FIXED_FUNCTION
   int tex_gen_slot = TexGenAttrib::get_class_slot();

+ 27 - 2
panda/src/glstuff/glShaderContext_src.cxx

@@ -690,12 +690,16 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         } else {
           bind._piece = Shader::SMP_transpose3x3;
         }
-      } else {
+      } else if (param_type == GL_FLOAT_MAT4) {
         if (transpose) {
           bind._piece = Shader::SMP_transpose;
         } else {
           bind._piece = Shader::SMP_whole;
         }
+      } else {
+        GLCAT.error()
+          << "Matrix input p3d_" << matrix_name << " should be mat3 or mat4\n";
+        return;
       }
       bind._arg[0] = NULL;
       bind._arg[1] = NULL;
@@ -731,7 +735,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
         bind._part[1] = Shader::SMO_identity;
 
         if (param_type != GL_FLOAT_MAT3) {
-          GLCAT.error() << "p3d_NormalMatrix input should be mat3, not mat4!\n";
+          GLCAT.warning() << "p3d_NormalMatrix input should be mat3, not mat4!\n";
         }
 
       } else if (matrix_name == "ModelMatrix") {
@@ -761,6 +765,27 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
           bind._part[1] = Shader::SMO_view_to_apiclip;
         }
 
+      } else if (matrix_name == "TextureMatrix") {
+        // We may support 2-D texmats later, but let's make sure that people
+        // don't think they can just use a mat3 to get the 2-D version.
+        if (param_type != GL_FLOAT_MAT4) {
+          GLCAT.error() << "p3d_TextureMatrix should be mat4[], not mat3[]!\n";
+          return;
+        }
+
+        bind._func = Shader::SMF_first;
+        bind._part[0] = inverse ? Shader::SMO_inv_texmat_i
+                                : Shader::SMO_texmat_i;
+        bind._part[1] = Shader::SMO_identity;
+        bind._dep[0] = Shader::SSD_general | Shader::SSD_tex_matrix;
+        bind._dep[1] = 0;
+
+        // Add it once for each index.
+        for (bind._index = 0; bind._index < param_size; ++bind._index) {
+          _shader->_mat_spec.push_back(bind);
+        }
+        return;
+
       } else {
         GLCAT.error() << "Unrecognized uniform matrix name '" << matrix_name << "'!\n";
         return;

+ 6 - 2
panda/src/gobj/shader.cxx

@@ -452,6 +452,9 @@ cp_dependency(ShaderMatInput inp) {
       (inp == SMO_apiview_clipplane_i)) {
     dep |= SSD_clip_planes;
   }
+  if (inp == SMO_texmat_i || inp == SMO_inv_texmat_i) {
+    dep |= SSD_tex_matrix;
+  }
 
   return dep;
 }
@@ -1040,10 +1043,11 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
     bind._id = p._id;
     bind._piece = SMP_whole;
     bind._func = SMF_first;
-    bind._part[0] = SMO_texmat_x;
-    bind._arg[0] = InternalName::make(pieces[1]);
+    bind._part[0] = SMO_texmat_i;
+    bind._arg[0] = NULL;
     bind._part[1] = SMO_identity;
     bind._arg[1] = NULL;
+    bind._index = atoi(pieces[1].c_str());
 
     cp_optimize_mat_spec(bind);
     _mat_spec.push_back(bind);

+ 4 - 1
panda/src/gobj/shader.h

@@ -132,7 +132,7 @@ public:
     SMO_plight_x,
     SMO_slight_x,
     SMO_satten_x,
-    SMO_texmat_x,
+    SMO_texmat_i,
     SMO_plane_x,
     SMO_clipplane_x,
 
@@ -191,6 +191,8 @@ public:
     SMO_apiview_to_apiclip,
     SMO_apiclip_to_apiview,
 
+    SMO_inv_texmat_i,
+
     SMO_INVALID
   };
 
@@ -270,6 +272,7 @@ public:
     SSD_fog           = 0x040,
     SSD_light         = 0x080,
     SSD_clip_planes   = 0x100,
+    SSD_tex_matrix    = 0x200,
   };
 
   enum ShaderBug {