Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions drivers/gles3/storage/texture_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1489,6 +1489,11 @@ void TextureStorage::texture_drawable_blit_rect(const TypedArray<RID> &p_texture
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);

i = 0;
while (i < p_textures.size()) {
texture_atlas_update_texture(p_textures[i]);
i += 1;
}
// Reset to system FBO
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
}
Expand Down Expand Up @@ -2315,6 +2320,30 @@ void TextureStorage::texture_atlas_remove_texture(RID p_texture) {
}
}

void TextureStorage::texture_atlas_update_texture(RID p_texture) {
if (texture_atlas.textures.has(p_texture)) {
CopyEffects *copy_effects = CopyEffects::get_singleton();
ERR_FAIL_NULL(copy_effects);
ERR_FAIL_COND(texture_atlas.texture == 0);

if (texture_atlas.dirty) {
return; //Don't mess with it while it's dirty anyway
}

glBindFramebuffer(GL_FRAMEBUFFER, texture_atlas.framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_atlas.texture, 0);
glViewport(0, 0, texture_atlas.size.width, texture_atlas.size.height);
glDisable(GL_BLEND);

TextureAtlas::Texture *t = texture_atlas.textures.getptr(p_texture);
Texture *src_tex = get_texture(p_texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, src_tex->tex_id);
copy_effects->copy_to_rect(t->uv_rect);
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
}
}

GLuint TextureStorage::texture_atlas_get_texture() const {
return texture_atlas.texture;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/gles3/storage/texture_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,7 @@ class TextureStorage : public RendererTextureStorage {
void texture_remove_from_texture_atlas(RID p_texture);
void texture_atlas_mark_dirty_on_texture(RID p_texture);
void texture_atlas_remove_texture(RID p_texture);
void texture_atlas_update_texture(RID p_texture);

/* DECAL API */

Expand Down
64 changes: 64 additions & 0 deletions servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1796,9 +1796,15 @@ void TextureStorage::texture_drawable_blit_rect(const TypedArray<RID> &p_texture

// DRAW!!
RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 6u);
// Detect if any target is in Decal Atlas and also draw to Decal Atlas?

RD::get_singleton()->draw_list_end();
RD::get_singleton()->draw_command_end_label();
i = 0;
while (i < p_textures.size()) {
decal_atlas_mark_draw_on_texture(p_textures[i]);
i += 1;
}
}

//these two APIs can be used together or in combination with the others.
Expand Down Expand Up @@ -3366,13 +3372,69 @@ void TextureStorage::decal_atlas_mark_dirty_on_texture(RID p_texture) {
}
}

void TextureStorage::decal_atlas_mark_draw_on_texture(RID p_texture) {
if (decal_atlas.dirty) {
return; //Don't mess with it while it's dirty anyway
}

if (decal_atlas.textures.has(p_texture)) {
//belongs to decal_atlas
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
t->drawn = true;

decal_atlas.draw_dirty = true;
}
}

void TextureStorage::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 TextureStorage::decal_atlas_redraw_textures() {
if (decal_atlas.dirty) {
return; //Don't mess with it while it's dirty anyway
}

if (!decal_atlas.draw_dirty) {
return; //Nothing to do
}

decal_atlas.draw_dirty = false;

CopyEffects *copy_effects = CopyEffects::get_singleton();
ERR_FAIL_NULL(copy_effects);
ERR_FAIL_COND(!decal_atlas.texture.is_valid());

RID prev_texture;
for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];

if (decal_atlas.textures.size()) {
if (i == 0) {
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb);
for (const KeyValue<RID, DecalAtlas::Texture> &E : decal_atlas.textures) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(E.key);
if (t->drawn) {
Texture *src_tex = get_texture(E.key);
copy_effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
t->drawn = false;
}
}

RD::get_singleton()->draw_list_end();

prev_texture = mm.texture;
} else {
copy_effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
prev_texture = mm.texture;
}
}
}
}

AABB TextureStorage::decal_get_aabb(RID p_decal) const {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_NULL_V(decal, AABB());
Expand Down Expand Up @@ -3403,6 +3465,7 @@ void TextureStorage::update_decal_atlas() {
}

decal_atlas.dirty = false;
decal_atlas.draw_dirty = false;

if (decal_atlas.texture.is_valid()) {
RD::get_singleton()->free_rid(decal_atlas.texture);
Expand Down Expand Up @@ -3573,6 +3636,7 @@ void TextureStorage::update_decal_atlas() {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(E.key);
Texture *src_tex = get_texture(E.key);
copy_effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
t->drawn = false;
}

RD::get_singleton()->draw_list_end();
Expand Down
4 changes: 4 additions & 0 deletions servers/rendering/renderer_rd/storage_rd/texture_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ class TextureStorage : public RendererTextureStorage {
int panorama_to_dp_users;
int users;
Rect2 uv_rect;
bool drawn = false;
};

struct SortItem {
Expand All @@ -277,6 +278,7 @@ class TextureStorage : public RendererTextureStorage {

HashMap<RID, Texture> textures;
bool dirty = true;
bool draw_dirty = false;
int mipmaps = 5;

RID texture;
Expand Down Expand Up @@ -665,7 +667,9 @@ class TextureStorage : public RendererTextureStorage {
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_mark_draw_on_texture(RID p_texture);
void decal_atlas_remove_texture(RID p_texture);
void decal_atlas_redraw_textures();

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;
Expand Down
1 change: 1 addition & 0 deletions servers/rendering/renderer_rd/storage_rd/utilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ void Utilities::update_dirty_resources() {
MaterialStorage::get_singleton()->_update_queued_materials();
MeshStorage::get_singleton()->_update_dirty_multimeshes();
MeshStorage::get_singleton()->_update_dirty_skeletons();
TextureStorage::get_singleton()->decal_atlas_redraw_textures();
TextureStorage::get_singleton()->update_decal_atlas();
}

Expand Down