Browse Source

Add support for passing int arrays and vectors to GLSL shaders.

rdb 11 years ago
parent
commit
6e64ff951c

+ 13 - 4
panda/src/glstuff/glCgShaderContext_src.cxx

@@ -281,7 +281,7 @@ issue_parameters(int altered) {
           case Shader::SAC_matrix:
           case Shader::SAC_matrix:
             cgGLSetMatrixParameterArrayfc(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
             cgGLSetMatrixParameterArrayfc(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
           }
           }
-        } 
+        }
         }
         }
       case Shader::SPT_double:
       case Shader::SPT_double:
         switch(_ptr._info._class) {
         switch(_ptr._info._class) {
@@ -308,7 +308,18 @@ issue_parameters(int altered) {
           case Shader::SAC_matrix:
           case Shader::SAC_matrix:
             cgGLSetMatrixParameterArraydc(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
             cgGLSetMatrixParameterArraydc(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
           }
           }
-        } 
+        }
+        }
+      case Shader::SPT_int:
+        switch(_ptr._info._class) {
+        case Shader::SAC_scalar: cgSetParameter1iv(p,(int*)ptr_data->_ptr); continue;
+        case Shader::SAC_vector:
+          switch(_ptr._info._type) {
+          case Shader::SAT_vec1: cgSetParameter1iv(p,(int*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec2: cgSetParameter2iv(p,(int*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec3: cgSetParameter3iv(p,(int*)ptr_data->_ptr); continue;
+          case Shader::SAT_vec4: cgSetParameter4iv(p,(int*)ptr_data->_ptr); continue;
+          }
         }
         }
       default: GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n"; 
       default: GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n"; 
         release_resources(); 
         release_resources(); 
@@ -317,8 +328,6 @@ issue_parameters(int altered) {
     }
     }
   }
   }
 
 
-  //FIXME: this could be much faster if we used deferred parameter setting.
-
   for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
   for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
     if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
     if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
       const LMatrix4 *val = _glgsg->fetch_specified_value(_shader->_mat_spec[i], altered);
       const LMatrix4 *val = _glgsg->fetch_specified_value(_shader->_mat_spec[i], altered);

+ 8 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1179,6 +1179,14 @@ reset() {
        get_extension_func("glUniform3fv");
        get_extension_func("glUniform3fv");
     _glUniform4fv = (PFNGLUNIFORM4FVPROC)
     _glUniform4fv = (PFNGLUNIFORM4FVPROC)
        get_extension_func("glUniform4fv");
        get_extension_func("glUniform4fv");
+    _glUniform1iv = (PFNGLUNIFORM1IVPROC)
+       get_extension_func("glUniform1iv");
+    _glUniform2iv = (PFNGLUNIFORM2IVPROC)
+       get_extension_func("glUniform2iv");
+    _glUniform3iv = (PFNGLUNIFORM3IVPROC)
+       get_extension_func("glUniform3iv");
+    _glUniform4iv = (PFNGLUNIFORM4IVPROC)
+       get_extension_func("glUniform4iv");
     _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)
     _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)
        get_extension_func("glUniformMatrix3fv");
        get_extension_func("glUniformMatrix3fv");
     _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
     _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)

+ 8 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.h

@@ -164,6 +164,10 @@ typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, con
 typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
 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 PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
 typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
 typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
+typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
+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 PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, 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 PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
 typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
 typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
@@ -693,6 +697,10 @@ public:
   PFNGLUNIFORM2FVPROC _glUniform2fv;
   PFNGLUNIFORM2FVPROC _glUniform2fv;
   PFNGLUNIFORM3FVPROC _glUniform3fv;
   PFNGLUNIFORM3FVPROC _glUniform3fv;
   PFNGLUNIFORM4FVPROC _glUniform4fv;
   PFNGLUNIFORM4FVPROC _glUniform4fv;
+  PFNGLUNIFORM1IVPROC _glUniform1iv;
+  PFNGLUNIFORM2IVPROC _glUniform2iv;
+  PFNGLUNIFORM3IVPROC _glUniform3iv;
+  PFNGLUNIFORM4IVPROC _glUniform4iv;
   PFNGLUNIFORMMATRIX3FVPROC _glUniformMatrix3fv;
   PFNGLUNIFORMMATRIX3FVPROC _glUniformMatrix3fv;
   PFNGLUNIFORMMATRIX4FVPROC _glUniformMatrix4fv;
   PFNGLUNIFORMMATRIX4FVPROC _glUniformMatrix4fv;
   PFNGLVALIDATEPROGRAMPROC _glValidateProgram;
   PFNGLVALIDATEPROGRAMPROC _glValidateProgram;

+ 55 - 21
panda/src/glstuff/glShaderContext_src.cxx

@@ -541,10 +541,6 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
               bind._dep[1] = Shader::SSD_NONE;
               bind._dep[1] = Shader::SSD_NONE;
               s->_mat_spec.push_back(bind);
               s->_mat_spec.push_back(bind);
               continue; }
               continue; }
-            case GL_BOOL:
-            case GL_BOOL_VEC2:
-            case GL_BOOL_VEC3:
-            case GL_BOOL_VEC4:
             case GL_FLOAT:
             case GL_FLOAT:
             case GL_FLOAT_VEC2:
             case GL_FLOAT_VEC2:
             case GL_FLOAT_VEC3:
             case GL_FLOAT_VEC3:
@@ -570,12 +566,33 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
               bind._dep[1] = Shader::SSD_NONE;
               bind._dep[1] = Shader::SSD_NONE;
               s->_mat_spec.push_back(bind);
               s->_mat_spec.push_back(bind);
               continue; }
               continue; }
+            case GL_BOOL:
+            case GL_BOOL_VEC2:
+            case GL_BOOL_VEC3:
+            case GL_BOOL_VEC4:
             case GL_INT:
             case GL_INT:
             case GL_INT_VEC2:
             case GL_INT_VEC2:
             case GL_INT_VEC3:
             case GL_INT_VEC3:
-            case GL_INT_VEC4:
-              GLCAT.warning() << "Panda does not support passing integers to shaders (yet)!\n";
+            case GL_INT_VEC4: {
+              Shader::ShaderPtrSpec bind;
+              bind._id = arg_id;
+              switch (param_type) {
+                case GL_BOOL:
+                case GL_INT:        bind._dim[1] = 1; break;
+                case GL_BOOL_VEC2:
+                case GL_INT_VEC2:   bind._dim[1] = 2; break;
+                case GL_BOOL_VEC3:
+                case GL_INT_VEC3:   bind._dim[1] = 3; break;
+                case GL_BOOL_VEC4:
+                case GL_INT_VEC4:   bind._dim[1] = 4; break;
+              }
+              bind._arg = InternalName::make(param_name);
+              bind._dim[0] = 1;
+              bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
+              bind._dep[1] = Shader::SSD_NONE;
+              s->_ptr_spec.push_back(bind);
               continue;
               continue;
+            }
 #ifndef OPENGLES
 #ifndef OPENGLES
             case GL_IMAGE_1D_EXT:
             case GL_IMAGE_1D_EXT:
             case GL_IMAGE_2D_EXT:
             case GL_IMAGE_2D_EXT:
@@ -618,6 +635,10 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
           case GL_BOOL_VEC2:
           case GL_BOOL_VEC2:
           case GL_BOOL_VEC3:
           case GL_BOOL_VEC3:
           case GL_BOOL_VEC4:
           case GL_BOOL_VEC4:
+          case GL_INT:
+          case GL_INT_VEC2:
+          case GL_INT_VEC3:
+          case GL_INT_VEC4:
           case GL_FLOAT:
           case GL_FLOAT:
           case GL_FLOAT_VEC2:
           case GL_FLOAT_VEC2:
           case GL_FLOAT_VEC3:
           case GL_FLOAT_VEC3:
@@ -628,12 +649,16 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
             bind._id = arg_id;
             bind._id = arg_id;
             switch (param_type) {
             switch (param_type) {
               case GL_BOOL:
               case GL_BOOL:
+              case GL_INT:
               case GL_FLOAT:      bind._dim[1] = 1; break;
               case GL_FLOAT:      bind._dim[1] = 1; break;
               case GL_BOOL_VEC2:
               case GL_BOOL_VEC2:
+              case GL_INT_VEC2:
               case GL_FLOAT_VEC2: bind._dim[1] = 2; break;
               case GL_FLOAT_VEC2: bind._dim[1] = 2; break;
               case GL_BOOL_VEC3:
               case GL_BOOL_VEC3:
+              case GL_INT_VEC3:
               case GL_FLOAT_VEC3: bind._dim[1] = 3; break;
               case GL_FLOAT_VEC3: bind._dim[1] = 3; break;
               case GL_BOOL_VEC4:
               case GL_BOOL_VEC4:
+              case GL_INT_VEC4:
               case GL_FLOAT_VEC4: bind._dim[1] = 4; break;
               case GL_FLOAT_VEC4: bind._dim[1] = 4; break;
               case GL_FLOAT_MAT3: bind._dim[1] = 9; break;
               case GL_FLOAT_MAT3: bind._dim[1] = 9; break;
               case GL_FLOAT_MAT4: bind._dim[1] = 16; break;
               case GL_FLOAT_MAT4: bind._dim[1] = 16; break;
@@ -643,13 +668,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
             bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
             bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs;
             bind._dep[1] = Shader::SSD_NONE;
             bind._dep[1] = Shader::SSD_NONE;
             s->_ptr_spec.push_back(bind);
             s->_ptr_spec.push_back(bind);
-            continue; }
-          case GL_INT:
-          case GL_INT_VEC2:
-          case GL_INT_VEC3:
-          case GL_INT_VEC4:
-            GLCAT.warning() << "Panda does not support passing integer arrays to shaders (yet)!\n";
             continue;
             continue;
+          }
           default:
           default:
             GLCAT.warning() << "Ignoring unrecognized GLSL parameter array type!\n";
             GLCAT.warning() << "Ignoring unrecognized GLSL parameter array type!\n";
           }
           }
@@ -874,20 +894,34 @@ issue_parameters(int altered) {
   for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
   for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
     if(altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])) {
     if(altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])) {
       const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
       const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
-      Shader::ShaderPtrData* _ptr_data =
+      Shader::ShaderPtrData* ptr_data =
         const_cast< Shader::ShaderPtrData*>(_glgsg->fetch_ptr_parameter(_ptr));
         const_cast< Shader::ShaderPtrData*>(_glgsg->fetch_ptr_parameter(_ptr));
-      if (_ptr_data == NULL) { //the input is not contained in ShaderPtrData
+      if (ptr_data == NULL) { //the input is not contained in ShaderPtrData
         release_resources();
         release_resources();
         return;
         return;
       }
       }
       GLint p = _glsl_parameter_map[_shader->_ptr_spec[i]._id._seqno];
       GLint p = _glsl_parameter_map[_shader->_ptr_spec[i]._id._seqno];
-      switch (_ptr._dim[1]) {
-        case 1: _glgsg->_glUniform1fv(p, _ptr._dim[0], (float*)_ptr_data->_ptr); continue;
-        case 2: _glgsg->_glUniform2fv(p, _ptr._dim[0], (float*)_ptr_data->_ptr); continue;
-        case 3: _glgsg->_glUniform3fv(p, _ptr._dim[0], (float*)_ptr_data->_ptr); continue;
-        case 4: _glgsg->_glUniform4fv(p, _ptr._dim[0], (float*)_ptr_data->_ptr); continue;
-        case 9: _glgsg->_glUniformMatrix3fv(p, _ptr._dim[0], GL_FALSE, (float*)_ptr_data->_ptr); continue;
-        case 16: _glgsg->_glUniformMatrix4fv(p, _ptr._dim[0], GL_FALSE, (float*)_ptr_data->_ptr); continue;
+
+      switch (ptr_data->_type) {
+      case Shader::SPT_float:
+        switch (_ptr._dim[1]) {
+          case 1: _glgsg->_glUniform1fv(p, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
+          case 2: _glgsg->_glUniform2fv(p, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
+          case 3: _glgsg->_glUniform3fv(p, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
+          case 4: _glgsg->_glUniform4fv(p, _ptr._dim[0], (float*)ptr_data->_ptr); continue;
+          case 9: _glgsg->_glUniformMatrix3fv(p, _ptr._dim[0], GL_FALSE, (float*)ptr_data->_ptr); continue;
+          case 16: _glgsg->_glUniformMatrix4fv(p, _ptr._dim[0], GL_FALSE, (float*)ptr_data->_ptr); continue;
+        }
+      case Shader::SPT_int:
+        switch (_ptr._dim[1]) {
+          case 1: _glgsg->_glUniform1iv(p, _ptr._dim[0], (int*)ptr_data->_ptr); continue;
+          case 2: _glgsg->_glUniform2iv(p, _ptr._dim[0], (int*)ptr_data->_ptr); continue;
+          case 3: _glgsg->_glUniform3iv(p, _ptr._dim[0], (int*)ptr_data->_ptr); continue;
+          case 4: _glgsg->_glUniform4iv(p, _ptr._dim[0], (int*)ptr_data->_ptr); continue;
+        }
+      case Shader::SPT_double:
+        GLCAT.error() << "Passing double-precision shader inputs to GLSL shaders is not currently supported\n";
+        continue;
       }
       }
     }
     }
   }
   }

+ 127 - 0
panda/src/gobj/shader.I

@@ -555,6 +555,120 @@ ShaderPtrData(const LMatrix3d &mat) :
   memcpy(_ptr, mat.get_data(), sizeof(mat(0, 0)) * mat.get_num_components());
   memcpy(_ptr, mat.get_data(), sizeof(mat(0, 0)) * mat.get_num_components());
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//  Function: Shader::ShaderPtrData Constructor
+//  Access:
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE Shader::ShaderPtrData::
+ShaderPtrData(const PTA_int &ptr):
+  _pta(ptr.v0()),
+  _ptr(ptr.p()),
+  _type(SPT_int),
+  _updated(true),
+  _size(ptr.size())
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//  Function: Shader::ShaderPtrData Constructor
+//  Access:
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE Shader::ShaderPtrData::
+ShaderPtrData(const PTA_LVecBase4i &ptr):
+  _pta(ptr.v0()),
+  _ptr(ptr.p()),
+  _type(SPT_int),
+  _updated(true),
+  _size(ptr.size() * 4)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//  Function: Shader::ShaderPtrData Constructor
+//  Access:
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE Shader::ShaderPtrData::
+ShaderPtrData(const PTA_LVecBase3i &ptr):
+  _pta(ptr.v0()),
+  _ptr(ptr.p()),
+  _type(SPT_int),
+  _updated(true),
+  _size(ptr.size() * 3)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//  Function: Shader::ShaderPtrData Constructor
+//  Access:
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE Shader::ShaderPtrData::
+ShaderPtrData(const PTA_LVecBase2i &ptr):
+  _pta(ptr.v0()),
+  _ptr(ptr.p()),
+  _type(SPT_int),
+  _updated(true),
+  _size(ptr.size() * 2)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//  Function: Shader::ShaderPtrData Constructor
+//  Access:
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE Shader::ShaderPtrData::
+ShaderPtrData(const LVecBase4i &vec) :
+  _type(SPT_int),
+  _updated(true),
+  _size(4)
+{
+  PTA_int pta = PTA_int::empty_array(4);
+  _pta = pta.v0();
+  _ptr = pta.p();
+  nassertv(sizeof(vec[0]) * vec.get_num_components() == pta.size() * sizeof(pta[0]));
+  memcpy(_ptr, vec.get_data(), sizeof(vec[0]) * vec.get_num_components());
+}
+
+////////////////////////////////////////////////////////////////////
+//  Function: Shader::ShaderPtrData Constructor
+//  Access:
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE Shader::ShaderPtrData::
+ShaderPtrData(const LVecBase3i &vec) :
+  _type(SPT_int),
+  _updated(true),
+  _size(3)
+{
+  PTA_int pta = PTA_int::empty_array(3);
+  _pta = pta.v0();
+  _ptr = pta.p();
+  nassertv(sizeof(vec[0]) * vec.get_num_components() == pta.size() * sizeof(pta[0]));
+  memcpy(_ptr, vec.get_data(), sizeof(vec[0]) * vec.get_num_components());
+}
+
+////////////////////////////////////////////////////////////////////
+//  Function: Shader::ShaderPtrData Constructor
+//  Access:
+//  Description: 
+////////////////////////////////////////////////////////////////////
+INLINE Shader::ShaderPtrData::
+ShaderPtrData(const LVecBase2i &vec) :
+  _type(SPT_int),
+  _updated(true),
+  _size(2)
+{
+  PTA_int pta = PTA_int::empty_array(2);
+  _pta = pta.v0();
+  _ptr = pta.p();
+  nassertv(sizeof(vec[0]) * vec.get_num_components() == pta.size() * sizeof(pta[0]));
+  memcpy(_ptr, vec.get_data(), sizeof(vec[0]) * vec.get_num_components());
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Shader::ShaderPtrData::write_datagram
 //     Function: Shader::ShaderPtrData::write_datagram
 //       Access: Public
 //       Access: Public
@@ -577,6 +691,11 @@ write_datagram(Datagram &dg) const {
     for (size_t i = 0; i < _size; ++i) {
     for (size_t i = 0; i < _size; ++i) {
       dg.add_float32(data[i]);
       dg.add_float32(data[i]);
     }
     }
+  } else if (_type == SPT_int) {
+    const int *data = (const int *) _ptr;
+    for (size_t i = 0; i < _size; ++i) {
+      dg.add_int32(data[i]);
+    }
   }
   }
 }
 }
 
 
@@ -605,6 +724,14 @@ read_datagram(DatagramIterator &scan) {
     }
     }
     _pta = pta.v0();
     _pta = pta.v0();
     _ptr = pta.p();
     _ptr = pta.p();
+
+  } else if (_type == SPT_int) {
+    PTA_int pta = PTA_int::empty_array(_size);
+    for (size_t i = 0; i < _size; ++i) {
+      pta[i] = scan.get_int32();
+    }
+    _pta = pta.v0();
+    _ptr = pta.p();
   }
   }
 }
 }
 
 

+ 9 - 0
panda/src/gobj/shader.h

@@ -278,6 +278,7 @@ public:
   enum ShaderPtrType {
   enum ShaderPtrType {
     SPT_float,
     SPT_float,
     SPT_double,
     SPT_double,
+    SPT_int,
     SPT_unknown
     SPT_unknown
   };
   };
 
 
@@ -318,6 +319,14 @@ public:
     INLINE ShaderPtrData(const LMatrix4d &mat);
     INLINE ShaderPtrData(const LMatrix4d &mat);
     INLINE ShaderPtrData(const LMatrix3d &mat);
     INLINE ShaderPtrData(const LMatrix3d &mat);
 
 
+    INLINE ShaderPtrData(const PTA_int &ptr);
+    INLINE ShaderPtrData(const PTA_LVecBase4i &ptr);
+    INLINE ShaderPtrData(const PTA_LVecBase3i &ptr);
+    INLINE ShaderPtrData(const PTA_LVecBase2i &ptr);
+    INLINE ShaderPtrData(const LVecBase4i &vec);
+    INLINE ShaderPtrData(const LVecBase3i &vec);
+    INLINE ShaderPtrData(const LVecBase2i &vec);
+
     INLINE void write_datagram(Datagram &dg) const;
     INLINE void write_datagram(Datagram &dg) const;
     INLINE void read_datagram(DatagramIterator &source);
     INLINE void read_datagram(DatagramIterator &source);
   };
   };

+ 20 - 0
panda/src/pgraph/nodePath.cxx

@@ -3813,6 +3813,16 @@ set_shader_input(const InternalName *id, const PTA_double &v, int priority) {
   set_shader_input(new ShaderInput(id,v,priority));
   set_shader_input(new ShaderInput(id,v,priority));
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodePath::set_shader_input
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void NodePath:: 
+set_shader_input(const InternalName *id, const PTA_int &v, int priority) {
+  set_shader_input(new ShaderInput(id,v,priority));
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePath::set_shader_input
 //     Function: NodePath::set_shader_input
 //       Access: Published
 //       Access: Published
@@ -3964,6 +3974,16 @@ set_shader_input(const string &id, const PTA_double &v, int priority) {
   set_shader_input(new ShaderInput(InternalName::make(id),v,priority));
   set_shader_input(new ShaderInput(InternalName::make(id),v,priority));
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: NodePath::set_shader_input
+//       Access: Published
+//  Description: 
+////////////////////////////////////////////////////////////////////
+void NodePath:: 
+set_shader_input(const string &id, const PTA_int &v, int priority) {
+  set_shader_input(new ShaderInput(InternalName::make(id),v,priority));
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NodePath::set_shader_input
 //     Function: NodePath::set_shader_input
 //       Access: Published
 //       Access: Published

+ 2 - 0
panda/src/pgraph/nodePath.h

@@ -618,6 +618,7 @@ PUBLISHED:
   void set_shader_input(const InternalName *id, const NodePath &np, int priority=0);
   void set_shader_input(const InternalName *id, const NodePath &np, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_float &v, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_float &v, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_double &v, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_double &v, int priority=0);
+  void set_shader_input(const InternalName *id, const PTA_int &v, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_LVecBase4 &v, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_LVecBase4 &v, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_LVecBase3 &v, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_LVecBase3 &v, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_LVecBase2 &v, int priority=0);
   void set_shader_input(const InternalName *id, const PTA_LVecBase2 &v, int priority=0);
@@ -635,6 +636,7 @@ PUBLISHED:
   void set_shader_input(const string &id, const NodePath &np, int priority=0);
   void set_shader_input(const string &id, const NodePath &np, int priority=0);
   void set_shader_input(const string &id, const PTA_float &v, int priority=0); 
   void set_shader_input(const string &id, const PTA_float &v, int priority=0); 
   void set_shader_input(const string &id, const PTA_double &v, int priority=0); 
   void set_shader_input(const string &id, const PTA_double &v, int priority=0); 
+  void set_shader_input(const string &id, const PTA_int &v, int priority=0); 
   void set_shader_input(const string &id, const PTA_LVecBase4 &v, int priority=0); 
   void set_shader_input(const string &id, const PTA_LVecBase4 &v, int priority=0); 
   void set_shader_input(const string &id, const PTA_LVecBase3 &v, int priority=0); 
   void set_shader_input(const string &id, const PTA_LVecBase3 &v, int priority=0); 
   void set_shader_input(const string &id, const PTA_LVecBase2 &v, int priority=0); 
   void set_shader_input(const string &id, const PTA_LVecBase2 &v, int priority=0); 

+ 49 - 0
panda/src/pgraph/shaderAttrib.cxx

@@ -565,6 +565,55 @@ get_shader_input_texture(const InternalName *id) const {
   }
   }
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: ShaderAttrib::get_shader_input_matrix
+//       Access: Published
+//  Description: Returns the ShaderInput as a matrix.  Assertion
+//               fails if there is none, or if it is not a matrix
+//               or NodePath.
+////////////////////////////////////////////////////////////////////
+const LMatrix4 &ShaderAttrib::
+get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const {
+  Inputs::const_iterator i = _inputs.find(id);
+  if (i == _inputs.end()) {
+    ostringstream strm;
+    strm << "Shader input " << id->get_name() << " is not present.\n";
+    nassert_raise(strm.str());
+    return LMatrix4::ident_mat();
+  } else {
+    const ShaderInput *p = (*i).second;
+
+    if (p->get_value_type() == ShaderInput::M_nodepath) {
+      const NodePath &np = p->get_nodepath();
+      nassertr(!np.is_empty(), LMatrix4::ident_mat());
+      return np.get_transform()->get_mat();
+
+    } else if (p->get_value_type() == ShaderInput::M_numeric && p->get_ptr()._size == 16) {
+      const Shader::ShaderPtrData &ptr = p->get_ptr();
+
+      switch (ptr._type) {
+        case Shader::SPT_float: {
+          LMatrix4f matrixf;
+          memcpy(&matrixf(0, 0), ptr._ptr, sizeof(float) * 16);
+          matrix = LCAST(PN_stdfloat, matrixf);
+          return matrix;
+        }
+        case Shader::SPT_double: {
+          LMatrix4d matrixd;
+          memcpy(&matrixd(0, 0), ptr._ptr, sizeof(double) * 16);
+          matrix = LCAST(PN_stdfloat, matrixd);
+          return matrix;
+        }
+      }
+    }
+
+    ostringstream strm;
+    strm << "Shader input " << id->get_name() << " is not a NodePath or LMatrix4.\n";
+    nassert_raise(strm.str());
+    return LMatrix4::ident_mat();
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: ShaderAttrib::get_shader
 //     Function: ShaderAttrib::get_shader
 //       Access: Published
 //       Access: Published

+ 1 - 0
panda/src/pgraph/shaderAttrib.h

@@ -110,6 +110,7 @@ PUBLISHED:
   const LVecBase4 &get_shader_input_vector(InternalName *id) const;
   const LVecBase4 &get_shader_input_vector(InternalName *id) const;
   Texture *get_shader_input_texture(const InternalName *id) const;
   Texture *get_shader_input_texture(const InternalName *id) const;
   const Shader::ShaderPtrData *get_shader_input_ptr(const InternalName *id) const;
   const Shader::ShaderPtrData *get_shader_input_ptr(const InternalName *id) const;
+  const LMatrix4 &get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const;
 
 
   static void register_with_read_factory();
   static void register_with_read_factory();