ShaderGenerator: fix toggling shadows while shader gen is on

This commit is contained in:
rdb 2018-12-31 14:07:14 +01:00
parent 83374de0ff
commit 4699dfcd5b
4 changed files with 80 additions and 51 deletions

View File

@ -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;
}

View File

@ -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 &copy) :
_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.

View File

@ -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 &copy);
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;

View File

@ -294,9 +294,15 @@ 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()) {
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;
}