mirror of
https://github.com/godotengine/godot.git
synced 2024-11-22 12:12:28 +00:00
Extract Decal and Decal atlas from Storage class
This commit is contained in:
parent
aa8ff21b2a
commit
0fe06e9467
@ -39,6 +39,7 @@
|
||||
#include "servers/rendering/renderer_compositor.h"
|
||||
#include "storage/canvas_texture_storage.h"
|
||||
#include "storage/config.h"
|
||||
#include "storage/decal_atlas_storage.h"
|
||||
#include "storage/render_target_storage.h"
|
||||
#include "storage/texture_storage.h"
|
||||
|
||||
@ -53,6 +54,7 @@ protected:
|
||||
GLES3::Config config;
|
||||
GLES3::CanvasTextureStorage canvas_texture_storage;
|
||||
GLES3::TextureStorage texture_storage;
|
||||
GLES3::DecalAtlasStorage decal_atlas_storage;
|
||||
RasterizerStorageGLES3 storage;
|
||||
RasterizerCanvasGLES3 canvas;
|
||||
RasterizerSceneGLES3 scene;
|
||||
@ -62,6 +64,7 @@ protected:
|
||||
public:
|
||||
RendererCanvasTextureStorage *get_canvas_texture_storage() { return &canvas_texture_storage; }
|
||||
RendererTextureStorage *get_texture_storage() { return &texture_storage; }
|
||||
RendererDecalAtlasStorage *get_decal_atlas_storage() { return &decal_atlas_storage; }
|
||||
RendererStorage *get_storage() { return &storage; }
|
||||
RendererCanvasRender *get_canvas() { return &canvas; }
|
||||
RendererSceneRender *get_scene() { return &scene; }
|
||||
|
@ -1202,46 +1202,6 @@ void RasterizerStorageGLES3::base_update_dependency(RID p_base, DependencyTracke
|
||||
void RasterizerStorageGLES3::skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) {
|
||||
}
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
RID RasterizerStorageGLES3::decal_allocate() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_initialize(RID p_rid) {
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_set_emission_energy(RID p_decal, float p_energy) {
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_set_albedo_mix(RID p_decal, float p_mix) {
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_set_modulate(RID p_decal, const Color &p_modulate) {
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_set_fade(RID p_decal, float p_above, float p_below) {
|
||||
}
|
||||
|
||||
void RasterizerStorageGLES3::decal_set_normal_fade(RID p_decal, float p_fade) {
|
||||
}
|
||||
|
||||
AABB RasterizerStorageGLES3::decal_get_aabb(RID p_decal) const {
|
||||
return AABB();
|
||||
}
|
||||
|
||||
/* VOXEL GI API */
|
||||
|
||||
RID RasterizerStorageGLES3::voxel_gi_allocate() {
|
||||
|
@ -579,25 +579,6 @@ public:
|
||||
void base_update_dependency(RID p_base, DependencyTracker *p_instance) override;
|
||||
void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override;
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
RID decal_allocate() override;
|
||||
void decal_initialize(RID p_rid) override;
|
||||
void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
|
||||
void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
|
||||
void decal_set_emission_energy(RID p_decal, float p_energy) override;
|
||||
void decal_set_albedo_mix(RID p_decal, float p_mix) override;
|
||||
void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
|
||||
void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
|
||||
void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
|
||||
void decal_set_fade(RID p_decal, float p_above, float p_below) override;
|
||||
void decal_set_normal_fade(RID p_decal, float p_fade) override;
|
||||
|
||||
AABB decal_get_aabb(RID p_decal) const override;
|
||||
|
||||
void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
|
||||
/* VOXEL GI API */
|
||||
|
||||
RID voxel_gi_allocate() override;
|
||||
|
75
drivers/gles3/storage/decal_atlas_storage.cpp
Normal file
75
drivers/gles3/storage/decal_atlas_storage.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*************************************************************************/
|
||||
/* decal_atlas_storage.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
#include "decal_atlas_storage.h"
|
||||
|
||||
using namespace GLES3;
|
||||
|
||||
RID DecalAtlasStorage::decal_allocate() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_initialize(RID p_rid) {
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
|
||||
}
|
||||
|
||||
AABB DecalAtlasStorage::decal_get_aabb(RID p_decal) const {
|
||||
return AABB();
|
||||
}
|
||||
|
||||
#endif // !GLES3_ENABLED
|
67
drivers/gles3/storage/decal_atlas_storage.h
Normal file
67
drivers/gles3/storage/decal_atlas_storage.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*************************************************************************/
|
||||
/* decal_atlas_storage.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef DECAL_ATLAS_STORAGE_GLES3_H
|
||||
#define DECAL_ATLAS_STORAGE_GLES3_H
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
#include "core/templates/rid_owner.h"
|
||||
#include "servers/rendering/storage/decal_atlas_storage.h"
|
||||
|
||||
namespace GLES3 {
|
||||
|
||||
class DecalAtlasStorage : public RendererDecalAtlasStorage {
|
||||
public:
|
||||
virtual RID decal_allocate() override;
|
||||
virtual void decal_initialize(RID p_rid) override;
|
||||
virtual void decal_free(RID p_rid) override{};
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const override;
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
};
|
||||
|
||||
} // namespace GLES3
|
||||
|
||||
#endif // !GLES3_ENABLED
|
||||
|
||||
#endif // !DECAL_ATLAS_STORAGE_GLES3_H
|
@ -38,6 +38,7 @@
|
||||
#include "servers/rendering/dummy/rasterizer_scene_dummy.h"
|
||||
#include "servers/rendering/dummy/rasterizer_storage_dummy.h"
|
||||
#include "servers/rendering/dummy/storage/canvas_texture_storage.h"
|
||||
#include "servers/rendering/dummy/storage/decal_atlas_storage.h"
|
||||
#include "servers/rendering/dummy/storage/texture_storage.h"
|
||||
#include "servers/rendering/renderer_compositor.h"
|
||||
#include "servers/rendering_server.h"
|
||||
@ -51,12 +52,14 @@ protected:
|
||||
RasterizerCanvasDummy canvas;
|
||||
RendererDummy::CanvasTextureStorage canvas_texture_storage;
|
||||
RendererDummy::TextureStorage texture_storage;
|
||||
RendererDummy::DecalAtlasStorage decal_atlas_storage;
|
||||
RasterizerStorageDummy storage;
|
||||
RasterizerSceneDummy scene;
|
||||
|
||||
public:
|
||||
RendererCanvasTextureStorage *get_canvas_texture_storage() override { return &canvas_texture_storage; };
|
||||
RendererTextureStorage *get_texture_storage() override { return &texture_storage; };
|
||||
RendererDecalAtlasStorage *get_decal_atlas_storage() override { return &decal_atlas_storage; };
|
||||
RendererStorage *get_storage() override { return &storage; }
|
||||
RendererCanvasRender *get_canvas() override { return &canvas; }
|
||||
RendererSceneRender *get_scene() override { return &scene; }
|
||||
|
@ -214,25 +214,6 @@ public:
|
||||
void base_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
|
||||
void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
RID decal_allocate() override { return RID(); }
|
||||
void decal_initialize(RID p_rid) override {}
|
||||
void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
|
||||
void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
|
||||
void decal_set_emission_energy(RID p_decal, float p_energy) override {}
|
||||
void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
|
||||
void decal_set_modulate(RID p_decal, const Color &p_modulate) override {}
|
||||
void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override {}
|
||||
void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override {}
|
||||
void decal_set_fade(RID p_decal, float p_above, float p_below) override {}
|
||||
void decal_set_normal_fade(RID p_decal, float p_fade) override {}
|
||||
|
||||
AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
|
||||
|
||||
void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
|
||||
/* VOXEL GI API */
|
||||
|
||||
RID voxel_gi_allocate() override { return RID(); }
|
||||
|
62
servers/rendering/dummy/storage/decal_atlas_storage.h
Normal file
62
servers/rendering/dummy/storage/decal_atlas_storage.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*************************************************************************/
|
||||
/* decal_atlas_storage.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef DECAL_ATLAS_STORAGE_DUMMY_H
|
||||
#define DECAL_ATLAS_STORAGE_DUMMY_H
|
||||
|
||||
#include "servers/rendering/storage/decal_atlas_storage.h"
|
||||
|
||||
namespace RendererDummy {
|
||||
|
||||
class DecalAtlasStorage : public RendererDecalAtlasStorage {
|
||||
public:
|
||||
virtual RID decal_allocate() override { return RID(); }
|
||||
virtual void decal_initialize(RID p_rid) override {}
|
||||
virtual void decal_free(RID p_rid) override{};
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override {}
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override {}
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override {}
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override {}
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override {}
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override {}
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
};
|
||||
|
||||
} // namespace RendererDummy
|
||||
|
||||
#endif // !DECAL_ATLAS_STORAGE_DUMMY_H
|
@ -35,6 +35,7 @@
|
||||
#include "servers/rendering/renderer_scene.h"
|
||||
#include "servers/rendering/renderer_storage.h"
|
||||
#include "servers/rendering/storage/canvas_texture_storage.h"
|
||||
#include "servers/rendering/storage/decal_atlas_storage.h"
|
||||
#include "servers/rendering/storage/texture_storage.h"
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
@ -74,6 +75,7 @@ public:
|
||||
|
||||
virtual RendererCanvasTextureStorage *get_canvas_texture_storage() = 0;
|
||||
virtual RendererTextureStorage *get_texture_storage() = 0;
|
||||
virtual RendererDecalAtlasStorage *get_decal_atlas_storage() = 0;
|
||||
virtual RendererStorage *get_storage() = 0;
|
||||
virtual RendererCanvasRender *get_canvas() = 0;
|
||||
virtual RendererSceneRender *get_scene() = 0;
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "render_forward_clustered.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
@ -2140,7 +2141,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
|
||||
RD::Uniform u;
|
||||
u.binding = 11;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = storage->decal_atlas_get_texture();
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
|
||||
u.append_id(decal_atlas);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
@ -2148,7 +2149,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
|
||||
RD::Uniform u;
|
||||
u.binding = 12;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = storage->decal_atlas_get_texture_srgb();
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_srgb();
|
||||
u.append_id(decal_atlas);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "render_forward_mobile.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
|
||||
@ -1275,7 +1276,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
||||
RD::Uniform u;
|
||||
u.binding = 11;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = storage->decal_atlas_get_texture();
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
|
||||
u.append_id(decal_atlas);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
@ -1283,7 +1284,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
||||
RD::Uniform u;
|
||||
u.binding = 12;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = storage->decal_atlas_get_texture_srgb();
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_srgb();
|
||||
u.append_id(decal_atlas);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "core/math/math_defs.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
#include "renderer_compositor_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
|
||||
void RendererCanvasRenderRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
|
||||
@ -947,7 +948,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.binding = 3;
|
||||
u.append_id(storage->decal_atlas_get_texture());
|
||||
u.append_id(RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
@ -1253,7 +1254,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
|
||||
}
|
||||
|
||||
if (clight->texture.is_valid()) {
|
||||
Rect2 atlas_rect = storage->decal_atlas_get_texture_rect(clight->texture);
|
||||
Rect2 atlas_rect = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_rect(clight->texture);
|
||||
state.light_uniforms[index].atlas_rect[0] = atlas_rect.position.x;
|
||||
state.light_uniforms[index].atlas_rect[1] = atlas_rect.position.y;
|
||||
state.light_uniforms[index].atlas_rect[2] = atlas_rect.size.width;
|
||||
@ -1479,18 +1480,20 @@ RID RendererCanvasRenderRD::light_create() {
|
||||
}
|
||||
|
||||
void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) {
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
|
||||
|
||||
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
|
||||
ERR_FAIL_COND(!cl);
|
||||
if (cl->texture == p_texture) {
|
||||
return;
|
||||
}
|
||||
if (cl->texture.is_valid()) {
|
||||
storage->texture_remove_from_decal_atlas(cl->texture);
|
||||
decal_atlas_storage->texture_remove_from_decal_atlas(cl->texture);
|
||||
}
|
||||
cl->texture = p_texture;
|
||||
|
||||
if (cl->texture.is_valid()) {
|
||||
storage->texture_add_to_decal_atlas(cl->texture);
|
||||
decal_atlas_storage->texture_add_to_decal_atlas(cl->texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,6 +155,7 @@ void RendererCompositorRD::finalize() {
|
||||
memdelete(scene);
|
||||
memdelete(canvas);
|
||||
memdelete(storage);
|
||||
memdelete(decal_atlas_storage);
|
||||
memdelete(texture_storage);
|
||||
memdelete(canvas_texture_storage);
|
||||
|
||||
@ -287,6 +288,7 @@ RendererCompositorRD::RendererCompositorRD() {
|
||||
|
||||
canvas_texture_storage = memnew(RendererRD::CanvasTextureStorage);
|
||||
texture_storage = memnew(RendererRD::TextureStorage);
|
||||
decal_atlas_storage = memnew(RendererRD::DecalAtlasStorage);
|
||||
storage = memnew(RendererStorageRD);
|
||||
canvas = memnew(RendererCanvasRenderRD(storage));
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
|
||||
|
||||
@ -49,6 +50,7 @@ protected:
|
||||
RendererCanvasRenderRD *canvas;
|
||||
RendererRD::CanvasTextureStorage *canvas_texture_storage;
|
||||
RendererRD::TextureStorage *texture_storage;
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage;
|
||||
RendererStorageRD *storage;
|
||||
RendererSceneRenderRD *scene;
|
||||
|
||||
@ -92,8 +94,9 @@ protected:
|
||||
static uint64_t frame;
|
||||
|
||||
public:
|
||||
RendererCanvasTextureStorage *get_canvas_texture_storage() { return canvas_texture_storage; };
|
||||
RendererTextureStorage *get_texture_storage() { return texture_storage; };
|
||||
RendererCanvasTextureStorage *get_canvas_texture_storage() { return canvas_texture_storage; }
|
||||
RendererTextureStorage *get_texture_storage() { return texture_storage; }
|
||||
RendererDecalAtlasStorage *get_decal_atlas_storage() { return decal_atlas_storage; }
|
||||
RendererStorage *get_storage() { return storage; }
|
||||
RendererCanvasRender *get_canvas() { return canvas; }
|
||||
RendererSceneRender *get_scene() { return scene; }
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "core/config/project_settings.h"
|
||||
#include "core/os/os.h"
|
||||
#include "renderer_compositor_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
|
||||
void get_vogel_disk(float *r_kernel, int p_sample_count) {
|
||||
@ -2674,7 +2675,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DECAL_ATLAS) {
|
||||
RID decal_atlas = storage->decal_atlas_get_texture();
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
|
||||
|
||||
if (decal_atlas.is_valid()) {
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
@ -3262,6 +3263,8 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows) {
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
|
||||
|
||||
Transform3D inverse_transform = p_camera_transform.affine_inverse();
|
||||
|
||||
r_directional_light_count = 0;
|
||||
@ -3545,7 +3548,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
||||
RID projector = storage->light_get_projector(base);
|
||||
|
||||
if (projector.is_valid()) {
|
||||
Rect2 rect = storage->decal_atlas_get_texture_rect(projector);
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(projector);
|
||||
|
||||
if (type == RS::LIGHT_SPOT) {
|
||||
light_data.projector_rect[0] = rect.position.x;
|
||||
@ -3661,6 +3664,8 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform) {
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
|
||||
|
||||
Transform3D uv_xform;
|
||||
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
|
||||
uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
|
||||
@ -3684,9 +3689,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
||||
|
||||
real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
|
||||
|
||||
if (storage->decal_is_distance_fade_enabled(decal)) {
|
||||
float fade_begin = storage->decal_get_distance_fade_begin(decal);
|
||||
float fade_length = storage->decal_get_distance_fade_length(decal);
|
||||
if (decal_atlas_storage->decal_is_distance_fade_enabled(decal)) {
|
||||
float fade_begin = decal_atlas_storage->decal_get_distance_fade_begin(decal);
|
||||
float fade_length = decal_atlas_storage->decal_get_distance_fade_length(decal);
|
||||
|
||||
if (distance > fade_begin) {
|
||||
if (distance > fade_begin + fade_length) {
|
||||
@ -3714,15 +3719,15 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
||||
_map_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id, i);
|
||||
}
|
||||
|
||||
di->cull_mask = storage->decal_get_cull_mask(decal);
|
||||
di->cull_mask = decal_atlas_storage->decal_get_cull_mask(decal);
|
||||
|
||||
Transform3D xform = di->transform;
|
||||
float fade = 1.0;
|
||||
|
||||
if (storage->decal_is_distance_fade_enabled(decal)) {
|
||||
if (decal_atlas_storage->decal_is_distance_fade_enabled(decal)) {
|
||||
real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
|
||||
float fade_begin = storage->decal_get_distance_fade_begin(decal);
|
||||
float fade_length = storage->decal_get_distance_fade_length(decal);
|
||||
float fade_begin = decal_atlas_storage->decal_get_distance_fade_begin(decal);
|
||||
float fade_length = decal_atlas_storage->decal_get_distance_fade_length(decal);
|
||||
|
||||
if (distance > fade_begin) {
|
||||
fade = 1.0 - (distance - fade_begin) / fade_length;
|
||||
@ -3731,7 +3736,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
||||
|
||||
Cluster::DecalData &dd = cluster.decals[i];
|
||||
|
||||
Vector3 decal_extents = storage->decal_get_extents(decal);
|
||||
Vector3 decal_extents = decal_atlas_storage->decal_get_extents(decal);
|
||||
|
||||
Transform3D scale_xform;
|
||||
scale_xform.basis.scale(decal_extents);
|
||||
@ -3744,12 +3749,12 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
||||
dd.normal[0] = normal.x;
|
||||
dd.normal[1] = normal.y;
|
||||
dd.normal[2] = normal.z;
|
||||
dd.normal_fade = storage->decal_get_normal_fade(decal);
|
||||
dd.normal_fade = decal_atlas_storage->decal_get_normal_fade(decal);
|
||||
|
||||
RID albedo_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO);
|
||||
RID emission_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION);
|
||||
RID albedo_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO);
|
||||
RID emission_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION);
|
||||
if (albedo_tex.is_valid()) {
|
||||
Rect2 rect = storage->decal_atlas_get_texture_rect(albedo_tex);
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(albedo_tex);
|
||||
dd.albedo_rect[0] = rect.position.x;
|
||||
dd.albedo_rect[1] = rect.position.y;
|
||||
dd.albedo_rect[2] = rect.size.x;
|
||||
@ -3764,10 +3769,10 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
||||
dd.albedo_rect[3] = 0;
|
||||
}
|
||||
|
||||
RID normal_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL);
|
||||
RID normal_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL);
|
||||
|
||||
if (normal_tex.is_valid()) {
|
||||
Rect2 rect = storage->decal_atlas_get_texture_rect(normal_tex);
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(normal_tex);
|
||||
dd.normal_rect[0] = rect.position.x;
|
||||
dd.normal_rect[1] = rect.position.y;
|
||||
dd.normal_rect[2] = rect.size.x;
|
||||
@ -3782,9 +3787,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
||||
dd.normal_rect[3] = 0;
|
||||
}
|
||||
|
||||
RID orm_tex = storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM);
|
||||
RID orm_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM);
|
||||
if (orm_tex.is_valid()) {
|
||||
Rect2 rect = storage->decal_atlas_get_texture_rect(orm_tex);
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(orm_tex);
|
||||
dd.orm_rect[0] = rect.position.x;
|
||||
dd.orm_rect[1] = rect.position.y;
|
||||
dd.orm_rect[2] = rect.size.x;
|
||||
@ -3797,7 +3802,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
||||
}
|
||||
|
||||
if (emission_tex.is_valid()) {
|
||||
Rect2 rect = storage->decal_atlas_get_texture_rect(emission_tex);
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(emission_tex);
|
||||
dd.emission_rect[0] = rect.position.x;
|
||||
dd.emission_rect[1] = rect.position.y;
|
||||
dd.emission_rect[2] = rect.size.x;
|
||||
@ -3809,16 +3814,16 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
||||
dd.emission_rect[3] = 0;
|
||||
}
|
||||
|
||||
Color modulate = storage->decal_get_modulate(decal);
|
||||
Color modulate = decal_atlas_storage->decal_get_modulate(decal);
|
||||
dd.modulate[0] = modulate.r;
|
||||
dd.modulate[1] = modulate.g;
|
||||
dd.modulate[2] = modulate.b;
|
||||
dd.modulate[3] = modulate.a * fade;
|
||||
dd.emission_energy = storage->decal_get_emission_energy(decal) * fade;
|
||||
dd.albedo_mix = storage->decal_get_albedo_mix(decal);
|
||||
dd.mask = storage->decal_get_cull_mask(decal);
|
||||
dd.upper_fade = storage->decal_get_upper_fade(decal);
|
||||
dd.lower_fade = storage->decal_get_lower_fade(decal);
|
||||
dd.emission_energy = decal_atlas_storage->decal_get_emission_energy(decal) * fade;
|
||||
dd.albedo_mix = decal_atlas_storage->decal_get_albedo_mix(decal);
|
||||
dd.mask = decal_atlas_storage->decal_get_cull_mask(decal);
|
||||
dd.upper_fade = decal_atlas_storage->decal_get_upper_fade(decal);
|
||||
dd.lower_fade = decal_atlas_storage->decal_get_lower_fade(decal);
|
||||
|
||||
if (current_cluster_builder != nullptr) {
|
||||
current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_DECAL, xform, decal_extents);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "core/math/math_defs.h"
|
||||
#include "renderer_compositor_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/rendering_server_globals.h"
|
||||
#include "servers/rendering/shader_language.h"
|
||||
@ -5315,6 +5316,7 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
|
||||
}
|
||||
|
||||
void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
|
||||
Light *light = light_owner.get_or_null(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
@ -5323,14 +5325,14 @@ void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
|
||||
}
|
||||
|
||||
if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
|
||||
texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
|
||||
decal_atlas_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
|
||||
}
|
||||
|
||||
light->projector = p_texture;
|
||||
|
||||
if (light->type != RS::LIGHT_DIRECTIONAL) {
|
||||
if (light->projector.is_valid()) {
|
||||
texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
|
||||
decal_atlas_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
|
||||
}
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
|
||||
}
|
||||
@ -5727,97 +5729,6 @@ float RendererStorageRD::reflection_probe_get_ambient_color_energy(RID p_probe)
|
||||
return reflection_probe->ambient_color_energy;
|
||||
}
|
||||
|
||||
RID RendererStorageRD::decal_allocate() {
|
||||
return decal_owner.allocate_rid();
|
||||
}
|
||||
void RendererStorageRD::decal_initialize(RID p_decal) {
|
||||
decal_owner.initialize_rid(p_decal, Decal());
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->extents = p_extents;
|
||||
decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
|
||||
|
||||
if (decal->textures[p_type] == p_texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(p_texture.is_valid() && !RendererRD::TextureStorage::get_singleton()->owns_texture(p_texture));
|
||||
|
||||
if (decal->textures[p_type].is_valid() && RendererRD::TextureStorage::get_singleton()->owns_texture(decal->textures[p_type])) {
|
||||
texture_remove_from_decal_atlas(decal->textures[p_type]);
|
||||
}
|
||||
|
||||
decal->textures[p_type] = p_texture;
|
||||
|
||||
if (decal->textures[p_type].is_valid()) {
|
||||
texture_add_to_decal_atlas(decal->textures[p_type]);
|
||||
}
|
||||
|
||||
decal->dependency.changed_notify(DEPENDENCY_CHANGED_DECAL);
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->emission_energy = p_energy;
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_albedo_mix(RID p_decal, float p_mix) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->albedo_mix = p_mix;
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulate) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->modulate = p_modulate;
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->cull_mask = p_layers;
|
||||
decal->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->distance_fade = p_enabled;
|
||||
decal->distance_fade_begin = p_begin;
|
||||
decal->distance_fade_length = p_length;
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->upper_fade = p_above;
|
||||
decal->lower_fade = p_below;
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->normal_fade = p_fade;
|
||||
}
|
||||
|
||||
AABB RendererStorageRD::decal_get_aabb(RID p_decal) const {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND_V(!decal, AABB());
|
||||
|
||||
return AABB(-decal->extents, decal->extents * 2.0);
|
||||
}
|
||||
|
||||
RID RendererStorageRD::voxel_gi_allocate() {
|
||||
return voxel_gi_owner.allocate_rid();
|
||||
}
|
||||
@ -7030,8 +6941,8 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_
|
||||
} else if (reflection_probe_owner.owns(p_base)) {
|
||||
ReflectionProbe *rp = reflection_probe_owner.get_or_null(p_base);
|
||||
p_instance->update_dependency(&rp->dependency);
|
||||
} else if (decal_owner.owns(p_base)) {
|
||||
Decal *decal = decal_owner.get_or_null(p_base);
|
||||
} else if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_base)) {
|
||||
RendererRD::Decal *decal = RendererRD::DecalAtlasStorage::get_singleton()->get_decal(p_base);
|
||||
p_instance->update_dependency(&decal->dependency);
|
||||
} else if (voxel_gi_owner.owns(p_base)) {
|
||||
VoxelGI *gip = voxel_gi_owner.get_or_null(p_base);
|
||||
@ -7074,7 +6985,7 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
|
||||
if (reflection_probe_owner.owns(p_rid)) {
|
||||
return RS::INSTANCE_REFLECTION_PROBE;
|
||||
}
|
||||
if (decal_owner.owns(p_rid)) {
|
||||
if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_rid)) {
|
||||
return RS::INSTANCE_DECAL;
|
||||
}
|
||||
if (voxel_gi_owner.owns(p_rid)) {
|
||||
@ -7102,252 +7013,6 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
|
||||
return RS::INSTANCE_NONE;
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_atlas_remove_texture(RID p_texture) {
|
||||
if (decal_atlas.textures.has(p_texture)) {
|
||||
decal_atlas.textures.erase(p_texture);
|
||||
//there is not much a point of making it dirty, just let it be.
|
||||
}
|
||||
}
|
||||
|
||||
void RendererStorageRD::decal_atlas_mark_dirty_on_texture(RID p_texture) {
|
||||
if (decal_atlas.textures.has(p_texture)) {
|
||||
//belongs to decal atlas..
|
||||
|
||||
decal_atlas.dirty = true; //mark it dirty since it was most likely modified
|
||||
}
|
||||
}
|
||||
|
||||
void RendererStorageRD::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 RendererStorageRD::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
|
||||
}
|
||||
}
|
||||
|
||||
RID RendererStorageRD::decal_atlas_get_texture() const {
|
||||
return decal_atlas.texture;
|
||||
}
|
||||
|
||||
RID RendererStorageRD::decal_atlas_get_texture_srgb() const {
|
||||
return decal_atlas.texture_srgb;
|
||||
}
|
||||
|
||||
void RendererStorageRD::_update_decal_atlas() {
|
||||
if (!decal_atlas.dirty) {
|
||||
return; //nothing to do
|
||||
}
|
||||
|
||||
decal_atlas.dirty = false;
|
||||
|
||||
if (decal_atlas.texture.is_valid()) {
|
||||
RD::get_singleton()->free(decal_atlas.texture);
|
||||
decal_atlas.texture = RID();
|
||||
decal_atlas.texture_srgb = RID();
|
||||
decal_atlas.texture_mipmaps.clear();
|
||||
}
|
||||
|
||||
int border = 1 << decal_atlas.mipmaps;
|
||||
|
||||
if (decal_atlas.textures.size()) {
|
||||
//generate atlas
|
||||
Vector<DecalAtlas::SortItem> itemsv;
|
||||
itemsv.resize(decal_atlas.textures.size());
|
||||
int base_size = 8;
|
||||
const RID *K = nullptr;
|
||||
|
||||
int idx = 0;
|
||||
while ((K = decal_atlas.textures.next(K))) {
|
||||
DecalAtlas::SortItem &si = itemsv.write[idx];
|
||||
|
||||
RendererRD::Texture *src_tex = RendererRD::TextureStorage::get_singleton()->get_texture(*K);
|
||||
|
||||
si.size.width = (src_tex->width / border) + 1;
|
||||
si.size.height = (src_tex->height / border) + 1;
|
||||
si.pixel_size = Size2i(src_tex->width, src_tex->height);
|
||||
|
||||
if (base_size < si.size.width) {
|
||||
base_size = nearest_power_of_2_templated(si.size.width);
|
||||
}
|
||||
|
||||
si.texture = *K;
|
||||
idx++;
|
||||
}
|
||||
|
||||
//sort items by size
|
||||
itemsv.sort();
|
||||
|
||||
//attempt to create atlas
|
||||
int item_count = itemsv.size();
|
||||
DecalAtlas::SortItem *items = itemsv.ptrw();
|
||||
|
||||
int atlas_height = 0;
|
||||
|
||||
while (true) {
|
||||
Vector<int> v_offsetsv;
|
||||
v_offsetsv.resize(base_size);
|
||||
|
||||
int *v_offsets = v_offsetsv.ptrw();
|
||||
memset(v_offsets, 0, sizeof(int) * base_size);
|
||||
|
||||
int max_height = 0;
|
||||
|
||||
for (int i = 0; i < item_count; i++) {
|
||||
//best fit
|
||||
DecalAtlas::SortItem &si = items[i];
|
||||
int best_idx = -1;
|
||||
int best_height = 0x7FFFFFFF;
|
||||
for (int j = 0; j <= base_size - si.size.width; j++) {
|
||||
int height = 0;
|
||||
for (int k = 0; k < si.size.width; k++) {
|
||||
int h = v_offsets[k + j];
|
||||
if (h > height) {
|
||||
height = h;
|
||||
if (height > best_height) {
|
||||
break; //already bad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (height < best_height) {
|
||||
best_height = height;
|
||||
best_idx = j;
|
||||
}
|
||||
}
|
||||
|
||||
//update
|
||||
for (int k = 0; k < si.size.width; k++) {
|
||||
v_offsets[k + best_idx] = best_height + si.size.height;
|
||||
}
|
||||
|
||||
si.pos.x = best_idx;
|
||||
si.pos.y = best_height;
|
||||
|
||||
if (si.pos.y + si.size.height > max_height) {
|
||||
max_height = si.pos.y + si.size.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_height <= base_size * 2) {
|
||||
atlas_height = max_height;
|
||||
break; //good ratio, break;
|
||||
}
|
||||
|
||||
base_size *= 2;
|
||||
}
|
||||
|
||||
decal_atlas.size.width = base_size * border;
|
||||
decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
|
||||
|
||||
for (int i = 0; i < item_count; i++) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
|
||||
t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
|
||||
t->uv_rect.size = items[i].pixel_size;
|
||||
|
||||
t->uv_rect.position /= Size2(decal_atlas.size);
|
||||
t->uv_rect.size /= Size2(decal_atlas.size);
|
||||
}
|
||||
} else {
|
||||
//use border as size, so it at least has enough mipmaps
|
||||
decal_atlas.size.width = border;
|
||||
decal_atlas.size.height = border;
|
||||
}
|
||||
|
||||
//blit textures
|
||||
|
||||
RD::TextureFormat tformat;
|
||||
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
tformat.width = decal_atlas.size.width;
|
||||
tformat.height = decal_atlas.size.height;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
|
||||
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
tformat.mipmaps = decal_atlas.mipmaps;
|
||||
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
|
||||
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
|
||||
|
||||
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
|
||||
RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1);
|
||||
|
||||
{
|
||||
//create the framebuffer
|
||||
|
||||
Size2i s = decal_atlas.size;
|
||||
|
||||
for (int i = 0; i < decal_atlas.mipmaps; i++) {
|
||||
DecalAtlas::MipMap mm;
|
||||
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i);
|
||||
Vector<RID> fb;
|
||||
fb.push_back(mm.texture);
|
||||
mm.fb = RD::get_singleton()->framebuffer_create(fb);
|
||||
mm.size = s;
|
||||
decal_atlas.texture_mipmaps.push_back(mm);
|
||||
|
||||
s.width = MAX(1, s.width >> 1);
|
||||
s.height = MAX(1, s.height >> 1);
|
||||
}
|
||||
{
|
||||
//create the SRGB variant
|
||||
RD::TextureView rd_view;
|
||||
rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB;
|
||||
decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture);
|
||||
}
|
||||
}
|
||||
|
||||
RID prev_texture;
|
||||
for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
|
||||
const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];
|
||||
|
||||
Color clear_color(0, 0, 0, 0);
|
||||
|
||||
if (decal_atlas.textures.size()) {
|
||||
if (i == 0) {
|
||||
Vector<Color> cc;
|
||||
cc.push_back(clear_color);
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
|
||||
|
||||
const RID *K = nullptr;
|
||||
while ((K = decal_atlas.textures.next(K))) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K);
|
||||
RendererRD::Texture *src_tex = RendererRD::TextureStorage::get_singleton()->get_texture(*K);
|
||||
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();
|
||||
|
||||
prev_texture = mm.texture;
|
||||
} else {
|
||||
effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
|
||||
prev_texture = mm.texture;
|
||||
}
|
||||
} else {
|
||||
RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t RendererStorageRD::_global_variable_allocate(uint32_t p_elements) {
|
||||
int32_t idx = 0;
|
||||
while (idx + p_elements <= global_variables.buffer_size) {
|
||||
@ -8017,7 +7682,7 @@ void RendererStorageRD::update_dirty_resources() {
|
||||
_update_queued_materials();
|
||||
_update_dirty_multimeshes();
|
||||
_update_dirty_skeletons();
|
||||
_update_decal_atlas();
|
||||
RendererRD::DecalAtlasStorage::get_singleton()->update_decal_atlas();
|
||||
}
|
||||
|
||||
bool RendererStorageRD::has_os_feature(const String &p_feature) const {
|
||||
@ -8103,15 +7768,8 @@ bool RendererStorageRD::free(RID p_rid) {
|
||||
ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
|
||||
reflection_probe->dependency.deleted_notify(p_rid);
|
||||
reflection_probe_owner.free(p_rid);
|
||||
} else if (decal_owner.owns(p_rid)) {
|
||||
Decal *decal = decal_owner.get_or_null(p_rid);
|
||||
for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) {
|
||||
if (decal->textures[i].is_valid() && RendererRD::TextureStorage::get_singleton()->owns_texture(decal->textures[i])) {
|
||||
texture_remove_from_decal_atlas(decal->textures[i]);
|
||||
}
|
||||
}
|
||||
decal->dependency.deleted_notify(p_rid);
|
||||
decal_owner.free(p_rid);
|
||||
} else if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_rid)) {
|
||||
RendererRD::DecalAtlasStorage::get_singleton()->decal_free(p_rid);
|
||||
} else if (voxel_gi_owner.owns(p_rid)) {
|
||||
voxel_gi_allocate_data(p_rid, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
|
||||
VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_rid);
|
||||
@ -8259,33 +7917,6 @@ RendererStorageRD::RendererStorageRD() {
|
||||
memset(global_variables.buffer_dirty_regions, 0, sizeof(bool) * global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE);
|
||||
global_variables.buffer = RD::get_singleton()->storage_buffer_create(sizeof(GlobalVariables::Value) * global_variables.buffer_size);
|
||||
|
||||
{ // default atlas texture
|
||||
RD::TextureFormat tformat;
|
||||
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
tformat.width = 4;
|
||||
tformat.height = 4;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
|
||||
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
|
||||
Vector<uint8_t> pv;
|
||||
pv.resize(16 * 4);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
pv.set(i * 4 + 0, 0);
|
||||
pv.set(i * 4 + 1, 0);
|
||||
pv.set(i * 4 + 2, 0);
|
||||
pv.set(i * 4 + 3, 255);
|
||||
}
|
||||
|
||||
{
|
||||
//take the chance and initialize decal atlas to something
|
||||
Vector<Vector<uint8_t>> vpv;
|
||||
vpv.push_back(pv);
|
||||
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
|
||||
decal_atlas.texture_srgb = decal_atlas.texture;
|
||||
}
|
||||
}
|
||||
|
||||
//default samplers
|
||||
for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
|
||||
for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
|
||||
@ -8737,14 +8368,6 @@ RendererStorageRD::~RendererStorageRD() {
|
||||
|
||||
RD::get_singleton()->free(default_rd_storage_buffer);
|
||||
|
||||
if (decal_atlas.textures.size()) {
|
||||
ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
|
||||
}
|
||||
|
||||
if (decal_atlas.texture.is_valid()) {
|
||||
RD::get_singleton()->free(decal_atlas.texture);
|
||||
}
|
||||
|
||||
if (effects) {
|
||||
memdelete(effects);
|
||||
effects = nullptr;
|
||||
|
@ -205,50 +205,6 @@ private:
|
||||
RID custom_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
|
||||
RID default_rd_storage_buffer;
|
||||
|
||||
/* DECAL ATLAS */
|
||||
|
||||
struct DecalAtlas {
|
||||
struct Texture {
|
||||
int panorama_to_dp_users;
|
||||
int users;
|
||||
Rect2 uv_rect;
|
||||
};
|
||||
|
||||
struct SortItem {
|
||||
RID texture;
|
||||
Size2i pixel_size;
|
||||
Size2i size;
|
||||
Point2i pos;
|
||||
|
||||
bool operator<(const SortItem &p_item) const {
|
||||
//sort larger to smaller
|
||||
if (size.height == p_item.size.height) {
|
||||
return size.width > p_item.size.width;
|
||||
} else {
|
||||
return size.height > p_item.size.height;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
HashMap<RID, Texture> textures;
|
||||
bool dirty = true;
|
||||
int mipmaps = 5;
|
||||
|
||||
RID texture;
|
||||
RID texture_srgb;
|
||||
struct MipMap {
|
||||
RID fb;
|
||||
RID texture;
|
||||
Size2i size;
|
||||
};
|
||||
Vector<MipMap> texture_mipmaps;
|
||||
|
||||
Size2i size;
|
||||
|
||||
} decal_atlas;
|
||||
|
||||
void _update_decal_atlas();
|
||||
|
||||
/* SHADER */
|
||||
|
||||
struct Material;
|
||||
@ -952,27 +908,6 @@ private:
|
||||
|
||||
mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner;
|
||||
|
||||
/* DECAL */
|
||||
|
||||
struct Decal {
|
||||
Vector3 extents = Vector3(1, 1, 1);
|
||||
RID textures[RS::DECAL_TEXTURE_MAX];
|
||||
float emission_energy = 1.0;
|
||||
float albedo_mix = 1.0;
|
||||
Color modulate = Color(1, 1, 1, 1);
|
||||
uint32_t cull_mask = (1 << 20) - 1;
|
||||
float upper_fade = 0.3;
|
||||
float lower_fade = 0.3;
|
||||
bool distance_fade = false;
|
||||
float distance_fade_begin = 10;
|
||||
float distance_fade_length = 1;
|
||||
float normal_fade = 0.0;
|
||||
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<Decal, true> decal_owner;
|
||||
|
||||
/* VOXEL GI */
|
||||
|
||||
struct VoxelGI {
|
||||
@ -1190,17 +1125,6 @@ private:
|
||||
EffectsRD *effects = nullptr;
|
||||
|
||||
public:
|
||||
RID decal_atlas_get_texture() const;
|
||||
RID decal_atlas_get_texture_srgb() const;
|
||||
_FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
|
||||
if (!t) {
|
||||
return Rect2();
|
||||
}
|
||||
|
||||
return t->uv_rect;
|
||||
}
|
||||
|
||||
//internal usage
|
||||
|
||||
_FORCE_INLINE_ RID sampler_rd_get_default(RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat) {
|
||||
@ -1791,89 +1715,6 @@ public:
|
||||
void base_update_dependency(RID p_base, DependencyTracker *p_instance);
|
||||
void skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance);
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
RID decal_allocate();
|
||||
void decal_initialize(RID p_decal);
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents);
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture);
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy);
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix);
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate);
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers);
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length);
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below);
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade);
|
||||
|
||||
void decal_atlas_mark_dirty_on_texture(RID p_texture);
|
||||
void decal_atlas_remove_texture(RID p_texture);
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false);
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false);
|
||||
|
||||
_FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->extents;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->textures[p_texture];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color decal_get_modulate(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->modulate;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->emission_energy;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->albedo_mix;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->cull_mask;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->upper_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->lower_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->normal_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade_begin;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade_length;
|
||||
}
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const;
|
||||
|
||||
/* VOXEL GI API */
|
||||
|
||||
RID voxel_gi_allocate();
|
||||
|
437
servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.cpp
Normal file
437
servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.cpp
Normal file
@ -0,0 +1,437 @@
|
||||
/*************************************************************************/
|
||||
/* decal_atlas_storage.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "decal_atlas_storage.h"
|
||||
#include "texture_storage.h"
|
||||
|
||||
// Should be able to remove this once we move effects into their own file and include the correct effects
|
||||
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
|
||||
|
||||
using namespace RendererRD;
|
||||
|
||||
DecalAtlasStorage *DecalAtlasStorage::singleton = nullptr;
|
||||
|
||||
DecalAtlasStorage *DecalAtlasStorage::get_singleton() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
DecalAtlasStorage::DecalAtlasStorage() {
|
||||
singleton = this;
|
||||
|
||||
{ // default atlas texture
|
||||
RD::TextureFormat tformat;
|
||||
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
tformat.width = 4;
|
||||
tformat.height = 4;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
|
||||
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
|
||||
Vector<uint8_t> pv;
|
||||
pv.resize(16 * 4);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
pv.set(i * 4 + 0, 0);
|
||||
pv.set(i * 4 + 1, 0);
|
||||
pv.set(i * 4 + 2, 0);
|
||||
pv.set(i * 4 + 3, 255);
|
||||
}
|
||||
|
||||
{
|
||||
//take the chance and initialize decal atlas to something
|
||||
Vector<Vector<uint8_t>> vpv;
|
||||
vpv.push_back(pv);
|
||||
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
|
||||
decal_atlas.texture_srgb = decal_atlas.texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecalAtlasStorage::~DecalAtlasStorage() {
|
||||
if (decal_atlas.textures.size()) {
|
||||
ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
|
||||
}
|
||||
|
||||
if (decal_atlas.texture.is_valid()) {
|
||||
RD::get_singleton()->free(decal_atlas.texture);
|
||||
}
|
||||
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
RID DecalAtlasStorage::decal_atlas_get_texture() const {
|
||||
return decal_atlas.texture;
|
||||
}
|
||||
|
||||
RID DecalAtlasStorage::decal_atlas_get_texture_srgb() const {
|
||||
return decal_atlas.texture_srgb;
|
||||
}
|
||||
|
||||
RID DecalAtlasStorage::decal_allocate() {
|
||||
return decal_owner.allocate_rid();
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_initialize(RID p_decal) {
|
||||
decal_owner.initialize_rid(p_decal, Decal());
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_free(RID p_rid) {
|
||||
Decal *decal = decal_owner.get_or_null(p_rid);
|
||||
for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) {
|
||||
if (decal->textures[i].is_valid() && TextureStorage::get_singleton()->owns_texture(decal->textures[i])) {
|
||||
texture_remove_from_decal_atlas(decal->textures[i]);
|
||||
}
|
||||
}
|
||||
decal->dependency.deleted_notify(p_rid);
|
||||
decal_owner.free(p_rid);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->extents = p_extents;
|
||||
decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
|
||||
|
||||
if (decal->textures[p_type] == p_texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(p_texture.is_valid() && !TextureStorage::get_singleton()->owns_texture(p_texture));
|
||||
|
||||
if (decal->textures[p_type].is_valid() && TextureStorage::get_singleton()->owns_texture(decal->textures[p_type])) {
|
||||
texture_remove_from_decal_atlas(decal->textures[p_type]);
|
||||
}
|
||||
|
||||
decal->textures[p_type] = p_texture;
|
||||
|
||||
if (decal->textures[p_type].is_valid()) {
|
||||
texture_add_to_decal_atlas(decal->textures[p_type]);
|
||||
}
|
||||
|
||||
decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_DECAL);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->emission_energy = p_energy;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->albedo_mix = p_mix;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->modulate = p_modulate;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->cull_mask = p_layers;
|
||||
decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->distance_fade = p_enabled;
|
||||
decal->distance_fade_begin = p_begin;
|
||||
decal->distance_fade_length = p_length;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->upper_fade = p_above;
|
||||
decal->lower_fade = p_below;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->normal_fade = p_fade;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_atlas_mark_dirty_on_texture(RID p_texture) {
|
||||
if (decal_atlas.textures.has(p_texture)) {
|
||||
//belongs to decal atlas..
|
||||
|
||||
decal_atlas.dirty = true; //mark it dirty since it was most likely modified
|
||||
}
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_atlas_remove_texture(RID p_texture) {
|
||||
if (decal_atlas.textures.has(p_texture)) {
|
||||
decal_atlas.textures.erase(p_texture);
|
||||
//there is not much a point of making it dirty, just let it be.
|
||||
}
|
||||
}
|
||||
|
||||
AABB DecalAtlasStorage::decal_get_aabb(RID p_decal) const {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND_V(!decal, AABB());
|
||||
|
||||
return AABB(-decal->extents, decal->extents * 2.0);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::update_decal_atlas() {
|
||||
EffectsRD *effects = RendererStorageRD::base_singleton->get_effects();
|
||||
|
||||
if (!decal_atlas.dirty) {
|
||||
return; //nothing to do
|
||||
}
|
||||
|
||||
decal_atlas.dirty = false;
|
||||
|
||||
if (decal_atlas.texture.is_valid()) {
|
||||
RD::get_singleton()->free(decal_atlas.texture);
|
||||
decal_atlas.texture = RID();
|
||||
decal_atlas.texture_srgb = RID();
|
||||
decal_atlas.texture_mipmaps.clear();
|
||||
}
|
||||
|
||||
int border = 1 << decal_atlas.mipmaps;
|
||||
|
||||
if (decal_atlas.textures.size()) {
|
||||
//generate atlas
|
||||
Vector<DecalAtlas::SortItem> itemsv;
|
||||
itemsv.resize(decal_atlas.textures.size());
|
||||
int base_size = 8;
|
||||
const RID *K = nullptr;
|
||||
|
||||
int idx = 0;
|
||||
while ((K = decal_atlas.textures.next(K))) {
|
||||
DecalAtlas::SortItem &si = itemsv.write[idx];
|
||||
|
||||
Texture *src_tex = TextureStorage::get_singleton()->get_texture(*K);
|
||||
|
||||
si.size.width = (src_tex->width / border) + 1;
|
||||
si.size.height = (src_tex->height / border) + 1;
|
||||
si.pixel_size = Size2i(src_tex->width, src_tex->height);
|
||||
|
||||
if (base_size < si.size.width) {
|
||||
base_size = nearest_power_of_2_templated(si.size.width);
|
||||
}
|
||||
|
||||
si.texture = *K;
|
||||
idx++;
|
||||
}
|
||||
|
||||
//sort items by size
|
||||
itemsv.sort();
|
||||
|
||||
//attempt to create atlas
|
||||
int item_count = itemsv.size();
|
||||
DecalAtlas::SortItem *items = itemsv.ptrw();
|
||||
|
||||
int atlas_height = 0;
|
||||
|
||||
while (true) {
|
||||
Vector<int> v_offsetsv;
|
||||
v_offsetsv.resize(base_size);
|
||||
|
||||
int *v_offsets = v_offsetsv.ptrw();
|
||||
memset(v_offsets, 0, sizeof(int) * base_size);
|
||||
|
||||
int max_height = 0;
|
||||
|
||||
for (int i = 0; i < item_count; i++) {
|
||||
//best fit
|
||||
DecalAtlas::SortItem &si = items[i];
|
||||
int best_idx = -1;
|
||||
int best_height = 0x7FFFFFFF;
|
||||
for (int j = 0; j <= base_size - si.size.width; j++) {
|
||||
int height = 0;
|
||||
for (int k = 0; k < si.size.width; k++) {
|
||||
int h = v_offsets[k + j];
|
||||
if (h > height) {
|
||||
height = h;
|
||||
if (height > best_height) {
|
||||
break; //already bad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (height < best_height) {
|
||||
best_height = height;
|
||||
best_idx = j;
|
||||
}
|
||||
}
|
||||
|
||||
//update
|
||||
for (int k = 0; k < si.size.width; k++) {
|
||||
v_offsets[k + best_idx] = best_height + si.size.height;
|
||||
}
|
||||
|
||||
si.pos.x = best_idx;
|
||||
si.pos.y = best_height;
|
||||
|
||||
if (si.pos.y + si.size.height > max_height) {
|
||||
max_height = si.pos.y + si.size.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_height <= base_size * 2) {
|
||||
atlas_height = max_height;
|
||||
break; //good ratio, break;
|
||||
}
|
||||
|
||||
base_size *= 2;
|
||||
}
|
||||
|
||||
decal_atlas.size.width = base_size * border;
|
||||
decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
|
||||
|
||||
for (int i = 0; i < item_count; i++) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
|
||||
t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
|
||||
t->uv_rect.size = items[i].pixel_size;
|
||||
|
||||
t->uv_rect.position /= Size2(decal_atlas.size);
|
||||
t->uv_rect.size /= Size2(decal_atlas.size);
|
||||
}
|
||||
} else {
|
||||
//use border as size, so it at least has enough mipmaps
|
||||
decal_atlas.size.width = border;
|
||||
decal_atlas.size.height = border;
|
||||
}
|
||||
|
||||
//blit textures
|
||||
|
||||
RD::TextureFormat tformat;
|
||||
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
tformat.width = decal_atlas.size.width;
|
||||
tformat.height = decal_atlas.size.height;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
|
||||
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
tformat.mipmaps = decal_atlas.mipmaps;
|
||||
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
|
||||
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
|
||||
|
||||
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
|
||||
RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1);
|
||||
|
||||
{
|
||||
//create the framebuffer
|
||||
|
||||
Size2i s = decal_atlas.size;
|
||||
|
||||
for (int i = 0; i < decal_atlas.mipmaps; i++) {
|
||||
DecalAtlas::MipMap mm;
|
||||
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i);
|
||||
Vector<RID> fb;
|
||||
fb.push_back(mm.texture);
|
||||
mm.fb = RD::get_singleton()->framebuffer_create(fb);
|
||||
mm.size = s;
|
||||
decal_atlas.texture_mipmaps.push_back(mm);
|
||||
|
||||
s.width = MAX(1, s.width >> 1);
|
||||
s.height = MAX(1, s.height >> 1);
|
||||
}
|
||||
{
|
||||
//create the SRGB variant
|
||||
RD::TextureView rd_view;
|
||||
rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB;
|
||||
decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture);
|
||||
}
|
||||
}
|
||||
|
||||
RID prev_texture;
|
||||
for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
|
||||
const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];
|
||||
|
||||
Color clear_color(0, 0, 0, 0);
|
||||
|
||||
if (decal_atlas.textures.size()) {
|
||||
if (i == 0) {
|
||||
Vector<Color> cc;
|
||||
cc.push_back(clear_color);
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
|
||||
|
||||
const RID *K = nullptr;
|
||||
while ((K = decal_atlas.textures.next(K))) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K);
|
||||
Texture *src_tex = TextureStorage::get_singleton()->get_texture(*K);
|
||||
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();
|
||||
|
||||
prev_texture = mm.texture;
|
||||
} else {
|
||||
effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
|
||||
prev_texture = mm.texture;
|
||||
}
|
||||
} else {
|
||||
RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::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 DecalAtlasStorage::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
|
||||
}
|
||||
}
|
211
servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h
Normal file
211
servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h
Normal file
@ -0,0 +1,211 @@
|
||||
/*************************************************************************/
|
||||
/* decal_atlas_storage.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef DECAL_ATLAS_STORAGE_RD_H
|
||||
#define DECAL_ATLAS_STORAGE_RD_H
|
||||
|
||||
#include "core/templates/rid_owner.h"
|
||||
#include "servers/rendering/renderer_storage.h"
|
||||
#include "servers/rendering/storage/decal_atlas_storage.h"
|
||||
|
||||
namespace RendererRD {
|
||||
|
||||
struct DecalAtlas {
|
||||
struct Texture {
|
||||
int panorama_to_dp_users;
|
||||
int users;
|
||||
Rect2 uv_rect;
|
||||
};
|
||||
|
||||
struct SortItem {
|
||||
RID texture;
|
||||
Size2i pixel_size;
|
||||
Size2i size;
|
||||
Point2i pos;
|
||||
|
||||
bool operator<(const SortItem &p_item) const {
|
||||
//sort larger to smaller
|
||||
if (size.height == p_item.size.height) {
|
||||
return size.width > p_item.size.width;
|
||||
} else {
|
||||
return size.height > p_item.size.height;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
HashMap<RID, Texture> textures;
|
||||
bool dirty = true;
|
||||
int mipmaps = 5;
|
||||
|
||||
RID texture;
|
||||
RID texture_srgb;
|
||||
struct MipMap {
|
||||
RID fb;
|
||||
RID texture;
|
||||
Size2i size;
|
||||
};
|
||||
Vector<MipMap> texture_mipmaps;
|
||||
|
||||
Size2i size;
|
||||
};
|
||||
|
||||
struct Decal {
|
||||
Vector3 extents = Vector3(1, 1, 1);
|
||||
RID textures[RS::DECAL_TEXTURE_MAX];
|
||||
float emission_energy = 1.0;
|
||||
float albedo_mix = 1.0;
|
||||
Color modulate = Color(1, 1, 1, 1);
|
||||
uint32_t cull_mask = (1 << 20) - 1;
|
||||
float upper_fade = 0.3;
|
||||
float lower_fade = 0.3;
|
||||
bool distance_fade = false;
|
||||
float distance_fade_begin = 10;
|
||||
float distance_fade_length = 1;
|
||||
float normal_fade = 0.0;
|
||||
|
||||
RendererStorage::Dependency dependency;
|
||||
};
|
||||
|
||||
class DecalAtlasStorage : public RendererDecalAtlasStorage {
|
||||
private:
|
||||
static DecalAtlasStorage *singleton;
|
||||
|
||||
DecalAtlas decal_atlas;
|
||||
|
||||
mutable RID_Owner<Decal, true> decal_owner;
|
||||
|
||||
public:
|
||||
static DecalAtlasStorage *get_singleton();
|
||||
|
||||
void update_decal_atlas();
|
||||
|
||||
DecalAtlasStorage();
|
||||
virtual ~DecalAtlasStorage();
|
||||
|
||||
Decal *get_decal(RID p_rid) { return decal_owner.get_or_null(p_rid); };
|
||||
bool owns_decal(RID p_rid) { return decal_owner.owns(p_rid); };
|
||||
|
||||
RID decal_atlas_get_texture() const;
|
||||
RID decal_atlas_get_texture_srgb() const;
|
||||
_FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
|
||||
if (!t) {
|
||||
return Rect2();
|
||||
}
|
||||
|
||||
return t->uv_rect;
|
||||
}
|
||||
|
||||
virtual RID decal_allocate() override;
|
||||
virtual void decal_initialize(RID p_decal) override;
|
||||
virtual void decal_free(RID p_rid) override;
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
|
||||
|
||||
void decal_atlas_mark_dirty_on_texture(RID p_texture);
|
||||
void decal_atlas_remove_texture(RID p_texture);
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
|
||||
|
||||
_FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->extents;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->textures[p_texture];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color decal_get_modulate(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->modulate;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->emission_energy;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->albedo_mix;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->cull_mask;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->upper_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->lower_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->normal_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade_begin;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade_length;
|
||||
}
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const override;
|
||||
};
|
||||
|
||||
} // namespace RendererRD
|
||||
|
||||
#endif // !DECAL_ATLAS_STORAGE_RD_H
|
@ -29,9 +29,7 @@
|
||||
/*************************************************************************/
|
||||
|
||||
#include "texture_storage.h"
|
||||
|
||||
// only include until we have DecalStorage sorted
|
||||
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
|
||||
#include "decal_atlas_storage.h"
|
||||
|
||||
using namespace RendererRD;
|
||||
|
||||
@ -332,7 +330,7 @@ void TextureStorage::texture_free(RID p_texture) {
|
||||
}
|
||||
}
|
||||
|
||||
RendererStorageRD::base_singleton->decal_atlas_remove_texture(p_texture);
|
||||
DecalAtlasStorage::get_singleton()->decal_atlas_remove_texture(p_texture);
|
||||
|
||||
for (int i = 0; i < t->proxies.size(); i++) {
|
||||
Texture *p = texture_owner.get_or_null(t->proxies[i]);
|
||||
@ -931,7 +929,7 @@ void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
|
||||
//delete last, so proxies can be updated
|
||||
texture_owner.free(p_by_texture);
|
||||
|
||||
RendererStorageRD::base_singleton->decal_atlas_mark_dirty_on_texture(p_texture);
|
||||
DecalAtlasStorage::get_singleton()->decal_atlas_mark_dirty_on_texture(p_texture);
|
||||
}
|
||||
|
||||
void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) {
|
||||
|
@ -1887,7 +1887,7 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
|
||||
|
||||
} break;
|
||||
case RenderingServer::INSTANCE_DECAL: {
|
||||
new_aabb = RSG::storage->decal_get_aabb(p_instance->base);
|
||||
new_aabb = RSG::decal_atlas_storage->decal_get_aabb(p_instance->base);
|
||||
|
||||
} break;
|
||||
case RenderingServer::INSTANCE_VOXEL_GI: {
|
||||
|
@ -54,7 +54,6 @@ public:
|
||||
|
||||
struct DependencyTracker;
|
||||
|
||||
protected:
|
||||
struct Dependency {
|
||||
void changed_notify(DependencyChangedNotification p_notification);
|
||||
void deleted_notify(const RID &p_rid);
|
||||
@ -327,26 +326,6 @@ public:
|
||||
virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
|
||||
virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
virtual RID decal_allocate() = 0;
|
||||
virtual void decal_initialize(RID p_rid) = 0;
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const = 0;
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
|
||||
/* VOXEL GI API */
|
||||
|
||||
virtual RID voxel_gi_allocate() = 0;
|
||||
|
@ -399,6 +399,7 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
|
||||
RSG::scene = sr;
|
||||
RSG::rasterizer = RendererCompositor::create();
|
||||
RSG::canvas_texture_storage = RSG::rasterizer->get_canvas_texture_storage();
|
||||
RSG::decal_atlas_storage = RSG::rasterizer->get_decal_atlas_storage();
|
||||
RSG::texture_storage = RSG::rasterizer->get_texture_storage();
|
||||
RSG::storage = RSG::rasterizer->get_storage();
|
||||
RSG::canvas_render = RSG::rasterizer->get_canvas();
|
||||
|
@ -385,6 +385,12 @@ public:
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
#undef ServerName
|
||||
#undef server_name
|
||||
|
||||
#define ServerName RendererDecalAtlasStorage
|
||||
#define server_name RSG::decal_atlas_storage
|
||||
|
||||
FUNCRIDSPLIT(decal)
|
||||
|
||||
FUNC2(decal_set_extents, RID, const Vector3 &)
|
||||
@ -399,6 +405,13 @@ public:
|
||||
|
||||
/* BAKED LIGHT API */
|
||||
|
||||
//from now on, calls forwarded to this singleton
|
||||
#undef ServerName
|
||||
#undef server_name
|
||||
|
||||
#define ServerName RendererStorage
|
||||
#define server_name RSG::storage
|
||||
|
||||
FUNCRIDSPLIT(voxel_gi)
|
||||
|
||||
FUNC8(voxel_gi_allocate_data, RID, const Transform3D &, const AABB &, const Vector3i &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<uint8_t> &, const Vector<int> &)
|
||||
|
@ -33,6 +33,7 @@
|
||||
bool RenderingServerGlobals::threaded = false;
|
||||
|
||||
RendererCanvasTextureStorage *RenderingServerGlobals::canvas_texture_storage = nullptr;
|
||||
RendererDecalAtlasStorage *RenderingServerGlobals::decal_atlas_storage = nullptr;
|
||||
RendererTextureStorage *RenderingServerGlobals::texture_storage = nullptr;
|
||||
RendererStorage *RenderingServerGlobals::storage = nullptr;
|
||||
RendererCanvasRender *RenderingServerGlobals::canvas_render = nullptr;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "servers/rendering/renderer_canvas_render.h"
|
||||
#include "servers/rendering/renderer_scene.h"
|
||||
#include "servers/rendering/storage/canvas_texture_storage.h"
|
||||
#include "servers/rendering/storage/decal_atlas_storage.h"
|
||||
#include "servers/rendering/storage/texture_storage.h"
|
||||
|
||||
class RendererCanvasCull;
|
||||
@ -47,6 +48,7 @@ public:
|
||||
|
||||
static RendererCanvasTextureStorage *canvas_texture_storage;
|
||||
static RendererTextureStorage *texture_storage;
|
||||
static RendererDecalAtlasStorage *decal_atlas_storage;
|
||||
static RendererStorage *storage;
|
||||
static RendererCanvasRender *canvas_render;
|
||||
static RendererCompositor *rasterizer;
|
||||
|
60
servers/rendering/storage/decal_atlas_storage.h
Normal file
60
servers/rendering/storage/decal_atlas_storage.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*************************************************************************/
|
||||
/* decal_atlas_storage.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef DECAL_ATLAS_STORAGE_H
|
||||
#define DECAL_ATLAS_STORAGE_H
|
||||
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
class RendererDecalAtlasStorage {
|
||||
public:
|
||||
virtual ~RendererDecalAtlasStorage(){};
|
||||
|
||||
virtual RID decal_allocate() = 0;
|
||||
virtual void decal_initialize(RID p_rid) = 0;
|
||||
virtual void decal_free(RID p_rid) = 0;
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const = 0;
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
};
|
||||
|
||||
#endif // !DECAL_ATLAS_STORAGE_H
|
Loading…
Reference in New Issue
Block a user