From 2a3ad0d4e5153cf4553ed8bde4d398480442de61 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 7 Nov 2011 00:08:04 +0000 Subject: [PATCH] Add RenderState::get_auto_shader_state() --- .../glstuff/glGraphicsStateGuardian_src.cxx | 7 +- panda/src/pgraph/alphaTestAttrib.cxx | 10 ++ panda/src/pgraph/alphaTestAttrib.h | 1 + panda/src/pgraph/auxBitplaneAttrib.cxx | 10 ++ panda/src/pgraph/auxBitplaneAttrib.h | 1 + panda/src/pgraph/clipPlaneAttrib.cxx | 10 ++ panda/src/pgraph/clipPlaneAttrib.h | 1 + panda/src/pgraph/colorAttrib.cxx | 15 +++ panda/src/pgraph/colorAttrib.h | 1 + panda/src/pgraph/colorBlendAttrib.cxx | 10 ++ panda/src/pgraph/colorBlendAttrib.h | 1 + panda/src/pgraph/colorScaleAttrib.cxx | 14 +++ panda/src/pgraph/colorScaleAttrib.h | 1 + panda/src/pgraph/fogAttrib.cxx | 10 ++ panda/src/pgraph/fogAttrib.h | 1 + panda/src/pgraph/lightAttrib.cxx | 10 ++ panda/src/pgraph/lightAttrib.h | 1 + panda/src/pgraph/lightRampAttrib.cxx | 10 ++ panda/src/pgraph/lightRampAttrib.h | 1 + panda/src/pgraph/materialAttrib.cxx | 10 ++ panda/src/pgraph/materialAttrib.h | 1 + panda/src/pgraph/renderAttrib.I | 25 +++++ panda/src/pgraph/renderAttrib.cxx | 10 ++ panda/src/pgraph/renderAttrib.h | 3 + panda/src/pgraph/renderState.cxx | 97 ++++++++++++++++++- panda/src/pgraph/renderState.h | 16 ++- panda/src/pgraph/shaderAttrib.cxx | 21 ++++ panda/src/pgraph/shaderAttrib.h | 1 + panda/src/pgraph/texGenAttrib.cxx | 10 ++ panda/src/pgraph/texGenAttrib.h | 1 + panda/src/pgraph/texMatrixAttrib.cxx | 24 +++++ panda/src/pgraph/texMatrixAttrib.h | 1 + panda/src/pgraph/textureAttrib.cxx | 10 ++ panda/src/pgraph/textureAttrib.h | 1 + panda/src/pgraph/transparencyAttrib.cxx | 10 ++ panda/src/pgraph/transparencyAttrib.h | 1 + 36 files changed, 347 insertions(+), 10 deletions(-) diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 8ecde159f9..ef7eb69b56 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -7141,13 +7141,14 @@ set_state_and_transform(const RenderState *target, #ifndef OPENGLES_1 if (_target_shader->auto_shader()) { // If we don't have a generated shader, make sure we have a ShaderGenerator, then generate the shader. - if (_target_rs->_generated_shader == NULL) { + CPT(RenderState) shader = _target_rs->get_auto_shader_state(); + if (shader->_generated_shader == NULL) { if (_shader_generator == NULL) { _shader_generator = new ShaderGenerator(this, _scene_setup->get_display_region()->get_window()); } - const_cast(_target_rs.p())->_generated_shader = DCAST(ShaderAttrib, _shader_generator->synthesize_shader(_target_rs)); + const_cast(shader.p())->_generated_shader = DCAST(ShaderAttrib, _shader_generator->synthesize_shader(shader)); } - _target_shader = DCAST(ShaderAttrib, _target_rs->_generated_shader); + _target_shader = DCAST(ShaderAttrib, shader->_generated_shader); } #endif diff --git a/panda/src/pgraph/alphaTestAttrib.cxx b/panda/src/pgraph/alphaTestAttrib.cxx index d5129478c5..8819fe74f0 100644 --- a/panda/src/pgraph/alphaTestAttrib.cxx +++ b/panda/src/pgraph/alphaTestAttrib.cxx @@ -108,6 +108,16 @@ get_hash_impl() const { return hash; } +//////////////////////////////////////////////////////////////////// +// Function: AlphaTestAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AlphaTestAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: AlphaTestAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/alphaTestAttrib.h b/panda/src/pgraph/alphaTestAttrib.h index b47147f162..2e3cf9e539 100644 --- a/panda/src/pgraph/alphaTestAttrib.h +++ b/panda/src/pgraph/alphaTestAttrib.h @@ -44,6 +44,7 @@ public: protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: PandaCompareFunc _mode; diff --git a/panda/src/pgraph/auxBitplaneAttrib.cxx b/panda/src/pgraph/auxBitplaneAttrib.cxx index fd82f1727b..2972bcd227 100644 --- a/panda/src/pgraph/auxBitplaneAttrib.cxx +++ b/panda/src/pgraph/auxBitplaneAttrib.cxx @@ -114,6 +114,16 @@ get_hash_impl() const { return hash; } +//////////////////////////////////////////////////////////////////// +// Function: AuxBitplaneAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) AuxBitplaneAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: AuxBitplaneAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/auxBitplaneAttrib.h b/panda/src/pgraph/auxBitplaneAttrib.h index 4f395a1b82..7c918db7bc 100644 --- a/panda/src/pgraph/auxBitplaneAttrib.h +++ b/panda/src/pgraph/auxBitplaneAttrib.h @@ -77,6 +77,7 @@ public: protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: int _outputs; diff --git a/panda/src/pgraph/clipPlaneAttrib.cxx b/panda/src/pgraph/clipPlaneAttrib.cxx index db86bc915e..b07052125e 100644 --- a/panda/src/pgraph/clipPlaneAttrib.cxx +++ b/panda/src/pgraph/clipPlaneAttrib.cxx @@ -908,6 +908,16 @@ invert_compose_impl(const RenderAttrib *other) const { return other; } +//////////////////////////////////////////////////////////////////// +// Function: ClipPlaneAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ClipPlaneAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: ClipPlaneAttrib::sort_on_planes // Access: Private diff --git a/panda/src/pgraph/clipPlaneAttrib.h b/panda/src/pgraph/clipPlaneAttrib.h index 6389c8e398..f8651800b0 100644 --- a/panda/src/pgraph/clipPlaneAttrib.h +++ b/panda/src/pgraph/clipPlaneAttrib.h @@ -103,6 +103,7 @@ protected: virtual size_t get_hash_impl() const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: INLINE void check_filtered() const; diff --git a/panda/src/pgraph/colorAttrib.cxx b/panda/src/pgraph/colorAttrib.cxx index c752838802..9e0b299e13 100644 --- a/panda/src/pgraph/colorAttrib.cxx +++ b/panda/src/pgraph/colorAttrib.cxx @@ -153,6 +153,21 @@ get_hash_impl() const { return hash; } +//////////////////////////////////////////////////////////////////// +// Function: ColorAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ColorAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + // For a ColorAttrib, the only relevant information is the type: is + // it flat-shaded or vertex-shaded? The actual color value is read + // by the shader from the graphics state. + + ColorAttrib *attrib = new ColorAttrib(_type, LColor(1.0f, 1.0f, 1.0f, 1.0f)); + return return_new(attrib); +} + //////////////////////////////////////////////////////////////////// // Function: ColorAttrib::quantize_color // Access: Private diff --git a/panda/src/pgraph/colorAttrib.h b/panda/src/pgraph/colorAttrib.h index 7058ee725f..c30131159a 100644 --- a/panda/src/pgraph/colorAttrib.h +++ b/panda/src/pgraph/colorAttrib.h @@ -51,6 +51,7 @@ public: protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: void quantize_color(); diff --git a/panda/src/pgraph/colorBlendAttrib.cxx b/panda/src/pgraph/colorBlendAttrib.cxx index b5e49cf222..2ad7bb5065 100644 --- a/panda/src/pgraph/colorBlendAttrib.cxx +++ b/panda/src/pgraph/colorBlendAttrib.cxx @@ -152,6 +152,16 @@ get_hash_impl() const { return hash; } +//////////////////////////////////////////////////////////////////// +// Function: ColorBlendAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ColorBlendAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: ColorBlendAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/colorBlendAttrib.h b/panda/src/pgraph/colorBlendAttrib.h index ae20d1b65c..85ee3b2164 100644 --- a/panda/src/pgraph/colorBlendAttrib.h +++ b/panda/src/pgraph/colorBlendAttrib.h @@ -96,6 +96,7 @@ public: protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: Mode _mode; diff --git a/panda/src/pgraph/colorScaleAttrib.cxx b/panda/src/pgraph/colorScaleAttrib.cxx index 58d6e706b1..04d9db0b9b 100644 --- a/panda/src/pgraph/colorScaleAttrib.cxx +++ b/panda/src/pgraph/colorScaleAttrib.cxx @@ -274,6 +274,20 @@ invert_compose_impl(const RenderAttrib *other) const { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: ColorScaleAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ColorScaleAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + // A ColorScaleAttrib doesn't directly contribute to the auto-shader + // contents--instead, the shader is always written to query + // attr_colorscale at runtime. So the attrib itself means nothing + // to the shader. + return NULL; +} + //////////////////////////////////////////////////////////////////// // Function: ColorScaleAttrib::quantize_scale // Access: Private diff --git a/panda/src/pgraph/colorScaleAttrib.h b/panda/src/pgraph/colorScaleAttrib.h index b98f1f87f6..ca947ec049 100644 --- a/panda/src/pgraph/colorScaleAttrib.h +++ b/panda/src/pgraph/colorScaleAttrib.h @@ -55,6 +55,7 @@ protected: virtual size_t get_hash_impl() const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: void quantize_scale(); diff --git a/panda/src/pgraph/fogAttrib.cxx b/panda/src/pgraph/fogAttrib.cxx index df1590cbb9..4c0cd2e0cf 100644 --- a/panda/src/pgraph/fogAttrib.cxx +++ b/panda/src/pgraph/fogAttrib.cxx @@ -120,6 +120,16 @@ get_hash_impl() const { return hash; } +//////////////////////////////////////////////////////////////////// +// Function: FogAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) FogAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: FogAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/fogAttrib.h b/panda/src/pgraph/fogAttrib.h index efde339448..99afd79cde 100644 --- a/panda/src/pgraph/fogAttrib.h +++ b/panda/src/pgraph/fogAttrib.h @@ -42,6 +42,7 @@ public: protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: PT(Fog) _fog; diff --git a/panda/src/pgraph/lightAttrib.cxx b/panda/src/pgraph/lightAttrib.cxx index da346664e2..4a0f0f2fe1 100644 --- a/panda/src/pgraph/lightAttrib.cxx +++ b/panda/src/pgraph/lightAttrib.cxx @@ -940,6 +940,16 @@ invert_compose_impl(const RenderAttrib *other) const { return other; } +//////////////////////////////////////////////////////////////////// +// Function: LightAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) LightAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: LightAttrib::sort_on_lights // Access: Private diff --git a/panda/src/pgraph/lightAttrib.h b/panda/src/pgraph/lightAttrib.h index 3dd0e32ab7..393e5436b6 100644 --- a/panda/src/pgraph/lightAttrib.h +++ b/panda/src/pgraph/lightAttrib.h @@ -102,6 +102,7 @@ protected: virtual size_t get_hash_impl() const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: INLINE void check_filtered() const; diff --git a/panda/src/pgraph/lightRampAttrib.cxx b/panda/src/pgraph/lightRampAttrib.cxx index c0640e14ab..32df6a0f4b 100644 --- a/panda/src/pgraph/lightRampAttrib.cxx +++ b/panda/src/pgraph/lightRampAttrib.cxx @@ -282,6 +282,16 @@ get_hash_impl() const { return hash; } +//////////////////////////////////////////////////////////////////// +// Function: LightRampAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) LightRampAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: LightRampAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/lightRampAttrib.h b/panda/src/pgraph/lightRampAttrib.h index 3c107a8a9c..1fc427c1ea 100644 --- a/panda/src/pgraph/lightRampAttrib.h +++ b/panda/src/pgraph/lightRampAttrib.h @@ -62,6 +62,7 @@ public: protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: LightRampMode _mode; diff --git a/panda/src/pgraph/materialAttrib.cxx b/panda/src/pgraph/materialAttrib.cxx index ce85fbde73..26912d6d09 100644 --- a/panda/src/pgraph/materialAttrib.cxx +++ b/panda/src/pgraph/materialAttrib.cxx @@ -121,6 +121,16 @@ get_hash_impl() const { return hash; } +//////////////////////////////////////////////////////////////////// +// Function: MaterialAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) MaterialAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: MaterialAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/materialAttrib.h b/panda/src/pgraph/materialAttrib.h index 5665eb22a0..5272375852 100644 --- a/panda/src/pgraph/materialAttrib.h +++ b/panda/src/pgraph/materialAttrib.h @@ -45,6 +45,7 @@ public: protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: PT(Material) _material; diff --git a/panda/src/pgraph/renderAttrib.I b/panda/src/pgraph/renderAttrib.I index f37798129b..bb12b66e62 100644 --- a/panda/src/pgraph/renderAttrib.I +++ b/panda/src/pgraph/renderAttrib.I @@ -118,6 +118,31 @@ get_unique() const { return return_unique((RenderAttrib *)this); } +//////////////////////////////////////////////////////////////////// +// Function: RenderAttrib::get_auto_shader_attrib +// Access: Published +// Description: Returns the variant of this RenderAttrib that's most +// relevant for associating with an auto-generated +// shader. This should be a new RenderAttrib of the +// same type as this one, with any superfluous data set +// to neutral. Only the parts of the attrib that +// contribute to the shader should be reflected in the +// returned attrib. The idea is to associate the +// auto-generated shader with the most neutral form of +// all states, to allow it to be shared across as many +// RenderState objects as possible. +// +// If this RenderAttrib is completely irrelevant to the +// auto-shader, this should return NULL to indicate that +// the attrib won't be assocaited with the shader at +// all. In this case the attrib does not contribute to +// the shader meaningfully. +//////////////////////////////////////////////////////////////////// +INLINE CPT(RenderAttrib) RenderAttrib:: +get_auto_shader_attrib(const RenderState *state) const { + return get_auto_shader_attrib_impl(state); +} + //////////////////////////////////////////////////////////////////// // Function: RenderAttrib::register_slot // Access: Public, Static diff --git a/panda/src/pgraph/renderAttrib.cxx b/panda/src/pgraph/renderAttrib.cxx index 9306ddb76a..fcb5ee7b52 100644 --- a/panda/src/pgraph/renderAttrib.cxx +++ b/panda/src/pgraph/renderAttrib.cxx @@ -140,6 +140,16 @@ cull_callback(CullTraverser *, const CullTraverserData &) const { return true; } +//////////////////////////////////////////////////////////////////// +// Function: RenderAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) RenderAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return NULL; +} + //////////////////////////////////////////////////////////////////// // Function: RenderAttrib::unref // Access: Published, Virtual diff --git a/panda/src/pgraph/renderAttrib.h b/panda/src/pgraph/renderAttrib.h index 81a12cac5c..0783080a0b 100644 --- a/panda/src/pgraph/renderAttrib.h +++ b/panda/src/pgraph/renderAttrib.h @@ -28,6 +28,7 @@ class AttribSlots; class GraphicsStateGuardianBase; class CullTraverser; class CullTraverserData; +class RenderState; //////////////////////////////////////////////////////////////////// // Class : RenderAttrib @@ -81,6 +82,7 @@ PUBLISHED: INLINE int compare_to(const RenderAttrib &other) const; INLINE size_t get_hash() const; INLINE CPT(RenderAttrib) get_unique() const; + INLINE CPT(RenderAttrib) get_auto_shader_attrib(const RenderState *state) const; virtual bool unref() const; @@ -185,6 +187,7 @@ protected: virtual size_t get_hash_impl() const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; void output_comparefunc(ostream &out, PandaCompareFunc fn) const; public: diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 5ce2f0799e..27bdb08cff 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -69,6 +69,7 @@ TypeHandle RenderState::_type_handle; RenderState:: RenderState() : _flags(0), + _auto_shader_state(NULL), _lock("RenderState") { // Allocate the _attributes array. @@ -99,6 +100,7 @@ RenderState:: RenderState(const RenderState ©) : _filled_slots(copy._filled_slots), _flags(0), + _auto_shader_state(NULL), _lock("RenderState") { // Allocate the _attributes array. @@ -145,6 +147,14 @@ RenderState:: nassertv(_saved_entry == -1); nassertv(_composition_cache.is_empty() && _invert_composition_cache.is_empty()); + // Make sure the _auto_shader_state cache pointer is cleared. + if (_auto_shader_state != (const RenderState *)NULL) { + if (_auto_shader_state != this) { + cache_unref_delete(_auto_shader_state); + } + _auto_shader_state = NULL; + } + // If this was true at the beginning of the destructor, but is no // longer true now, probably we've been double-deleted. nassertv(get_ref_count() == 0); @@ -843,9 +853,32 @@ get_invert_composition_cache() const { } #endif // HAVE_PYTHON +//////////////////////////////////////////////////////////////////// +// Function: RenderState::get_auto_shader_state +// Access: Published +// Description: Returns the base RenderState that should have the +// generated_shader stored within it, for generated +// shader states. The returned object might be the same +// as this object, or it might be a different +// RenderState with certain attributes removed, or set +// to their default values. +// +// The point is to avoid needless regeneration of the +// shader attrib by storing the generated shader on a +// common RenderState object, with all irrelevant +// attributes removed. +//////////////////////////////////////////////////////////////////// +const RenderState *RenderState:: +get_auto_shader_state() const { + if (_auto_shader_state == (const RenderState *)NULL) { + ((RenderState *)this)->assign_auto_shader_state(); + } + return _auto_shader_state; +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::output -// Access: Published, Virtual +// Access: Published // Description: //////////////////////////////////////////////////////////////////// void RenderState:: @@ -875,7 +908,7 @@ output(ostream &out) const { //////////////////////////////////////////////////////////////////// // Function: RenderState::write -// Access: Published, Virtual +// Access: Published // Description: //////////////////////////////////////////////////////////////////// void RenderState:: @@ -1490,6 +1523,58 @@ do_calc_hash() { _flags |= F_hash_known; } +//////////////////////////////////////////////////////////////////// +// Function: RenderState::assign_auto_shader_state +// Access: Private +// Description: Sets _auto_shader_state to the appropriate +// RenderState object pointer, either the same pointer +// as this object, or some other (simpler) RenderState. +//////////////////////////////////////////////////////////////////// +void RenderState:: +assign_auto_shader_state() { + CPT(RenderState) state = do_calc_auto_shader_state(); + + { + LightReMutexHolder holder(*_states_lock); + if (_auto_shader_state == (const RenderState *)NULL) { + _auto_shader_state = state; + if (_auto_shader_state != this) { + _auto_shader_state->cache_ref(); + } + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: RenderState::do_calc_auto_shader_state +// Access: Private +// Description: Returns the appropriate RenderState that should be +// used to store the auto shader pointer for nodes that +// shader this RenderState. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) RenderState:: +do_calc_auto_shader_state() { + RenderState *state = new RenderState; + + SlotMask mask = _filled_slots; + int slot = mask.get_lowest_on_bit(); + while (slot >= 0) { + const Attribute &attrib = _attributes[slot]; + nassertr(attrib._attrib != (RenderAttrib *)NULL, this); + CPT(RenderAttrib) new_attrib = attrib._attrib->get_auto_shader_attrib(this); + if (new_attrib != NULL) { + nassertr(new_attrib->get_slot() == slot, this); + state->_attributes[slot].set(new_attrib, 0); + state->_filled_slots.set_bit(slot); + } + + mask.clear_bit(slot); + slot = mask.get_lowest_on_bit(); + } + + return return_new(state); +} + //////////////////////////////////////////////////////////////////// // Function: RenderState::return_new @@ -1941,6 +2026,14 @@ void RenderState:: remove_cache_pointers() { nassertv(_states_lock->debug_is_locked()); + // First, make sure the _auto_shader_state cache pointer is cleared. + if (_auto_shader_state != (const RenderState *)NULL) { + if (_auto_shader_state != this) { + cache_unref_delete(_auto_shader_state); + } + _auto_shader_state = NULL; + } + // Fortunately, since we added CompositionCache records in pairs, we // know exactly the set of RenderState objects that have us in their // cache: it's the same set of RenderState objects that we have in diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index 051e92317d..8c5fc27a8b 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -131,6 +131,8 @@ PUBLISHED: PyObject *get_invert_composition_cache() const; #endif // HAVE_PYTHON + const RenderState *get_auto_shader_state() const; + void output(ostream &out) const; void write(ostream &out, int indent_level) const; @@ -167,6 +169,8 @@ private: INLINE bool do_node_unref() const; INLINE void calc_hash(); void do_calc_hash(); + void assign_auto_shader_state(); + CPT(RenderState) do_calc_auto_shader_state(); class CompositionCycleDescEntry { public: @@ -311,12 +315,14 @@ private: int _draw_order; size_t _hash; + const RenderState *_auto_shader_state; + enum Flags { - F_checked_bin_index = 0x000001, - F_checked_cull_callback = 0x000002, - F_has_cull_callback = 0x000004, - F_is_destructing = 0x000008, - F_hash_known = 0x000010, + F_checked_bin_index = 0x000001, + F_checked_cull_callback = 0x000002, + F_has_cull_callback = 0x000004, + F_is_destructing = 0x000008, + F_hash_known = 0x000010, }; unsigned int _flags; diff --git a/panda/src/pgraph/shaderAttrib.cxx b/panda/src/pgraph/shaderAttrib.cxx index e533388aef..e4289c56d7 100755 --- a/panda/src/pgraph/shaderAttrib.cxx +++ b/panda/src/pgraph/shaderAttrib.cxx @@ -732,6 +732,27 @@ compose_impl(const RenderAttrib *other) const { return return_new(attr); } +//////////////////////////////////////////////////////////////////// +// Function: ShaderAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) ShaderAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + // For a ShaderAttrib, we only need to preserve the auto-shader + // flags. Custom shaders, and custom shader inputs, aren't relevant + // to the shader generator. + ShaderAttrib *attrib = new ShaderAttrib; + attrib->_auto_shader = _auto_shader; + attrib->_has_shader = _has_shader; + attrib->_auto_normal_on = _auto_normal_on; + attrib->_auto_glow_on = _auto_glow_on; + attrib->_auto_gloss_on = _auto_gloss_on; + attrib->_auto_ramp_on = _auto_ramp_on; + attrib->_auto_shadow_on = _auto_shadow_on; + return return_new(attrib); +} + //////////////////////////////////////////////////////////////////// // Function: ShaderAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/shaderAttrib.h b/panda/src/pgraph/shaderAttrib.h index 09be382a67..9b83494bc7 100755 --- a/panda/src/pgraph/shaderAttrib.h +++ b/panda/src/pgraph/shaderAttrib.h @@ -119,6 +119,7 @@ protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: diff --git a/panda/src/pgraph/texGenAttrib.cxx b/panda/src/pgraph/texGenAttrib.cxx index d1efb46d4e..464bb2e783 100755 --- a/panda/src/pgraph/texGenAttrib.cxx +++ b/panda/src/pgraph/texGenAttrib.cxx @@ -563,6 +563,16 @@ invert_compose_impl(const RenderAttrib *other) const { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: TexGenAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) TexGenAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: TexGenAttrib::filled_stages // Access: Private diff --git a/panda/src/pgraph/texGenAttrib.h b/panda/src/pgraph/texGenAttrib.h index 99c5c0c029..608805a925 100755 --- a/panda/src/pgraph/texGenAttrib.h +++ b/panda/src/pgraph/texGenAttrib.h @@ -79,6 +79,7 @@ protected: virtual size_t get_hash_impl() const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: class ModeDef; diff --git a/panda/src/pgraph/texMatrixAttrib.cxx b/panda/src/pgraph/texMatrixAttrib.cxx index b90b0047fb..308ff574f2 100644 --- a/panda/src/pgraph/texMatrixAttrib.cxx +++ b/panda/src/pgraph/texMatrixAttrib.cxx @@ -472,6 +472,30 @@ invert_compose_impl(const RenderAttrib *other) const { return return_new(attrib); } +//////////////////////////////////////////////////////////////////// +// Function: TexMatrixAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) TexMatrixAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + // For a TexMatrixAttrib, the particular matrix per TextureStage + // isn't important, just whether there is a matrix at all. So we + // create a new state with an identity matrix everywhere there is a + // matrix at all in the original. + + TexMatrixAttrib *attrib = new TexMatrixAttrib; + + Stages::const_iterator ai; + for (ai = _stages.begin(); ai != _stages.end(); ++ai) { + StageNode sn((*ai)._stage); + sn._transform = TransformState::make_identity(); + attrib->_stages.insert(attrib->_stages.end(), sn); + } + + return return_new(attrib); +} + //////////////////////////////////////////////////////////////////// // Function: TexMatrixAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/texMatrixAttrib.h b/panda/src/pgraph/texMatrixAttrib.h index 813ebd2a7b..a6a29e155a 100644 --- a/panda/src/pgraph/texMatrixAttrib.h +++ b/panda/src/pgraph/texMatrixAttrib.h @@ -70,6 +70,7 @@ protected: virtual size_t get_hash_impl() const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: INLINE void check_stage_list() const; diff --git a/panda/src/pgraph/textureAttrib.cxx b/panda/src/pgraph/textureAttrib.cxx index d6db6534b1..7afddd99e3 100644 --- a/panda/src/pgraph/textureAttrib.cxx +++ b/panda/src/pgraph/textureAttrib.cxx @@ -769,6 +769,16 @@ invert_compose_impl(const RenderAttrib *other) const { return other; } +//////////////////////////////////////////////////////////////////// +// Function: TextureAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) TextureAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: TextureAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/textureAttrib.h b/panda/src/pgraph/textureAttrib.h index 63da0ee88d..f9bd610dc9 100644 --- a/panda/src/pgraph/textureAttrib.h +++ b/panda/src/pgraph/textureAttrib.h @@ -93,6 +93,7 @@ protected: virtual size_t get_hash_impl() const; virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: INLINE void check_sorted() const; diff --git a/panda/src/pgraph/transparencyAttrib.cxx b/panda/src/pgraph/transparencyAttrib.cxx index e31a38d64f..2b20559bc8 100644 --- a/panda/src/pgraph/transparencyAttrib.cxx +++ b/panda/src/pgraph/transparencyAttrib.cxx @@ -123,6 +123,16 @@ get_hash_impl() const { return hash; } +//////////////////////////////////////////////////////////////////// +// Function: TransparencyAttrib::get_auto_shader_attrib_impl +// Access: Protected, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +CPT(RenderAttrib) TransparencyAttrib:: +get_auto_shader_attrib_impl(const RenderState *state) const { + return this; +} + //////////////////////////////////////////////////////////////////// // Function: TransparencyAttrib::register_with_read_factory // Access: Public, Static diff --git a/panda/src/pgraph/transparencyAttrib.h b/panda/src/pgraph/transparencyAttrib.h index 318ce849d4..b653641207 100644 --- a/panda/src/pgraph/transparencyAttrib.h +++ b/panda/src/pgraph/transparencyAttrib.h @@ -63,6 +63,7 @@ public: protected: virtual int compare_to_impl(const RenderAttrib *other) const; virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const; private: Mode _mode;