diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index ba0d367254..48e2bd70b6 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -618,12 +618,16 @@ class build_apps(setuptools.Command): rootdir = wf.split(os.path.sep, 1)[0] search_path.append(os.path.join(whl, rootdir, '.libs')) + # Also look for eg. numpy.libs or Pillow.libs in the root + whl_name = os.path.basename(whl).split('-', 1)[0] + search_path.append(os.path.join(whl, whl_name + '.libs')) + # Also look for more specific per-package cases, defined in # PACKAGE_LIB_DIRS at the top of this file. - whl_name = os.path.basename(whl).split('-', 1)[0] extra_dirs = PACKAGE_LIB_DIRS.get(whl_name, []) for extra_dir in extra_dirs: search_path.append(os.path.join(whl, extra_dir.replace('/', os.path.sep))) + return search_path def create_runtime(appname, mainscript, use_console): diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 911ef621da..f26104449a 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -1985,7 +1985,14 @@ fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler, Light *light_obj = light.node()->as_light(); nassertr(light_obj != nullptr, nullptr); - PT(Texture) tex = get_shadow_map(light); + PT(Texture) tex; + LightLensNode *lln = DCAST(LightLensNode, light.node()); + if (lln != nullptr && lln->_shadow_caster) { + tex = get_shadow_map(light); + } else { + tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type); + } + if (tex != nullptr) { sampler = tex->get_default_sampler(); } diff --git a/panda/src/pgraph/textureAttrib.cxx b/panda/src/pgraph/textureAttrib.cxx index 0184f1825c..d08344fc4d 100644 --- a/panda/src/pgraph/textureAttrib.cxx +++ b/panda/src/pgraph/textureAttrib.cxx @@ -109,12 +109,18 @@ add_on_stage(TextureStage *stage, Texture *tex, int override) const { nassertr(tex != nullptr, this); TextureAttrib *attrib = new TextureAttrib(*this); - Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first; - (*si)._override = override; - (*si)._texture = tex; - (*si)._implicit_sort = attrib->_next_implicit_sort; - (*si)._has_sampler = false; - ++(attrib->_next_implicit_sort); + auto result = attrib->_on_stages.insert(StageNode(stage)); + StageNode &sn = *result.first; + sn._override = override; + sn._texture = tex; + sn._has_sampler = false; + + // Only bump this if it doesn't already have the highest implicit sort. + // This prevents replacing a texture from creating a unique TextureAttrib. + if (result.second || sn._implicit_sort + 1 != attrib->_next_implicit_sort) { + sn._implicit_sort = attrib->_next_implicit_sort; + ++(attrib->_next_implicit_sort); + } return return_new(attrib); } @@ -128,13 +134,19 @@ add_on_stage(TextureStage *stage, Texture *tex, const SamplerState &sampler, int nassertr(tex != nullptr, this); TextureAttrib *attrib = new TextureAttrib(*this); - Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first; - (*si)._override = override; - (*si)._texture = tex; - (*si)._sampler = sampler; - (*si)._implicit_sort = attrib->_next_implicit_sort; - (*si)._has_sampler = true; - ++(attrib->_next_implicit_sort); + auto result = attrib->_on_stages.insert(StageNode(stage)); + StageNode &sn = *result.first; + sn._override = override; + sn._texture = tex; + sn._sampler = sampler; + sn._has_sampler = true; + + // Only bump this if it doesn't already have the highest implicit sort. + // This prevents replacing a texture from creating a unique TextureAttrib. + if (result.second || sn._implicit_sort + 1 != attrib->_next_implicit_sort) { + sn._implicit_sort = attrib->_next_implicit_sort; + ++(attrib->_next_implicit_sort); + } return return_new(attrib); } diff --git a/tests/pgraph/test_textureattrib.py b/tests/pgraph/test_textureattrib.py index 2be4b479f3..82ec9912f5 100644 --- a/tests/pgraph/test_textureattrib.py +++ b/tests/pgraph/test_textureattrib.py @@ -89,25 +89,6 @@ def test_textureattrib_compose_both(): assert stage3 in tattr3.on_stages -def test_textureattrib_implicit_sort(): - # Tests that two TextureStages with same sort retain insertion order. - tattr1 = core.TextureAttrib.make() - tattr1 = tattr1.add_on_stage(stage1, tex1) - tattr1 = tattr1.add_on_stage(stage2, tex2) - - assert tattr1.get_on_stage(0) == stage1 - assert tattr1.get_on_stage(1) == stage2 - - tattr2 = core.TextureAttrib.make() - tattr2 = tattr1.add_on_stage(stage2, tex2) - tattr2 = tattr1.add_on_stage(stage1, tex1) - - assert tattr2.get_on_stage(0) == stage2 - assert tattr2.get_on_stage(1) == stage1 - - assert tattr1.compare_to(tattr2) == -tattr2.compare_to(tattr1) - - def test_textureattrib_compose_alloff(): # Tests a case in which a child node disables all textures. tattr1 = core.TextureAttrib.make() @@ -124,6 +105,37 @@ def test_textureattrib_compose_alloff(): assert tattr3.has_all_off() +def test_textureattrib_implicit_sort(): + # Tests that two TextureStages with same sort retain insertion order. + tattr1 = core.TextureAttrib.make() + tattr1 = tattr1.add_on_stage(stage1, tex1) + tattr1 = tattr1.add_on_stage(stage2, tex2) + + assert tattr1.get_on_stage(0) == stage1 + assert tattr1.get_on_stage(1) == stage2 + + tattr2 = core.TextureAttrib.make() + tattr2 = tattr2.add_on_stage(stage2, tex2) + tattr2 = tattr2.add_on_stage(stage1, tex1) + + assert tattr2.get_on_stage(0) == stage2 + assert tattr2.get_on_stage(1) == stage1 + + assert tattr1.compare_to(tattr2) == -tattr2.compare_to(tattr1) + + +def test_textureattrib_replace(): + # Test that replacing a texture doesn't create a unique TextureAttrib. + tattr1 = core.TextureAttrib.make() + tattr1 = tattr1.add_on_stage(stage1, tex1) + + tattr2 = tattr1.add_on_stage(stage1, tex1) + + assert tattr1.get_num_on_stages() == 1 + assert tattr2.get_num_on_stages() == 1 + assert tattr1.compare_to(tattr2) == 0 + + def test_textureattrib_compare(): tattr1 = core.TextureAttrib.make() tattr2 = core.TextureAttrib.make()