diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2020-04-14 23:03:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-14 23:03:32 +0200 |
commit | 9db525941f92f8f84928153dd63173513fabd8eb (patch) | |
tree | 55993330051ce3e30b4e1ceb058aa6511f2beb04 /servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp | |
parent | 84142f6a5fcdf26e2a023e7b3914ac059b63df99 (diff) | |
parent | 6f293ed7958d56fb4a8033f04e5ef59e037d2ae7 (diff) |
Merge pull request #37887 from reduz/implement-projectors
Add support for projectors in spot and omni lights.
Diffstat (limited to 'servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp')
-rw-r--r-- | servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp index fe48321e59..148494692c 100644 --- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp +++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp @@ -3180,7 +3180,19 @@ void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) { Light *light = light_owner.getornull(p_light); ERR_FAIL_COND(!light); + if (light->projector == p_texture) { + return; + } + + if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) { + texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI); + } + light->projector = p_texture; + + if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) { + texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI); + } } void RasterizerStorageRD::light_set_negative(RID p_light, bool p_enable) { @@ -4381,22 +4393,30 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const { return RS::INSTANCE_NONE; } -void RasterizerStorageRD::texture_add_to_decal_atlas(RID p_texture) { +void RasterizerStorageRD::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) { if (!decal_atlas.textures.has(p_texture)) { DecalAtlas::Texture t; t.users = 1; + t.panorama_to_dp_users = p_panorama_to_dp ? 1 : 0; decal_atlas.textures[p_texture] = t; decal_atlas.dirty = true; } else { DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture); t->users++; + if (p_panorama_to_dp) { + t->panorama_to_dp_users++; + } } } -void RasterizerStorageRD::texture_remove_from_decal_atlas(RID p_texture) { +void RasterizerStorageRD::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture); ERR_FAIL_COND(!t); t->users--; + if (p_panorama_to_dp) { + ERR_FAIL_COND(t->panorama_to_dp_users == 0); + t->panorama_to_dp_users--; + } if (t->users == 0) { decal_atlas.textures.erase(p_texture); //do not mark it dirty, there is no need to since it remains working @@ -4590,7 +4610,7 @@ void RasterizerStorageRD::_update_decal_atlas() { while ((K = decal_atlas.textures.next(K))) { DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K); Texture *src_tex = texture_owner.getornull(*K); - effects.copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list); + effects.copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0); } RD::get_singleton()->draw_list_end(); @@ -4732,6 +4752,7 @@ bool RasterizerStorageRD::free(RID p_rid) { } else if (light_owner.owns(p_rid)) { + light_set_projector(p_rid, RID()); //clear projector // delete the texture Light *light = light_owner.getornull(p_rid); light->instance_dependency.instance_notify_deleted(p_rid); |