diff --git a/panda/src/pgraph/Sources.pp b/panda/src/pgraph/Sources.pp index b23b87540a..b7154386ec 100644 --- a/panda/src/pgraph/Sources.pp +++ b/panda/src/pgraph/Sources.pp @@ -102,6 +102,7 @@ sequenceNode.I sequenceNode.h \ shadeModelAttrib.I shadeModelAttrib.h \ shaderAttrib.I shaderAttrib.h \ + shaderGenerator.I shaderGenerator.h \ shaderInput.I shaderInput.h \ shaderPool.I shaderPool.h \ showBoundsEffect.I showBoundsEffect.h \ @@ -211,6 +212,7 @@ sequenceNode.cxx \ shadeModelAttrib.cxx \ shaderAttrib.cxx \ + shaderGenerator.cxx \ shaderInput.cxx \ shaderPool.cxx \ showBoundsEffect.cxx \ @@ -317,6 +319,7 @@ sequenceNode.I sequenceNode.h \ shadeModelAttrib.I shadeModelAttrib.h \ shaderAttrib.I shaderAttrib.h \ + shaderGenerator.I shaderGenerator.h \ shaderInput.I shaderInput.h \ shaderPool.I shaderPool.h \ showBoundsEffect.I showBoundsEffect.h \ diff --git a/panda/src/pgraph/pgraph_composite4.cxx b/panda/src/pgraph/pgraph_composite4.cxx index 3073fbd1a2..604bf3f261 100644 --- a/panda/src/pgraph/pgraph_composite4.cxx +++ b/panda/src/pgraph/pgraph_composite4.cxx @@ -12,6 +12,7 @@ #include "shaderInput.cxx" #include "shaderAttrib.cxx" #include "shaderPool.cxx" +#include "shaderGenerator.cxx" #include "showBoundsEffect.cxx" #include "spotlight.cxx" #include "stateMunger.cxx" diff --git a/panda/src/pgraph/renderState.I b/panda/src/pgraph/renderState.I index f5650eefb1..c109f16099 100644 --- a/panda/src/pgraph/renderState.I +++ b/panda/src/pgraph/renderState.I @@ -601,26 +601,6 @@ compare_to(const Attribute &other) const { return _override - other._override; } -//////////////////////////////////////////////////////////////////// -// Function: RenderState::get_generated_shader -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE ShaderAttrib *RenderState:: -get_generated_shader() const { - return (ShaderAttrib*)(RenderAttrib*)_generated_shader; -} - -//////////////////////////////////////////////////////////////////// -// Function: RenderState::set_generated_shader -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE void RenderState:: -set_generated_shader(ShaderAttrib *attr) { - _generated_shader = (RenderAttrib*)attr; -} - //////////////////////////////////////////////////////////////////// // Function: RenderState::flush_level // Access: Public, Static @@ -671,3 +651,22 @@ CompositionCycleDescEntry(const RenderState *obj, _inverted(inverted) { } + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::get_generated_shader +// Access: Public +// Description: Generate a ShaderAttrib for this RenderState. This +// generated ShaderAttrib can be thought of as a +// replacement for the regular ShaderAttrib that is a +// standard part of the RenderState. +//////////////////////////////////////////////////////////////////// +INLINE const ShaderAttrib *RenderState:: +get_generated_shader() const { + if (_generated_shader != (RenderAttrib*)NULL) { + return DCAST(ShaderAttrib, _generated_shader); + } + ((RenderState*)this)->_generated_shader = + ShaderGenerator::synthesize_shader(this); + return DCAST(ShaderAttrib, _generated_shader); +} + diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index cadfc9fbf8..878225830c 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -2118,3 +2118,4 @@ fillin(DatagramIterator &scan, BamReader *manager) { _attributes.push_back(Attribute(override)); } } + diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index 9cc3ea3bbc..3c981b3209 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -36,6 +36,7 @@ #include "deletedChain.h" #include "simpleHashMap.h" #include "cacheStats.h" +#include "shaderGenerator.h" class GraphicsStateGuardianBase; class FogAttrib; @@ -154,13 +155,13 @@ PUBLISHED: int get_geom_rendering(int geom_rendering) const; + INLINE const ShaderAttrib *get_generated_shader() const; + public: void store_into_slots(AttribSlots *slots) const; static void bin_removed(int bin_index); - INLINE ShaderAttrib *get_generated_shader() const; - INLINE void set_generated_shader(ShaderAttrib *attr); - + INLINE static void flush_level(); private: @@ -303,7 +304,7 @@ private: // ShaderAttrib will be synthesized by the runtime and stored here. // I can't declare this as a ShaderAttrib because that would create // a circular include-file dependency problem. Aaargh. - PT(RenderAttrib) _generated_shader; + CPT(RenderAttrib) _generated_shader; // We also cache the pointer to some critical attribs stored in the // state, if they exist. diff --git a/panda/src/pgraph/shaderAttrib.cxx b/panda/src/pgraph/shaderAttrib.cxx index 5876683ec0..732b932514 100755 --- a/panda/src/pgraph/shaderAttrib.cxx +++ b/panda/src/pgraph/shaderAttrib.cxx @@ -288,13 +288,17 @@ get_shader_input_nodepath(InternalName *id) const { static NodePath resfail; Inputs::const_iterator i = _inputs.find(id); if (i == _inputs.end()) { - pgraph_cat.error() << "Shader input " << id->get_name() << " is not present.\n"; - nassertr(false, resfail); + ostringstream strm; + strm << "Shader input " << id->get_name() << " is not present.\n"; + nassert_raise(strm.str()); + return resfail; } else { const ShaderInput *p = (*i).second; if (p->get_value_type() != ShaderInput::M_nodepath) { - pgraph_cat.error() << "Shader input " << id->get_name() << " is not a nodepath.\n"; - nassertr(false, resfail); + ostringstream strm; + strm << "Shader input " << id->get_name() << " is not a nodepath.\n"; + nassert_raise(strm.str()); + return resfail; } return p->get_nodepath(); } @@ -314,14 +318,16 @@ get_shader_input_vector(InternalName *id) const { static LVector4f resfail(0,0,0,0); Inputs::const_iterator i = _inputs.find(id); if (i == _inputs.end()) { - pgraph_cat.error() << "Shader input " << id->get_name() << " is not present.\n"; - nassertr(false, resfail); + ostringstream strm; + strm << "Shader input " << id->get_name() << " is not present.\n"; + nassert_raise(strm.str()); return resfail; } else { const ShaderInput *p = (*i).second; if (p->get_value_type() != ShaderInput::M_vector) { - pgraph_cat.error() << "Shader input " << id->get_name() << " is not a vector.\n"; - nassertr(false, resfail); + ostringstream strm; + strm << "Shader input " << id->get_name() << " is not a vector.\n"; + nassert_raise(strm.str()); return resfail; } return p->get_vector(); @@ -338,14 +344,16 @@ Texture *ShaderAttrib:: get_shader_input_texture(InternalName *id) const { Inputs::const_iterator i = _inputs.find(id); if (i == _inputs.end()) { - pgraph_cat.error() << "Shader input " << id->get_name() << " is not present.\n"; - nassertr(false, NULL); + ostringstream strm; + strm << "Shader input " << id->get_name() << " is not present.\n"; + nassert_raise(strm.str()); return NULL; } else { const ShaderInput *p = (*i).second; if (p->get_value_type() != ShaderInput::M_texture) { - pgraph_cat.error() << "Shader input " << id->get_name() << " is not a texture.\n"; - nassertr(false, NULL); + ostringstream strm; + strm << "Shader input " << id->get_name() << " is not a texture.\n"; + nassert_raise(strm.str()); return NULL; } return p->get_texture(); @@ -418,6 +426,9 @@ compare_to_impl(const RenderAttrib *other) const { if (this->_shader_priority != that->_shader_priority) { return (this->_shader_priority < that->_shader_priority) ? -1 : 1; } + if (this->_auto_shader != that->_auto_shader) { + return (this->_auto_shader < that->_auto_shader) ? -1 : 1; + } if (this->_has_shader != that->_has_shader) { return (this->_has_shader < that->_has_shader) ? -1 : 1; }