mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-27 03:26:38 +00:00 
			
		
		
		
	To prevent crash:
==7733==ERROR: AddressSanitizer: heap-use-after-free on address 0x6040000ca1b0 at pc 0x55fcfa8d1ee3 bp 0x7ffd1c464e00 sp 0x7ffd1c464df0
READ of size 4 at 0x6040000ca1b0 thread T0
    #0 0x55fcfa8d1ee2 in std::less<unsigned int>::operator()(unsigned int const&, unsigned int const&) const /usr/include/c++/11.1.0/bits/stl_function.h:386
    #1 0x55fcfa8d1ee2 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> >, std::_Select1st<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::_M_lower_bound(std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >*, std::_Rb_tree_node_base*, unsigned int const&) /usr/include/c++/11.1.0/bits/stl_tree.h:1903
    #2 0x55fcfa8ca76e in std::_Rb_tree<unsigned int, std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> >, std::_Select1st<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::lower_bound(unsigned int const&) /usr/include/c++/11.1.0/bits/stl_tree.h:1270
    #3 0x55fcfa8ca76e in std::map<unsigned int, osg::ref_ptr<osg::ContextData>, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::lower_bound(unsigned int const&) /usr/include/c++/11.1.0/bits/stl_map.h:1259
    #4 0x55fcfa8ca76e in std::map<unsigned int, osg::ref_ptr<osg::ContextData>, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::operator[](unsigned int const&) /usr/include/c++/11.1.0/bits/stl_map.h:497
    #5 0x55fcfa8ca76e in osg::getOrCreateContextData(unsigned int) /home/elsid/dev/OpenSceneGraph/src/osg/ContextData.cpp:142
    #6 0x55fcfab6848a in GLShaderManager* osg::get<GLShaderManager>(unsigned int) /home/elsid/dev/OpenSceneGraph/include/osg/ContextData:154
    #7 0x55fcfab6848a in osg::Shader::PerContextShader::~PerContextShader() /home/elsid/dev/OpenSceneGraph/src/osg/Shader.cpp:540
    #8 0x55fcfab68dc6 in osg::Shader::PerContextShader::~PerContextShader() /home/elsid/dev/OpenSceneGraph/src/osg/Shader.cpp:541
    #9 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292
    #10 0x55fcfab6d0ce in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201
    #11 0x55fcfab6d0ce in osg::ref_ptr<osg::Shader::PerContextShader>::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44
    #12 0x55fcfab6d0ce in void std::_Destroy<osg::ref_ptr<osg::Shader::PerContextShader> >(osg::ref_ptr<osg::Shader::PerContextShader>*) /usr/include/c++/11.1.0/bits/stl_construct.h:140
    #13 0x55fcfab6d0ce in void std::_Destroy_aux<false>::__destroy<osg::ref_ptr<osg::Shader::PerContextShader>*>(osg::ref_ptr<osg::Shader::PerContextShader>*, osg::ref_ptr<osg::Shader::PerContextShader>*) /usr/include/c++/11.1.0/bits/stl_construct.h:152
    #14 0x55fcfab6d0ce in void std::_Destroy<osg::ref_ptr<osg::Shader::PerContextShader>*>(osg::ref_ptr<osg::Shader::PerContextShader>*, osg::ref_ptr<osg::Shader::PerContextShader>*) /usr/include/c++/11.1.0/bits/stl_construct.h:185
    #15 0x55fcfab6d0ce in void std::_Destroy<osg::ref_ptr<osg::Shader::PerContextShader>*, osg::ref_ptr<osg::Shader::PerContextShader> >(osg::ref_ptr<osg::Shader::PerContextShader>*, osg::ref_ptr<osg::Shader::PerContextShader>*, std::allocator<osg::ref_ptr<osg::Shader::PerContextShader> >&) /usr/include/c++/11.1.0/bits/alloc_traits.h:746
    #16 0x55fcfab6d0ce in std::vector<osg::ref_ptr<osg::Shader::PerContextShader>, std::allocator<osg::ref_ptr<osg::Shader::PerContextShader> > >::~vector() /usr/include/c++/11.1.0/bits/stl_vector.h:680
    #17 0x55fcfab6d0ce in osg::Shader::ShaderObjects::~ShaderObjects() /home/elsid/dev/OpenSceneGraph/include/osg/Shader:264
    #18 0x55fcfab6d0ce in osg::Shader::ShaderObjects::~ShaderObjects() /home/elsid/dev/OpenSceneGraph/include/osg/Shader:264
    #19 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292
    #20 0x55fcfab6c532 in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201
    #21 0x55fcfab6c532 in osg::ref_ptr<osg::Shader::ShaderObjects>::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44
    #22 0x55fcfab6c532 in void std::_Destroy<osg::ref_ptr<osg::Shader::ShaderObjects> >(osg::ref_ptr<osg::Shader::ShaderObjects>*) /usr/include/c++/11.1.0/bits/stl_construct.h:140
    #23 0x55fcfab6c532 in void std::_Destroy_aux<false>::__destroy<osg::ref_ptr<osg::Shader::ShaderObjects>*>(osg::ref_ptr<osg::Shader::ShaderObjects>*, osg::ref_ptr<osg::Shader::ShaderObjects>*) /usr/include/c++/11.1.0/bits/stl_construct.h:152
    #24 0x55fcfab6c532 in void std::_Destroy<osg::ref_ptr<osg::Shader::ShaderObjects>*>(osg::ref_ptr<osg::Shader::ShaderObjects>*, osg::ref_ptr<osg::Shader::ShaderObjects>*) /usr/include/c++/11.1.0/bits/stl_construct.h:185
    #25 0x55fcfab6c532 in void std::_Destroy<osg::ref_ptr<osg::Shader::ShaderObjects>*, osg::ref_ptr<osg::Shader::ShaderObjects> >(osg::ref_ptr<osg::Shader::ShaderObjects>*, osg::ref_ptr<osg::Shader::ShaderObjects>*, std::allocator<osg::ref_ptr<osg::Shader::ShaderObjects> >&) /usr/include/c++/11.1.0/bits/alloc_traits.h:746
    #26 0x55fcfab6c532 in std::vector<osg::ref_ptr<osg::Shader::ShaderObjects>, std::allocator<osg::ref_ptr<osg::Shader::ShaderObjects> > >::~vector() /usr/include/c++/11.1.0/bits/stl_vector.h:680
    #27 0x55fcfab6c532 in osg::buffered_value<osg::ref_ptr<osg::Shader::ShaderObjects> >::~buffered_value() /home/elsid/dev/OpenSceneGraph/include/osg/buffered_value:26
    #28 0x55fcfab6c532 in osg::Shader::~Shader() /home/elsid/dev/OpenSceneGraph/src/osg/Shader.cpp:271
    #29 0x55fcfab6c80a in osg::Shader::~Shader() /home/elsid/dev/OpenSceneGraph/src/osg/Shader.cpp:271
    #30 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292
    #31 0x55fcfab185bd in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201
    #32 0x55fcfab185bd in osg::ref_ptr<osg::Shader>::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44
    #33 0x55fcfab185bd in void std::_Destroy<osg::ref_ptr<osg::Shader> >(osg::ref_ptr<osg::Shader>*) /usr/include/c++/11.1.0/bits/stl_construct.h:140
    #34 0x55fcfab185bd in void std::_Destroy_aux<false>::__destroy<osg::ref_ptr<osg::Shader>*>(osg::ref_ptr<osg::Shader>*, osg::ref_ptr<osg::Shader>*) /usr/include/c++/11.1.0/bits/stl_construct.h:152
    #35 0x55fcfab185bd in void std::_Destroy<osg::ref_ptr<osg::Shader>*>(osg::ref_ptr<osg::Shader>*, osg::ref_ptr<osg::Shader>*) /usr/include/c++/11.1.0/bits/stl_construct.h:185
    #36 0x55fcfab185bd in void std::_Destroy<osg::ref_ptr<osg::Shader>*, osg::ref_ptr<osg::Shader> >(osg::ref_ptr<osg::Shader>*, osg::ref_ptr<osg::Shader>*, std::allocator<osg::ref_ptr<osg::Shader> >&) /usr/include/c++/11.1.0/bits/alloc_traits.h:746
    #37 0x55fcfab185bd in std::vector<osg::ref_ptr<osg::Shader>, std::allocator<osg::ref_ptr<osg::Shader> > >::~vector() /usr/include/c++/11.1.0/bits/stl_vector.h:680
    #38 0x55fcfab185bd in osg::Program::~Program() /home/elsid/dev/OpenSceneGraph/src/osg/Program.cpp:147
    #39 0x55fcfab18ae0 in osg::Program::~Program() /home/elsid/dev/OpenSceneGraph/src/osg/Program.cpp:147
    #40 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292
    #41 0x55fcf8582cfa in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/build/gcc/asan/install/include/osg/Referenced:201
    #42 0x55fcf8582cfa in osg::ref_ptr<osg::StateAttribute>::~ref_ptr() /home/elsid/dev/OpenSceneGraph/build/gcc/asan/install/include/osg/ref_ptr:44
    #43 0x55fcf8582cfa in std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int>::~pair() /usr/include/c++/11.1.0/bits/stl_pair.h:211
    #44 0x55fcf8582cfa in std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> >::~pair() /usr/include/c++/11.1.0/bits/stl_pair.h:211
    #45 0x55fcf8582cfa in void __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > > >::destroy<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > >(std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> >*) /usr/include/c++/11.1.0/ext/new_allocator.h:162
    #46 0x55fcf8582cfa in void std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > > > >::destroy<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > >(std::allocator<std::_Rb_tree_node<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > > >&, std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> >*) /usr/include/c++/11.1.0/bits/alloc_traits.h:531
    #47 0x55fcf8582cfa in std::_Rb_tree<std::pair<osg::StateAttribute::Type, unsigned int>, std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> >, std::_Select1st<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > >, std::less<std::pair<osg::StateAttribute::Type, unsigned int> >, std::allocator<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > > >::_M_destroy_node(std::_Rb_tree_node<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:623
    #48 0x55fcf8582cfa in std::_Rb_tree<std::pair<osg::StateAttribute::Type, unsigned int>, std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> >, std::_Select1st<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > >, std::less<std::pair<osg::StateAttribute::Type, unsigned int> >, std::allocator<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > > >::_M_drop_node(std::_Rb_tree_node<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:631
    #49 0x55fcf8582cfa in std::_Rb_tree<std::pair<osg::StateAttribute::Type, unsigned int>, std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> >, std::_Select1st<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > >, std::less<std::pair<osg::StateAttribute::Type, unsigned int> >, std::allocator<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > > >::_M_erase(std::_Rb_tree_node<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1889
    #50 0x55fcfac1f281 in std::_Rb_tree<std::pair<osg::StateAttribute::Type, unsigned int>, std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> >, std::_Select1st<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > >, std::less<std::pair<osg::StateAttribute::Type, unsigned int> >, std::allocator<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > > >::clear() /usr/include/c++/11.1.0/bits/stl_tree.h:1254
    #51 0x55fcfac1f281 in std::map<std::pair<osg::StateAttribute::Type, unsigned int>, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int>, std::less<std::pair<osg::StateAttribute::Type, unsigned int> >, std::allocator<std::pair<std::pair<osg::StateAttribute::Type, unsigned int> const, std::pair<osg::ref_ptr<osg::StateAttribute>, unsigned int> > > >::clear() /usr/include/c++/11.1.0/bits/stl_map.h:1134
    #52 0x55fcfac1f281 in osg::StateSet::clear() /home/elsid/dev/OpenSceneGraph/src/osg/StateSet.cpp:738
    #53 0x55fcfac2079e in osg::StateSet::~StateSet() /home/elsid/dev/OpenSceneGraph/src/osg/StateSet.cpp:285
    #54 0x55fcfac20d3e in osg::StateSet::~StateSet() /home/elsid/dev/OpenSceneGraph/src/osg/StateSet.cpp:286
    #55 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292
    #56 0x55fcfb20dcac in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/build/gcc/asan/install/include/osg/Referenced:201
    #57 0x55fcfb20dcac in osg::ref_ptr<osg::StateSet>::~ref_ptr() /home/elsid/dev/OpenSceneGraph/build/gcc/asan/install/include/osg/ref_ptr:44
    #58 0x55fcfb20dcac in std::array<osg::ref_ptr<osg::StateSet>, 8ul>::~array() /usr/include/c++/11.1.0/array:95
    #59 0x55fcfb20dcac in SceneUtil::ShadowsBin::~ShadowsBin() /home/elsid/dev/openmw/components/sceneutil/shadowsbin.hpp:16
    #60 0x55fcfb20dcac in SceneUtil::ShadowsBin::~ShadowsBin() /home/elsid/dev/openmw/components/sceneutil/shadowsbin.hpp:16
    #61 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292
    #62 0x55fcfa6cc17f in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201
    #63 0x55fcfa6cc17f in osg::ref_ptr<osgUtil::RenderBin>::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44
    #64 0x55fcfa6cc17f in std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> >::~pair() /usr/include/c++/11.1.0/bits/stl_pair.h:211
    #65 0x55fcfa6cc17f in void __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > >::destroy<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> >*) /usr/include/c++/11.1.0/ext/new_allocator.h:162
    #66 0x55fcfa6cc17f in void std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > > >::destroy<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >(std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > >&, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> >*) /usr/include/c++/11.1.0/bits/alloc_traits.h:531
    #67 0x55fcfa6cc17f in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > >::_M_destroy_node(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:623
    #68 0x55fcfa6cc17f in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > >::_M_drop_node(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:631
    #69 0x55fcfa6cc17f in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > >::_M_erase(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1889
    #70 0x55fcfa6cc122 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > >::_M_erase(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1887
    #71 0x55fcfa6cc122 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > >::_M_erase(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1887
    #72 0x55fcfa6cc245 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > >::~_Rb_tree() /usr/include/c++/11.1.0/bits/stl_tree.h:984
    #73 0x55fcfa6cc245 in std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, osg::ref_ptr<osgUtil::RenderBin>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, osg::ref_ptr<osgUtil::RenderBin> > > >::~map() /usr/include/c++/11.1.0/bits/stl_map.h:302
    #74 0x55fcfa6cc245 in RenderBinPrototypeList::~RenderBinPrototypeList() /home/elsid/dev/OpenSceneGraph/src/osgUtil/RenderBin.cpp:48
    #75 0x55fcfa6cc245 in RenderBinPrototypeList::~RenderBinPrototypeList() /home/elsid/dev/OpenSceneGraph/src/osgUtil/RenderBin.cpp:48
    #76 0x55fcfab4a3f3 in osg::Referenced::signalObserversAndDelete(bool, bool) const /home/elsid/dev/OpenSceneGraph/src/osg/Referenced.cpp:292
    #77 0x55fcfa6cbcc1 in osg::Referenced::unref() const /home/elsid/dev/OpenSceneGraph/include/osg/Referenced:201
    #78 0x55fcfa6cbcc1 in osg::ref_ptr<RenderBinPrototypeList>::~ref_ptr() /home/elsid/dev/OpenSceneGraph/include/osg/ref_ptr:44
    #79 0x7f3977bd04a6 in __run_exit_handlers (/usr/lib/libc.so.6+0x3f4a6)
    #80 0x7f3977bd064d in exit (/usr/lib/libc.so.6+0x3f64d)
    #81 0x7f3977bb8b2b in __libc_start_main (/usr/lib/libc.so.6+0x27b2b)
    #82 0x55fcf81ea12d in _start (/home/elsid/dev/openmw/build/gcc/asan/openmw+0xa4412d)
0x6040000ca1b0 is located 32 bytes inside of 48-byte region [0x6040000ca190,0x6040000ca1c0)
freed by thread T0 here:
    #0 0x7f397a633d69 in operator delete(void*, unsigned long) /build/gcc/src/gcc/libsanitizer/asan/asan_new_delete.cpp:172
    #1 0x55fcfa8d1824 in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::deallocate(std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >*, unsigned long) /usr/include/c++/11.1.0/ext/new_allocator.h:139
    #2 0x55fcfa8d1824 in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > > >::deallocate(std::allocator<std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >&, std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >*, unsigned long) /usr/include/c++/11.1.0/bits/alloc_traits.h:492
    #3 0x55fcfa8d1824 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> >, std::_Select1st<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::_M_put_node(std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:565
    #4 0x55fcfa8d1824 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> >, std::_Select1st<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::_M_drop_node(std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:632
    #5 0x55fcfa8d1824 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> >, std::_Select1st<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::_M_erase(std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >*) /usr/include/c++/11.1.0/bits/stl_tree.h:1889
    #6 0x55fcfa8d18da in std::_Rb_tree<unsigned int, std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> >, std::_Select1st<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::~_Rb_tree() /usr/include/c++/11.1.0/bits/stl_tree.h:984
    #7 0x55fcfa8d18da in std::map<unsigned int, osg::ref_ptr<osg::ContextData>, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::~map() /usr/include/c++/11.1.0/bits/stl_map.h:302
    #8 0x7f3977bd04a6 in __run_exit_handlers (/usr/lib/libc.so.6+0x3f4a6)
previously allocated by thread T0 here:
    #0 0x7f397a632ca1 in operator new(unsigned long) /build/gcc/src/gcc/libsanitizer/asan/asan_new_delete.cpp:99
    #1 0x55fcfa8d3aa1 in __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::allocate(unsigned long, void const*) /usr/include/c++/11.1.0/ext/new_allocator.h:121
    #2 0x55fcfa8d3aa1 in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >&, unsigned long) /usr/include/c++/11.1.0/bits/alloc_traits.h:460
    #3 0x55fcfa8d3aa1 in std::_Rb_tree<unsigned int, std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> >, std::_Select1st<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::_M_get_node() /usr/include/c++/11.1.0/bits/stl_tree.h:561
    #4 0x55fcfa8d3aa1 in std::_Rb_tree_node<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >* std::_Rb_tree<unsigned int, std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> >, std::_Select1st<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::_M_create_node<std::piecewise_construct_t const&, std::tuple<unsigned int const&>, std::tuple<> >(std::piecewise_construct_t const&, std::tuple<unsigned int const&>&&, std::tuple<>&&) /usr/include/c++/11.1.0/bits/stl_tree.h:611
    #5 0x55fcfa8d3aa1 in std::_Rb_tree_iterator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > std::_Rb_tree<unsigned int, std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> >, std::_Select1st<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::_M_emplace_hint_unique<std::piecewise_construct_t const&, std::tuple<unsigned int const&>, std::tuple<> >(std::_Rb_tree_const_iterator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > >, std::piecewise_construct_t const&, std::tuple<unsigned int const&>&&, std::tuple<>&&) /usr/include/c++/11.1.0/bits/stl_tree.h:2429
    #6 0x55fcfa8cfd91 in std::map<unsigned int, osg::ref_ptr<osg::ContextData>, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, osg::ref_ptr<osg::ContextData> > > >::operator[](unsigned int const&) /usr/include/c++/11.1.0/bits/stl_map.h:501
    #7 0x55fcfa8cfd91 in osg::ContextData::createNewContextID() /home/elsid/dev/OpenSceneGraph/src/osg/ContextData.cpp:171
    #8 0x55fcfa9be218 in osg::GraphicsContext::createNewContextID() /home/elsid/dev/OpenSceneGraph/src/osg/GraphicsContext.cpp:320
    #9 0x55fcfb68d1ef in SDLUtil::GraphicsWindowSDL2::GraphicsWindowSDL2(osg::GraphicsContext::Traits*) /home/elsid/dev/openmw/components/sdlutil/sdlgraphicswindow.cpp:39
    #10 0x55fcfa17f93a in OMW::Engine::createWindow(Settings::Manager&) /home/elsid/dev/openmw/apps/openmw/engine.cpp:611
    #11 0x55fcfa18398f in OMW::Engine::prepareEngine(Settings::Manager&) /home/elsid/dev/openmw/apps/openmw/engine.cpp:679
    #12 0x55fcfa18c4f2 in OMW::Engine::go() /home/elsid/dev/openmw/apps/openmw/engine.cpp:949
    #13 0x55fcfa13c9ff in runApplication(int, char**) /home/elsid/dev/openmw/apps/openmw/main.cpp:316
    #14 0x55fcfb49f562 in wrapApplication(int (*)(int, char**), int, char**, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /home/elsid/dev/openmw/components/debug/debugging.cpp:205
    #15 0x55fcfa133114 in main /home/elsid/dev/openmw/apps/openmw/main.cpp:328
    #16 0x7f3977bb8b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/c++/11.1.0/bits/stl_function.h:386 in std::less<unsigned int>::operator()(unsigned int const&, unsigned int const&) const
Shadow bytes around the buggy address:
  0x0c08800113e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c08800113f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880011400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880011410: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880011420: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c0880011430: fa fa fd fd fd fd[fd]fd fa fa fa fa fa fa fa fa
  0x0c0880011440: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880011450: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880011460: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880011470: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880011480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==7733==ABORTING
		
	
			
		
			
				
	
	
		
			217 lines
		
	
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			217 lines
		
	
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "shadowsbin.hpp"
 | |
| #include <unordered_set>
 | |
| #include <osg/StateSet>
 | |
| #include <osg/AlphaFunc>
 | |
| #include <osg/Material>
 | |
| #include <osg/Program>
 | |
| #include <osgUtil/StateGraph>
 | |
| 
 | |
| using namespace osgUtil;
 | |
| 
 | |
| namespace
 | |
| {
 | |
|     template <typename T>
 | |
|     inline void accumulateState(T& currentValue, T newValue, bool& isOverride, unsigned int overrideFlags)
 | |
|     {
 | |
|         if (isOverride && !(overrideFlags & osg::StateAttribute::PROTECTED)) return;
 | |
| 
 | |
|         if (overrideFlags & osg::StateAttribute::OVERRIDE)
 | |
|             isOverride = true;
 | |
| 
 | |
|         currentValue = newValue;
 | |
|     }
 | |
| 
 | |
|     inline void accumulateModeState(const osg::StateSet* ss, bool& currentValue, bool& isOverride, int mode)
 | |
|     {
 | |
|         const osg::StateSet::ModeList& l = ss->getModeList();
 | |
|         osg::StateSet::ModeList::const_iterator mf = l.find(mode);
 | |
|         if (mf == l.end())
 | |
|             return;
 | |
|         unsigned int flags = mf->second;
 | |
|         bool newValue = flags & osg::StateAttribute::ON;
 | |
|         accumulateState(currentValue, newValue, isOverride, flags);
 | |
|     }
 | |
| 
 | |
|     inline bool materialNeedShadows(osg::Material* m)
 | |
|     {
 | |
|         // I'm pretty sure this needs to check the colour mode - vertex colours might override this value.
 | |
|         return m->getDiffuse(osg::Material::FRONT).a() > 0.5;
 | |
|     }
 | |
| }
 | |
| 
 | |
| namespace SceneUtil
 | |
| {
 | |
| 
 | |
| ShadowsBin::ShadowsBin(const CastingPrograms& castingPrograms)
 | |
| {
 | |
|     mNoTestStateSet = new osg::StateSet;
 | |
|     mNoTestStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", false));
 | |
|     mNoTestStateSet->addUniform(new osg::Uniform("alphaTestShadows", false));
 | |
| 
 | |
|     mShaderAlphaTestStateSet = new osg::StateSet;
 | |
|     mShaderAlphaTestStateSet->addUniform(new osg::Uniform("alphaTestShadows", true));
 | |
|     mShaderAlphaTestStateSet->addUniform(new osg::Uniform("useDiffuseMapForShadowAlpha", true));
 | |
|     mShaderAlphaTestStateSet->setMode(GL_BLEND, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE);
 | |
| 
 | |
|     for (size_t i = 0; i < castingPrograms.size(); ++i)
 | |
|     {
 | |
|         mAlphaFuncShaders[i] = new osg::StateSet;
 | |
|         mAlphaFuncShaders[i]->setAttribute(castingPrograms[i], osg::StateAttribute::ON | osg::StateAttribute::PROTECTED | osg::StateAttribute::OVERRIDE);
 | |
|     }
 | |
| }
 | |
| 
 | |
| StateGraph* ShadowsBin::cullStateGraph(StateGraph* sg, StateGraph* root, std::unordered_set<StateGraph*>& uninterestingCache, bool cullFaceOverridden)
 | |
| {
 | |
|     std::vector<StateGraph*> return_path;
 | |
|     State state;
 | |
|     StateGraph* sg_new = sg;
 | |
|     do
 | |
|     {
 | |
|         if (uninterestingCache.find(sg_new) != uninterestingCache.end())
 | |
|             break;
 | |
|         return_path.push_back(sg_new);
 | |
|         sg_new = sg_new->_parent;
 | |
|     } while (sg_new && sg_new != root);
 | |
| 
 | |
|     for(auto itr=return_path.rbegin(); itr!=return_path.rend(); ++itr)
 | |
|     {
 | |
|         const osg::StateSet* ss = (*itr)->getStateSet();
 | |
|         if (!ss)
 | |
|             continue;
 | |
| 
 | |
|         accumulateModeState(ss, state.mAlphaBlend, state.mAlphaBlendOverride, GL_BLEND);
 | |
| 
 | |
|         const osg::StateSet::AttributeList& attributes = ss->getAttributeList();
 | |
|         osg::StateSet::AttributeList::const_iterator found = attributes.find(std::make_pair(osg::StateAttribute::MATERIAL, 0));
 | |
|         if (found != attributes.end())
 | |
|         {
 | |
|             const osg::StateSet::RefAttributePair& rap = found->second;
 | |
|             accumulateState(state.mMaterial, static_cast<osg::Material*>(rap.first.get()), state.mMaterialOverride, rap.second);
 | |
|             if (state.mMaterial && !materialNeedShadows(state.mMaterial))
 | |
|                 state.mMaterial = nullptr;
 | |
|         }
 | |
| 
 | |
|         found = attributes.find(std::make_pair(osg::StateAttribute::ALPHAFUNC, 0));
 | |
|         if (found != attributes.end())
 | |
|         {
 | |
|             // As force shaders is on, we know this is really a RemovedAlphaFunc
 | |
|             const osg::StateSet::RefAttributePair& rap = found->second;
 | |
|             accumulateState(state.mAlphaFunc, static_cast<osg::AlphaFunc*>(rap.first.get()), state.mAlphaFuncOverride, rap.second);
 | |
|         }
 | |
| 
 | |
|         if (!cullFaceOverridden)
 | |
|         {
 | |
|             // osg::FrontFace specifies triangle winding, not front-face culling. We can't safely reparent anything under it unless GL_CULL_FACE is off or we flip face culling.
 | |
|             found = attributes.find(std::make_pair(osg::StateAttribute::FRONTFACE, 0));
 | |
|             if (found != attributes.end())
 | |
|                 state.mImportantState = true;
 | |
|         }
 | |
| 
 | |
|         if ((*itr) != sg && !state.interesting())
 | |
|             uninterestingCache.insert(*itr);
 | |
|     }
 | |
| 
 | |
|     if (!state.needShadows())
 | |
|         return nullptr;
 | |
| 
 | |
|     if (!state.needTexture() && !state.mImportantState)
 | |
|     {
 | |
|         for (RenderLeaf* leaf : sg->_leaves)
 | |
|         {
 | |
|             leaf->_parent = root;
 | |
|             root->_leaves.push_back(leaf);
 | |
|         }
 | |
|         return nullptr;
 | |
|     }
 | |
| 
 | |
|     if (state.mAlphaBlend)
 | |
|     {
 | |
|         sg_new = sg->find_or_insert(mShaderAlphaTestStateSet);
 | |
|         sg_new->_leaves = std::move(sg->_leaves);
 | |
|         for (RenderLeaf* leaf : sg_new->_leaves)
 | |
|             leaf->_parent = sg_new;
 | |
|         sg = sg_new;
 | |
|     }
 | |
| 
 | |
|     // GL_ALWAYS is set by default by mwshadowtechnique
 | |
|     if (state.mAlphaFunc && state.mAlphaFunc->getFunction() != GL_ALWAYS)
 | |
|     {
 | |
|         sg_new = sg->find_or_insert(mAlphaFuncShaders[state.mAlphaFunc->getFunction() - GL_NEVER]);
 | |
|         sg_new->_leaves = std::move(sg->_leaves);
 | |
|         for (RenderLeaf* leaf : sg_new->_leaves)
 | |
|             leaf->_parent = sg_new;
 | |
|         sg = sg_new;
 | |
|     }
 | |
| 
 | |
|     return sg;
 | |
| }
 | |
| 
 | |
| inline bool ShadowsBin::State::needTexture() const
 | |
| {
 | |
|     return mAlphaBlend || (mAlphaFunc && mAlphaFunc->getFunction() != GL_ALWAYS);
 | |
| }
 | |
| 
 | |
| bool ShadowsBin::State::needShadows() const
 | |
| {
 | |
|     if (mAlphaFunc && mAlphaFunc->getFunction() == GL_NEVER)
 | |
|         return false;
 | |
|     // other alpha func + material combinations might be skippable
 | |
|     if (mAlphaBlend && mMaterial)
 | |
|         return materialNeedShadows(mMaterial);
 | |
|     return true;
 | |
| }
 | |
| 
 | |
| void ShadowsBin::sortImplementation()
 | |
| {
 | |
|     // The cull visitor contains a stategraph.
 | |
|     // When a stateset is pushed, it's added/found as a child of the current stategraph node, then that node becomes the new current stategraph node.
 | |
|     // When a drawable is added, the current stategraph node is added to the current renderbin (if it's not there already) and the drawable is added as a renderleaf to the stategraph
 | |
|     // This means our list only contains stategraph nodes with directly-attached renderleaves, but they might have parents with more state set that needs to be considered.
 | |
|     if (!_stateGraphList.size())
 | |
|         return;
 | |
|     StateGraph* root = _stateGraphList[0];
 | |
|     while (root->_parent)
 | |
|     {
 | |
|         root = root->_parent;
 | |
|         const osg::StateSet* ss = root->getStateSet();
 | |
|         if (ss->getMode(GL_NORMALIZE) & osg::StateAttribute::ON // that is root stategraph of renderingmanager cpp
 | |
|            || ss->getAttribute(osg::StateAttribute::VIEWPORT)) // fallback to rendertarget's sg just in case
 | |
|             break;
 | |
|         if (!root->_parent)
 | |
|             return;
 | |
|     }
 | |
|     StateGraph* noTestRoot = root->find_or_insert(mNoTestStateSet.get());
 | |
|     // noTestRoot is now a stategraph with useDiffuseMapForShadowAlpha disabled but minimal other state
 | |
| 
 | |
|     bool cullFaceOverridden = false;
 | |
|     while (root->_parent)
 | |
|     {
 | |
|         root = root->_parent;
 | |
|         if (!root->getStateSet())
 | |
|             continue;
 | |
|         unsigned int cullFaceFlags = root->getStateSet()->getMode(GL_CULL_FACE);
 | |
|         if (cullFaceFlags & osg::StateAttribute::OVERRIDE && !(cullFaceFlags & osg::StateAttribute::ON))
 | |
|         {
 | |
|             cullFaceOverridden = true;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     noTestRoot->_leaves.reserve(_stateGraphList.size());
 | |
|     StateGraphList newList;
 | |
|     std::unordered_set<StateGraph*> uninterestingCache;
 | |
|     for (StateGraph* graph : _stateGraphList)
 | |
|     {
 | |
|         // Render leaves which shouldn't use the diffuse map for shadow alpha but do cast shadows become children of root, so graph is now empty. Don't add to newList.
 | |
|         // Graphs containing just render leaves which don't cast shadows are discarded. Don't add to newList.
 | |
|         // Graphs containing other leaves need to be in newList.
 | |
|         StateGraph* graphToAdd = cullStateGraph(graph, noTestRoot, uninterestingCache, cullFaceOverridden);
 | |
|         if (graphToAdd)
 | |
|             newList.push_back(graphToAdd);
 | |
|     }
 | |
|     if (!noTestRoot->_leaves.empty())
 | |
|         newList.push_back(noTestRoot);
 | |
|     _stateGraphList = std::move(newList);
 | |
| }
 | |
| 
 | |
| }
 |