From 6e64ff951cbb1cc108909df74d4b25080cf37097 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 3 Jul 2014 21:54:45 +0000 Subject: [PATCH] Add support for passing int arrays and vectors to GLSL shaders. --- panda/src/glstuff/glCgShaderContext_src.cxx | 17 ++- .../glstuff/glGraphicsStateGuardian_src.cxx | 8 ++ .../src/glstuff/glGraphicsStateGuardian_src.h | 8 ++ panda/src/glstuff/glShaderContext_src.cxx | 76 ++++++++--- panda/src/gobj/shader.I | 127 ++++++++++++++++++ panda/src/gobj/shader.h | 9 ++ panda/src/pgraph/nodePath.cxx | 20 +++ panda/src/pgraph/nodePath.h | 2 + panda/src/pgraph/shaderAttrib.cxx | 49 +++++++ panda/src/pgraph/shaderAttrib.h | 1 + 10 files changed, 292 insertions(+), 25 deletions(-) diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx index fe35672716..a37a9073fd 100755 --- a/panda/src/glstuff/glCgShaderContext_src.cxx +++ b/panda/src/glstuff/glCgShaderContext_src.cxx @@ -281,7 +281,7 @@ issue_parameters(int altered) { case Shader::SAC_matrix: cgGLSetMatrixParameterArrayfc(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue; } - } + } } case Shader::SPT_double: switch(_ptr._info._class) { @@ -308,7 +308,18 @@ issue_parameters(int altered) { case Shader::SAC_matrix: 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"; 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++) { 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); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index f863c3a8dc..d58478bc28 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -1179,6 +1179,14 @@ reset() { get_extension_func("glUniform3fv"); _glUniform4fv = (PFNGLUNIFORM4FVPROC) 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) get_extension_func("glUniformMatrix3fv"); _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 90bca73524..b27c1e9bff 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/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 PFNGLUNIFORM3FVPROC) (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 PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); @@ -693,6 +697,10 @@ public: PFNGLUNIFORM2FVPROC _glUniform2fv; PFNGLUNIFORM3FVPROC _glUniform3fv; PFNGLUNIFORM4FVPROC _glUniform4fv; + PFNGLUNIFORM1IVPROC _glUniform1iv; + PFNGLUNIFORM2IVPROC _glUniform2iv; + PFNGLUNIFORM3IVPROC _glUniform3iv; + PFNGLUNIFORM4IVPROC _glUniform4iv; PFNGLUNIFORMMATRIX3FVPROC _glUniformMatrix3fv; PFNGLUNIFORMMATRIX4FVPROC _glUniformMatrix4fv; PFNGLVALIDATEPROGRAMPROC _glValidateProgram; diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx index e7255f732f..bc0d54eb19 100755 --- a/panda/src/glstuff/glShaderContext_src.cxx +++ b/panda/src/glstuff/glShaderContext_src.cxx @@ -541,10 +541,6 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext bind._dep[1] = Shader::SSD_NONE; s->_mat_spec.push_back(bind); continue; } - case GL_BOOL: - case GL_BOOL_VEC2: - case GL_BOOL_VEC3: - case GL_BOOL_VEC4: case GL_FLOAT: case GL_FLOAT_VEC2: case GL_FLOAT_VEC3: @@ -570,12 +566,33 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext bind._dep[1] = Shader::SSD_NONE; s->_mat_spec.push_back(bind); continue; } + case GL_BOOL: + case GL_BOOL_VEC2: + case GL_BOOL_VEC3: + case GL_BOOL_VEC4: case GL_INT: case GL_INT_VEC2: 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; + } #ifndef OPENGLES case GL_IMAGE_1D_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_VEC3: 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_VEC2: case GL_FLOAT_VEC3: @@ -628,12 +649,16 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext bind._id = arg_id; switch (param_type) { case GL_BOOL: + case GL_INT: case GL_FLOAT: bind._dim[1] = 1; break; case GL_BOOL_VEC2: + case GL_INT_VEC2: case GL_FLOAT_VEC2: bind._dim[1] = 2; break; case GL_BOOL_VEC3: + case GL_INT_VEC3: case GL_FLOAT_VEC3: bind._dim[1] = 3; break; case GL_BOOL_VEC4: + case GL_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; @@ -643,13 +668,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs; bind._dep[1] = Shader::SSD_NONE; 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; + } default: 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++) { if(altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])) { 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)); - if (_ptr_data == NULL) { //the input is not contained in ShaderPtrData + if (ptr_data == NULL) { //the input is not contained in ShaderPtrData release_resources(); return; } 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; } } } diff --git a/panda/src/gobj/shader.I b/panda/src/gobj/shader.I index 862966f85d..9a84d9b6ef 100755 --- a/panda/src/gobj/shader.I +++ b/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()); } +//////////////////////////////////////////////////////////////////// +// 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 // Access: Public @@ -577,6 +691,11 @@ write_datagram(Datagram &dg) const { for (size_t i = 0; i < _size; ++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(); _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(); } } diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h index 34657495ab..44682f7c91 100755 --- a/panda/src/gobj/shader.h +++ b/panda/src/gobj/shader.h @@ -278,6 +278,7 @@ public: enum ShaderPtrType { SPT_float, SPT_double, + SPT_int, SPT_unknown }; @@ -318,6 +319,14 @@ public: INLINE ShaderPtrData(const LMatrix4d &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 read_datagram(DatagramIterator &source); }; diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 216c7deb4b..f80388bf87 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/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)); } +//////////////////////////////////////////////////////////////////// +// 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 // 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)); } +//////////////////////////////////////////////////////////////////// +// 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 // Access: Published diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 4bdbba41ff..ecfb6b33ed 100644 --- a/panda/src/pgraph/nodePath.h +++ b/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 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_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_LVecBase3 &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 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_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_LVecBase3 &v, int priority=0); void set_shader_input(const string &id, const PTA_LVecBase2 &v, int priority=0); diff --git a/panda/src/pgraph/shaderAttrib.cxx b/panda/src/pgraph/shaderAttrib.cxx index 02ff8ab652..354f5ff57f 100755 --- a/panda/src/pgraph/shaderAttrib.cxx +++ b/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 // Access: Published diff --git a/panda/src/pgraph/shaderAttrib.h b/panda/src/pgraph/shaderAttrib.h index fba1340751..0f8f22505c 100755 --- a/panda/src/pgraph/shaderAttrib.h +++ b/panda/src/pgraph/shaderAttrib.h @@ -110,6 +110,7 @@ PUBLISHED: const LVecBase4 &get_shader_input_vector(InternalName *id) const; Texture *get_shader_input_texture(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();