diff --git a/panda/src/pgraphnodes/lightLensNode.I b/panda/src/pgraphnodes/lightLensNode.I index 9c59b6c998..4fd1138b03 100644 --- a/panda/src/pgraphnodes/lightLensNode.I +++ b/panda/src/pgraphnodes/lightLensNode.I @@ -28,51 +28,6 @@ is_shadow_caster() const { return _shadow_caster; } -/** - * Sets the flag indicating whether this light should cast shadows or not. - * This is the variant without buffer size, meaning that the current buffer - * size will be kept (512x512 is the default). Note that enabling shadows will - * require the shader generator to be enabled on the scene. - */ -INLINE void LightLensNode:: -set_shadow_caster(bool caster) { - if (_shadow_caster && !caster) { - clear_shadow_buffers(); - } - _shadow_caster = caster; - set_active(caster); - if (caster) { - setup_shadow_map(); - } -} - -/** - * Sets the flag indicating whether this light should cast shadows or not. - * The xsize and ysize parameters specify the size of the shadow buffer that - * will be set up, the sort parameter specifies the sort. Note that enabling - * shadows will require the shader generator to be enabled on the scene. - */ -INLINE void LightLensNode:: -set_shadow_caster(bool caster, int buffer_xsize, int buffer_ysize, int buffer_sort) { - if ((_shadow_caster && !caster) || buffer_xsize != _sb_size[0] || buffer_ysize != _sb_size[1]) { - clear_shadow_buffers(); - } - _shadow_caster = caster; - _sb_size.set(buffer_xsize, buffer_ysize); - - if (buffer_sort != _sb_sort) { - ShadowBuffers::iterator it; - for(it = _sbuffers.begin(); it != _sbuffers.end(); ++it) { - (*it).second->set_sort(buffer_sort); - } - _sb_sort = buffer_sort; - } - set_active(caster); - if (caster) { - setup_shadow_map(); - } -} - /** * Returns the sort of the shadow buffer to be created for this light source. */ @@ -115,3 +70,11 @@ get_shadow_buffer(GraphicsStateGuardianBase *gsg) { return (*it).second; } } + +/** + * Marks this light as having been used by the auto shader. + */ +INLINE void LightLensNode:: +mark_used_by_auto_shader() const { + _used_by_auto_shader = true; +} diff --git a/panda/src/pgraphnodes/lightLensNode.cxx b/panda/src/pgraphnodes/lightLensNode.cxx index 87f9a5bca8..aaa290e08b 100644 --- a/panda/src/pgraphnodes/lightLensNode.cxx +++ b/panda/src/pgraphnodes/lightLensNode.cxx @@ -19,6 +19,7 @@ #include "renderState.h" #include "cullFaceAttrib.h" #include "colorWriteAttrib.h" +#include "graphicsStateGuardianBase.h" TypeHandle LightLensNode::_type_handle; @@ -29,7 +30,8 @@ LightLensNode:: LightLensNode(const std::string &name, Lens *lens) : Camera(name, lens), _has_specular_color(false), - _attrib_count(0) + _attrib_count(0), + _used_by_auto_shader(false) { set_active(false); _shadow_caster = false; @@ -65,13 +67,67 @@ LightLensNode(const LightLensNode ©) : _sb_size(copy._sb_size), _sb_sort(-10), _has_specular_color(copy._has_specular_color), - _attrib_count(0) + _attrib_count(0), + _used_by_auto_shader(false) { if (_shadow_caster) { setup_shadow_map(); } } +/** + * Sets the flag indicating whether this light should cast shadows or not. + * This is the variant without buffer size, meaning that the current buffer + * size will be kept (512x512 is the default). Note that enabling shadows will + * require the shader generator to be enabled on the scene. + */ +void LightLensNode:: +set_shadow_caster(bool caster) { + if (_shadow_caster && !caster) { + clear_shadow_buffers(); + } + if (_shadow_caster != caster && _used_by_auto_shader) { + // Make sure any shaders using this light are regenerated. + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); + } + _shadow_caster = caster; + set_active(caster); + if (caster) { + setup_shadow_map(); + } +} + +/** + * Sets the flag indicating whether this light should cast shadows or not. + * The xsize and ysize parameters specify the size of the shadow buffer that + * will be set up, the sort parameter specifies the sort. Note that enabling + * shadows will require the shader generator to be enabled on the scene. + */ +void LightLensNode:: +set_shadow_caster(bool caster, int buffer_xsize, int buffer_ysize, int buffer_sort) { + if ((_shadow_caster && !caster) || buffer_xsize != _sb_size[0] || buffer_ysize != _sb_size[1]) { + clear_shadow_buffers(); + } + if (_shadow_caster != caster && _used_by_auto_shader) { + // Make sure any shaders using this light are regenerated. + GraphicsStateGuardianBase::mark_rehash_generated_shaders(); + } + _shadow_caster = caster; + _sb_size.set(buffer_xsize, buffer_ysize); + + if (buffer_sort != _sb_sort) { + ShadowBuffers::iterator it; + for(it = _sbuffers.begin(); it != _sbuffers.end(); ++it) { + (*it).second->set_sort(buffer_sort); + } + _sb_sort = buffer_sort; + } + set_active(caster); + if (caster) { + setup_shadow_map(); + } +} + /** * Clears the shadow buffers, meaning they will be automatically recreated * when the Shader Generator needs them. diff --git a/panda/src/pgraphnodes/lightLensNode.h b/panda/src/pgraphnodes/lightLensNode.h index 4398f02bfd..f045c539b3 100644 --- a/panda/src/pgraphnodes/lightLensNode.h +++ b/panda/src/pgraphnodes/lightLensNode.h @@ -38,8 +38,8 @@ PUBLISHED: INLINE bool has_specular_color() const; INLINE bool is_shadow_caster() const; - INLINE void set_shadow_caster(bool caster); - INLINE void set_shadow_caster(bool caster, int buffer_xsize, int buffer_ysize, int sort = -10); + void set_shadow_caster(bool caster); + void set_shadow_caster(bool caster, int buffer_xsize, int buffer_ysize, int sort = -10); INLINE int get_shadow_buffer_sort() const; @@ -52,6 +52,9 @@ PUBLISHED: MAKE_PROPERTY(shadow_caster, is_shadow_caster); MAKE_PROPERTY(shadow_buffer_size, get_shadow_buffer_size, set_shadow_buffer_size); +public: + INLINE void mark_used_by_auto_shader() const; + protected: LightLensNode(const LightLensNode ©); void clear_shadow_buffers(); @@ -61,6 +64,7 @@ protected: bool _shadow_caster; bool _has_specular_color; int _sb_sort; + mutable bool _used_by_auto_shader = false; PT(Texture) _shadow_map; diff --git a/panda/src/pgraphnodes/shaderGenerator.cxx b/panda/src/pgraphnodes/shaderGenerator.cxx index cf8f0783d4..16a7483478 100644 --- a/panda/src/pgraphnodes/shaderGenerator.cxx +++ b/panda/src/pgraphnodes/shaderGenerator.cxx @@ -294,8 +294,14 @@ analyze_renderstate(ShaderKey &key, const RenderState *rs) { if (node->is_of_type(LightLensNode::get_class_type())) { const LightLensNode *llnode = (const LightLensNode *)node; - if (shader_attrib->auto_shadow_on() && llnode->is_shadow_caster()) { - info._flags |= ShaderKey::LF_has_shadows; + if (shader_attrib->auto_shadow_on()) { + if (llnode->is_shadow_caster()) { + info._flags |= ShaderKey::LF_has_shadows; + } + + // Make sure that the next time the shadows are toggled on this + // light, it triggers a state rehash. + llnode->mark_used_by_auto_shader(); } if (llnode->has_specular_color()) { info._flags |= ShaderKey::LF_has_specular_color;