diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.cpp | 46 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_canvas_gles3.h | 1 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_gles3.cpp | 21 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_gles3.h | 7 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 851 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 84 | ||||
-rw-r--r-- | drivers/gles3/storage/canvas_texture_storage.cpp | 96 | ||||
-rw-r--r-- | drivers/gles3/storage/canvas_texture_storage.h | 87 | ||||
-rw-r--r-- | drivers/gles3/storage/config.cpp | 4 | ||||
-rw-r--r-- | drivers/gles3/storage/decal_atlas_storage.cpp | 75 | ||||
-rw-r--r-- | drivers/gles3/storage/decal_atlas_storage.h | 67 | ||||
-rw-r--r-- | drivers/gles3/storage/render_target_storage.h | 132 | ||||
-rw-r--r-- | drivers/gles3/storage/texture_storage.cpp | 932 | ||||
-rw-r--r-- | drivers/gles3/storage/texture_storage.h | 228 |
14 files changed, 1208 insertions, 1423 deletions
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 1ddaf3d6a7..957713c444 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -38,9 +38,9 @@ #include "core/config/project_settings.h" #include "servers/rendering/rendering_server_default.h" -#include "storage/canvas_texture_storage.h" #include "storage/config.h" #include "storage/material_storage.h" +#include "storage/texture_storage.h" #ifndef GLES_OVER_GL #define glClearDepth glClearDepthf @@ -116,9 +116,11 @@ void RasterizerCanvasGLES3::_update_transform_to_mat4(const Transform3D &p_trans } void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) { - storage->frame.current_rt = nullptr; + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + + texture_storage->frame.current_rt = nullptr; - storage->_set_current_render_target(p_to_render_target); + texture_storage->_set_current_render_target(p_to_render_target); Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse(); @@ -130,7 +132,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ //update canvas state uniform buffer StateBuffer state_buffer; - Size2i ssize = storage->render_target_get_size(p_to_render_target); + Size2i ssize = texture_storage->render_target_get_size(p_to_render_target); Transform3D screen_transform; screen_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f); @@ -149,11 +151,11 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ state_buffer.canvas_modulate[2] = p_modulate.b; state_buffer.canvas_modulate[3] = p_modulate.a; - Size2 render_target_size = storage->render_target_get_size(p_to_render_target); + Size2 render_target_size = texture_storage->render_target_get_size(p_to_render_target); state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x; state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y; - state_buffer.time = storage->frame.time; + state_buffer.time = texture_storage->frame.time; state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel; state_buffer.directional_light_count = 0; //directional_light_count; @@ -166,7 +168,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ state_buffer.screen_to_sdf[0] = 1.0 / state_buffer.sdf_to_screen[0]; state_buffer.screen_to_sdf[1] = 1.0 / state_buffer.sdf_to_screen[1]; - Rect2 sdf_rect = storage->render_target_get_sdf_rect(p_to_render_target); + Rect2 sdf_rect = texture_storage->render_target_get_sdf_rect(p_to_render_target); Rect2 sdf_tex_rect(sdf_rect.position / canvas_scale, sdf_rect.size / canvas_scale); state_buffer.sdf_to_tex[0] = 1.0 / sdf_tex_rect.size.width; @@ -881,19 +883,21 @@ void RasterizerCanvasGLES3::update() { } void RasterizerCanvasGLES3::canvas_begin() { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + state.using_transparent_rt = false; - if (storage->frame.current_rt) { - storage->bind_framebuffer(storage->frame.current_rt->fbo); - state.using_transparent_rt = storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]; + if (texture_storage->frame.current_rt) { + glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->frame.current_rt->fbo); + state.using_transparent_rt = texture_storage->frame.current_rt->flags[GLES3::TextureStorage::RENDER_TARGET_TRANSPARENT]; } - if (storage->frame.current_rt && storage->frame.current_rt->clear_requested) { - const Color &col = storage->frame.current_rt->clear_color; + if (texture_storage->frame.current_rt && texture_storage->frame.current_rt->clear_requested) { + const Color &col = texture_storage->frame.current_rt->clear_color; glClearColor(col.r, col.g, col.b, col.a); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - storage->frame.current_rt->clear_requested = false; + texture_storage->frame.current_rt->clear_requested = false; } reset_canvas(); @@ -934,7 +938,7 @@ void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTe ct = t->canvas_texture; } else { - ct = GLES3::CanvasTextureStorage::get_singleton()->get_canvas_texture(p_texture); + ct = GLES3::TextureStorage::get_singleton()->get_canvas_texture(p_texture); } if (!ct) { @@ -1041,6 +1045,8 @@ void RasterizerCanvasGLES3::_set_uniforms() { } void RasterizerCanvasGLES3::reset_canvas() { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glDisable(GL_SCISSOR_TEST); @@ -1049,7 +1055,7 @@ void RasterizerCanvasGLES3::reset_canvas() { // Default to Mix. glBlendEquation(GL_FUNC_ADD); - if (storage->frame.current_rt && storage->frame.current_rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { + if (texture_storage->frame.current_rt && texture_storage->frame.current_rt->flags[GLES3::TextureStorage::RENDER_TARGET_TRANSPARENT]) { glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } else { glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); @@ -1255,7 +1261,7 @@ void RasterizerCanvasGLES3::_allocate_instance_data_buffer() { } void RasterizerCanvasGLES3::initialize() { - GLES3::CanvasTextureStorage *canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton(); + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); // quad buffer @@ -1450,8 +1456,8 @@ void fragment() { material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader); } - default_canvas_texture = canvas_texture_storage->canvas_texture_allocate(); - canvas_texture_storage->canvas_texture_initialize(default_canvas_texture); + default_canvas_texture = texture_storage->canvas_texture_allocate(); + texture_storage->canvas_texture_initialize(default_canvas_texture); state.using_light = nullptr; state.using_transparent_rt = false; @@ -1470,13 +1476,13 @@ RasterizerCanvasGLES3::RasterizerCanvasGLES3() { } RasterizerCanvasGLES3::~RasterizerCanvasGLES3() { - GLES3::CanvasTextureStorage *canvas_texture_storage = GLES3::CanvasTextureStorage::get_singleton(); + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); state.canvas_shader.version_free(state.canvas_shader_default_version); material_storage->material_free(default_canvas_group_material); material_storage->shader_free(default_canvas_group_shader); - canvas_texture_storage->canvas_texture_free(default_canvas_texture); + texture_storage->canvas_texture_free(default_canvas_texture); singleton = nullptr; } diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index 70066c5e2a..7294c9b132 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -37,7 +37,6 @@ #include "rasterizer_storage_gles3.h" #include "servers/rendering/renderer_canvas_render.h" #include "servers/rendering/renderer_compositor.h" -#include "storage/canvas_texture_storage.h" #include "storage/material_storage.h" #include "storage/texture_storage.h" diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 61aefc1192..1ad99d2d41 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -34,6 +34,7 @@ #include "core/config/project_settings.h" #include "core/os/os.h" +#include "storage/texture_storage.h" #define _EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 #define _EXT_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 @@ -87,6 +88,8 @@ #endif void RasterizerGLES3::begin_frame(double frame_step) { + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + frame++; delta = frame_step; @@ -95,9 +98,9 @@ void RasterizerGLES3::begin_frame(double frame_step) { double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs"); time_total = Math::fmod(time_total, time_roll_over); - storage.frame.time = time_total; - storage.frame.count++; - storage.frame.delta = frame_step; + texture_storage->frame.time = time_total; + texture_storage->frame.count++; + texture_storage->frame.delta = frame_step; storage.update_dirty_resources(); @@ -269,9 +272,10 @@ void RasterizerGLES3::prepare_for_blitting_render_targets() { } void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect) { - ERR_FAIL_COND(storage.frame.current_rt); + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + ERR_FAIL_COND(texture_storage->frame.current_rt); - GLES3::RenderTarget *rt = storage.render_target_owner.get_or_null(p_render_target); + GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target); ERR_FAIL_COND(!rt); // TODO: do we need a keep 3d linear option? @@ -282,16 +286,17 @@ void RasterizerGLES3::_blit_render_target_to_screen(RID p_render_target, Display glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo); } glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); glBlitFramebuffer(0, 0, rt->width, rt->height, 0, p_screen_rect.size.y, p_screen_rect.size.x, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST); } // is this p_screen useless in a multi window environment? void RasterizerGLES3::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) { // do this once off for all blits - storage.bind_framebuffer_system(); + GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton(); + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); - storage.frame.current_rt = nullptr; + texture_storage->frame.current_rt = nullptr; for (int i = 0; i < p_amount; i++) { const BlitToScreen &blit = p_render_targets[i]; diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h index 2279a502a2..35fbd070a5 100644 --- a/drivers/gles3/rasterizer_gles3.h +++ b/drivers/gles3/rasterizer_gles3.h @@ -37,12 +37,9 @@ #include "rasterizer_scene_gles3.h" #include "rasterizer_storage_gles3.h" #include "servers/rendering/renderer_compositor.h" -#include "storage/canvas_texture_storage.h" #include "storage/config.h" -#include "storage/decal_atlas_storage.h" #include "storage/material_storage.h" #include "storage/mesh_storage.h" -#include "storage/render_target_storage.h" #include "storage/texture_storage.h" class RasterizerGLES3 : public RendererCompositor { @@ -54,9 +51,7 @@ private: protected: GLES3::Config config; - GLES3::CanvasTextureStorage canvas_texture_storage; GLES3::TextureStorage texture_storage; - GLES3::DecalAtlasStorage decal_atlas_storage; GLES3::MaterialStorage material_storage; GLES3::MeshStorage mesh_storage; RasterizerStorageGLES3 storage; @@ -66,11 +61,9 @@ protected: void _blit_render_target_to_screen(RID p_render_target, DisplayServer::WindowID p_screen, const Rect2 &p_screen_rect); public: - RendererCanvasTextureStorage *get_canvas_texture_storage() { return &canvas_texture_storage; } RendererMaterialStorage *get_material_storage() { return &material_storage; } RendererMeshStorage *get_mesh_storage() { return &mesh_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; } diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 3517d985f0..1146c9c639 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -38,8 +38,6 @@ #include "rasterizer_scene_gles3.h" #include "servers/rendering/shader_language.h" -GLuint RasterizerStorageGLES3::system_fbo = 0; - void RasterizerStorageGLES3::bind_quad_array() const { //glBindBuffer(GL_ARRAY_BUFFER, resources.quadie); //glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0); @@ -658,758 +656,6 @@ AABB RasterizerStorageGLES3::visibility_notifier_get_aabb(RID p_notifier) const void RasterizerStorageGLES3::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) { } -/* RENDER TARGET */ - -void RasterizerStorageGLES3::_set_current_render_target(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - - if (rt) { - if (rt->allocate_is_dirty) { - rt->allocate_is_dirty = false; - _render_target_allocate(rt); - } - - frame.current_rt = rt; - ERR_FAIL_COND(!rt); - frame.clear_request = false; - - glViewport(0, 0, rt->width, rt->height); - - _dims.rt_width = rt->width; - _dims.rt_height = rt->height; - _dims.win_width = rt->width; - _dims.win_height = rt->height; - - } else { - frame.current_rt = nullptr; - frame.clear_request = false; - bind_framebuffer_system(); - } -} - -void RasterizerStorageGLES3::_render_target_allocate(GLES3::RenderTarget *rt) { - // do not allocate a render target with no size - if (rt->width <= 0 || rt->height <= 0) { - return; - } - - // do not allocate a render target that is attached to the screen - if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { - rt->fbo = RasterizerStorageGLES3::system_fbo; - return; - } - - GLuint color_internal_format; - GLuint color_format; - GLuint color_type = GL_UNSIGNED_BYTE; - Image::Format image_format; - - if (rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { -#ifdef GLES_OVER_GL - color_internal_format = GL_RGBA8; -#else - color_internal_format = GL_RGBA; -#endif - color_format = GL_RGBA; - image_format = Image::FORMAT_RGBA8; - } else { -#ifdef GLES_OVER_GL - color_internal_format = GL_RGB8; -#else - color_internal_format = GL_RGB; -#endif - color_format = GL_RGB; - image_format = Image::FORMAT_RGB8; - } - - rt->used_dof_blur_near = false; - rt->mip_maps_allocated = false; - - { - /* Front FBO */ - - GLES3::Texture *texture = GLES3::TextureStorage::get_singleton()->get_texture(rt->texture); - ERR_FAIL_COND(!texture); - - // framebuffer - glGenFramebuffers(1, &rt->fbo); - bind_framebuffer(rt->fbo); - - // color - glGenTextures(1, &rt->color); - glBindTexture(GL_TEXTURE_2D, rt->color); - - glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, nullptr); - - if (texture->flags & GLES3::TEXTURE_FLAG_FILTER) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); - - // depth - - if (config->support_depth_texture) { - glGenTextures(1, &rt->depth); - glBindTexture(GL_TEXTURE_2D, rt->depth); - glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); - } else { - glGenRenderbuffers(1, &rt->depth); - glBindRenderbuffer(GL_RENDERBUFFER, rt->depth); - - glRenderbufferStorage(GL_RENDERBUFFER, config->depth_buffer_internalformat, rt->width, rt->height); - - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - } - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - glDeleteFramebuffers(1, &rt->fbo); - if (config->support_depth_texture) { - glDeleteTextures(1, &rt->depth); - } else { - glDeleteRenderbuffers(1, &rt->depth); - } - - glDeleteTextures(1, &rt->color); - rt->fbo = 0; - rt->width = 0; - rt->height = 0; - rt->color = 0; - rt->depth = 0; - texture->tex_id = 0; - texture->active = false; - WARN_PRINT("Could not create framebuffer!!"); - return; - } - - texture->format = image_format; - texture->gl_format_cache = color_format; - texture->gl_type_cache = GL_UNSIGNED_BYTE; - texture->gl_internal_format_cache = color_internal_format; - texture->tex_id = rt->color; - texture->width = rt->width; - texture->alloc_width = rt->width; - texture->height = rt->height; - texture->alloc_height = rt->height; - texture->active = true; - - GLES3::TextureStorage::get_singleton()->texture_set_flags(rt->texture, texture->flags); - } - - /* BACK FBO */ - /* For MSAA */ - -#ifndef JAVASCRIPT_ENABLED - if (rt->msaa >= RS::VIEWPORT_MSAA_2X && rt->msaa <= RS::VIEWPORT_MSAA_8X) { - rt->multisample_active = true; - - static const int msaa_value[] = { 0, 2, 4, 8, 16 }; - int msaa = msaa_value[rt->msaa]; - - int max_samples = 0; - glGetIntegerv(GL_MAX_SAMPLES, &max_samples); - if (msaa > max_samples) { - WARN_PRINT("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples)); - msaa = max_samples; - } - - //regular fbo - glGenFramebuffers(1, &rt->multisample_fbo); - bind_framebuffer(rt->multisample_fbo); - - glGenRenderbuffers(1, &rt->multisample_depth); - glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_depth); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config->depth_buffer_internalformat, rt->width, rt->height); - - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth); - - glGenRenderbuffers(1, &rt->multisample_color); - glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_color); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height); - - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - // Delete allocated resources and default to no MSAA - WARN_PRINT_ONCE("Cannot allocate back framebuffer for MSAA"); - printf("err status: %x\n", status); - rt->multisample_active = false; - - glDeleteFramebuffers(1, &rt->multisample_fbo); - rt->multisample_fbo = 0; - - glDeleteRenderbuffers(1, &rt->multisample_depth); - rt->multisample_depth = 0; - - glDeleteRenderbuffers(1, &rt->multisample_color); - rt->multisample_color = 0; - } - - glBindRenderbuffer(GL_RENDERBUFFER, 0); - bind_framebuffer(0); - - } else -#endif // JAVASCRIPT_ENABLED - { - rt->multisample_active = false; - } - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - // copy texscreen buffers - // if (!(rt->flags[RendererStorage::RENDER_TARGET_NO_SAMPLING])) { - if (true) { - glGenTextures(1, &rt->copy_screen_effect.color); - glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color); - - if (rt->flags[RendererStorage::RENDER_TARGET_TRANSPARENT]) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - } else { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); - } - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glGenFramebuffers(1, &rt->copy_screen_effect.fbo); - bind_framebuffer(rt->copy_screen_effect.fbo); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->copy_screen_effect.color, 0); - - glClearColor(0, 0, 0, 0); - glClear(GL_COLOR_BUFFER_BIT); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - _render_target_clear(rt); - ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); - } - } - - // Allocate mipmap chains for post_process effects - // if (!rt->flags[RendererStorage::RENDER_TARGET_NO_3D] && rt->width >= 2 && rt->height >= 2) { - if (rt->width >= 2 && rt->height >= 2) { - for (int i = 0; i < 2; i++) { - ERR_FAIL_COND(rt->mip_maps[i].sizes.size()); - int w = rt->width; - int h = rt->height; - - if (i > 0) { - w >>= 1; - h >>= 1; - } - - int level = 0; - int fb_w = w; - int fb_h = h; - - while (true) { - GLES3::RenderTarget::MipMaps::Size mm; - mm.width = w; - mm.height = h; - rt->mip_maps[i].sizes.push_back(mm); - - w >>= 1; - h >>= 1; - - if (w < 2 || h < 2) { - break; - } - - level++; - } - - GLsizei width = fb_w; - GLsizei height = fb_h; - - if (config->render_to_mipmap_supported) { - glGenTextures(1, &rt->mip_maps[i].color); - glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].color); - - for (int l = 0; l < level + 1; l++) { - glTexImage2D(GL_TEXTURE_2D, l, color_internal_format, width, height, 0, color_format, color_type, nullptr); - width = MAX(1, (width / 2)); - height = MAX(1, (height / 2)); - } -#ifdef GLES_OVER_GL - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level); -#endif - } else { - // Can't render to specific levels of a mipmap in ES 2.0 or Webgl so create a texture for each level - for (int l = 0; l < level + 1; l++) { - glGenTextures(1, &rt->mip_maps[i].sizes.write[l].color); - glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[l].color); - glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, width, height, 0, color_format, color_type, nullptr); - width = MAX(1, (width / 2)); - height = MAX(1, (height / 2)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - } - - glDisable(GL_SCISSOR_TEST); - glColorMask(1, 1, 1, 1); - glDepthMask(GL_TRUE); - - for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) { - GLES3::RenderTarget::MipMaps::Size &mm = rt->mip_maps[i].sizes.write[j]; - - glGenFramebuffers(1, &mm.fbo); - bind_framebuffer(mm.fbo); - - if (config->render_to_mipmap_supported) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].color, j); - } else { - glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color, 0); - } - - bool used_depth = false; - if (j == 0 && i == 0) { //use always - if (config->support_depth_texture) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); - } else { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - } - used_depth = true; - } - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - WARN_PRINT_ONCE("Cannot allocate mipmaps for 3D post processing effects"); - bind_framebuffer_system(); - return; - } - - glClearColor(1.0, 0.0, 1.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT); - if (used_depth) { - glClearDepth(1.0); - glClear(GL_DEPTH_BUFFER_BIT); - } - } - - rt->mip_maps[i].levels = level; - - if (config->render_to_mipmap_supported) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - } - rt->mip_maps_allocated = true; - } - - bind_framebuffer_system(); -} - -void RasterizerStorageGLES3::_render_target_clear(GLES3::RenderTarget *rt) { - // there is nothing to clear when DIRECT_TO_SCREEN is used - if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { - return; - } - - if (rt->fbo) { - glDeleteFramebuffers(1, &rt->fbo); - glDeleteTextures(1, &rt->color); - rt->fbo = 0; - } - - if (rt->external.fbo != 0) { - // free this - glDeleteFramebuffers(1, &rt->external.fbo); - - // clean up our texture - GLES3::Texture *t = GLES3::TextureStorage::get_singleton()->get_texture(rt->external.texture); - t->alloc_height = 0; - t->alloc_width = 0; - t->width = 0; - t->height = 0; - t->active = false; - GLES3::TextureStorage::get_singleton()->texture_free(rt->external.texture); - memdelete(t); - - rt->external.fbo = 0; - } - - if (rt->depth) { - if (config->support_depth_texture) { - glDeleteTextures(1, &rt->depth); - } else { - glDeleteRenderbuffers(1, &rt->depth); - } - - rt->depth = 0; - } - - GLES3::Texture *tex = GLES3::TextureStorage::get_singleton()->get_texture(rt->texture); - tex->alloc_height = 0; - tex->alloc_width = 0; - tex->width = 0; - tex->height = 0; - tex->active = false; - - if (rt->copy_screen_effect.color) { - glDeleteFramebuffers(1, &rt->copy_screen_effect.fbo); - rt->copy_screen_effect.fbo = 0; - - glDeleteTextures(1, &rt->copy_screen_effect.color); - rt->copy_screen_effect.color = 0; - } - - for (int i = 0; i < 2; i++) { - if (rt->mip_maps[i].sizes.size()) { - for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) { - glDeleteFramebuffers(1, &rt->mip_maps[i].sizes[j].fbo); - glDeleteTextures(1, &rt->mip_maps[i].sizes[j].color); - } - - glDeleteTextures(1, &rt->mip_maps[i].color); - rt->mip_maps[i].sizes.clear(); - rt->mip_maps[i].levels = 0; - rt->mip_maps[i].color = 0; - } - } - - if (rt->multisample_active) { - glDeleteFramebuffers(1, &rt->multisample_fbo); - rt->multisample_fbo = 0; - - glDeleteRenderbuffers(1, &rt->multisample_depth); - rt->multisample_depth = 0; - - glDeleteRenderbuffers(1, &rt->multisample_color); - - rt->multisample_color = 0; - } -} - -RID RasterizerStorageGLES3::render_target_create() { - GLES3::RenderTarget *rt = memnew(GLES3::RenderTarget); - GLES3::Texture *t = memnew(GLES3::Texture); - - t->type = RenderingDevice::TEXTURE_TYPE_2D; - t->flags = 0; - t->width = 0; - t->height = 0; - t->alloc_height = 0; - t->alloc_width = 0; - t->format = Image::FORMAT_R8; - t->target = GL_TEXTURE_2D; - t->gl_format_cache = 0; - t->gl_internal_format_cache = 0; - t->gl_type_cache = 0; - t->data_size = 0; - t->total_data_size = 0; - t->ignore_mipmaps = false; - t->compressed = false; - t->mipmaps = 1; - t->active = true; - t->tex_id = 0; - t->render_target = rt; - - rt->texture = GLES3::TextureStorage::get_singleton()->make_rid(t); - return render_target_owner.make_rid(rt); -} - -void RasterizerStorageGLES3::render_target_set_position(RID p_render_target, int p_x, int p_y) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - rt->x = p_x; - rt->y = p_y; -} - -void RasterizerStorageGLES3::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - if (p_width == rt->width && p_height == rt->height) { - return; - } - - _render_target_clear(rt); - - rt->width = p_width; - rt->height = p_height; - - // print_line("render_target_set_size " + itos(p_render_target.get_id()) + ", w " + itos(p_width) + " h " + itos(p_height)); - - rt->allocate_is_dirty = true; - //_render_target_allocate(rt); -} - -// TODO: convert to Size2i internally -Size2i RasterizerStorageGLES3::render_target_get_size(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, Size2()); - - return Size2i(rt->width, rt->height); -} - -RID RasterizerStorageGLES3::render_target_get_texture(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, RID()); - - if (rt->external.fbo == 0) { - return rt->texture; - } else { - return rt->external.texture; - } -} - -void RasterizerStorageGLES3::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - if (p_texture_id == 0) { - if (rt->external.fbo != 0) { - // free this - glDeleteFramebuffers(1, &rt->external.fbo); - - // and this - if (rt->external.depth != 0) { - glDeleteRenderbuffers(1, &rt->external.depth); - } - - // clean up our texture - GLES3::Texture *t = GLES3::TextureStorage::get_singleton()->get_texture(rt->external.texture); - t->alloc_height = 0; - t->alloc_width = 0; - t->width = 0; - t->height = 0; - t->active = false; - GLES3::TextureStorage::get_singleton()->texture_free(rt->external.texture); - memdelete(t); - - rt->external.fbo = 0; - rt->external.color = 0; - rt->external.depth = 0; - } - } else { - GLES3::Texture *t; - - if (rt->external.fbo == 0) { - // create our fbo - glGenFramebuffers(1, &rt->external.fbo); - bind_framebuffer(rt->external.fbo); - - // allocate a texture - t = memnew(GLES3::Texture); - - t->type = RenderingDevice::TEXTURE_TYPE_2D; - t->flags = 0; - t->width = 0; - t->height = 0; - t->alloc_height = 0; - t->alloc_width = 0; - t->format = Image::FORMAT_RGBA8; - t->target = GL_TEXTURE_2D; - t->gl_format_cache = 0; - t->gl_internal_format_cache = 0; - t->gl_type_cache = 0; - t->data_size = 0; - t->compressed = false; - t->srgb = false; - t->total_data_size = 0; - t->ignore_mipmaps = false; - t->mipmaps = 1; - t->active = true; - t->tex_id = 0; - t->render_target = rt; - - rt->external.texture = GLES3::TextureStorage::get_singleton()->make_rid(t); - - } else { - // bind our frame buffer - bind_framebuffer(rt->external.fbo); - - // find our texture - t = GLES3::TextureStorage::get_singleton()->get_texture(rt->external.texture); - } - - // set our texture - t->tex_id = p_texture_id; - rt->external.color = p_texture_id; - - // size shouldn't be different - t->width = rt->width; - t->height = rt->height; - t->alloc_height = rt->width; - t->alloc_width = rt->height; - - // Switch our texture on our frame buffer - { - // set our texture as the destination for our framebuffer - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0); - - // seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :) - if (config->support_depth_texture) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); - } else { - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); - } - } - - // check status and unbind - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - bind_framebuffer_system(); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - printf("framebuffer fail, status: %x\n", status); - } - - ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); - } -} - -void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - // When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as - // those functions change how they operate depending on the value of DIRECT_TO_SCREEN - if (p_flag == RENDER_TARGET_DIRECT_TO_SCREEN && p_value != rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { - _render_target_clear(rt); - rt->flags[p_flag] = p_value; - _render_target_allocate(rt); - } - - rt->flags[p_flag] = p_value; - - switch (p_flag) { - case RENDER_TARGET_TRANSPARENT: - /* - case RENDER_TARGET_HDR: - case RENDER_TARGET_NO_3D: - case RENDER_TARGET_NO_SAMPLING: - case RENDER_TARGET_NO_3D_EFFECTS: */ - { - //must reset for these formats - _render_target_clear(rt); - _render_target_allocate(rt); - } - break; - default: { - } - } -} - -bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, false); - - return rt->used_in_frame; -} - -void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - rt->used_in_frame = false; -} - -void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - if (rt->msaa == p_msaa) { - return; - } - - _render_target_clear(rt); - rt->msaa = p_msaa; - _render_target_allocate(rt); -} - -//RasterizerStorageGLES3::GLES3::RenderTarget * RasterizerStorageGLES3::render_target_get(RID p_render_target) -//{ -// return render_target_owner.get_or_null(p_render_target); -//} - -void RasterizerStorageGLES3::render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - rt->use_fxaa = p_fxaa; -} - -void RasterizerStorageGLES3::render_target_set_use_debanding(RID p_render_target, bool p_debanding) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - - if (p_debanding) { - WARN_PRINT_ONCE("Debanding is not supported in the OpenGL backend. Switch to the Vulkan backend and make sure HDR is enabled."); - } - - rt->use_debanding = p_debanding; -} - -void RasterizerStorageGLES3::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - rt->clear_requested = true; - rt->clear_color = p_clear_color; - - // ERR_FAIL_COND(!frame.current_rt); - // frame.clear_request = true; - // frame.clear_request_color = p_color; -} - -bool RasterizerStorageGLES3::render_target_is_clear_requested(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, false); - return rt->clear_requested; -} -Color RasterizerStorageGLES3::render_target_get_clear_request_color(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND_V(!rt, Color()); - return rt->clear_color; -} - -void RasterizerStorageGLES3::render_target_disable_clear_request(RID p_render_target) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_render_target); - ERR_FAIL_COND(!rt); - rt->clear_requested = false; -} - -void RasterizerStorageGLES3::render_target_do_clear_request(RID p_render_target) { -} - -void RasterizerStorageGLES3::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { -} - -Rect2i RasterizerStorageGLES3::render_target_get_sdf_rect(RID p_render_target) const { - return Rect2i(); -} - -void RasterizerStorageGLES3::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) { -} - /* CANVAS SHADOW */ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) { @@ -1425,7 +671,7 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) { glActiveTexture(GL_TEXTURE0); glGenFramebuffers(1, &cls->fbo); - bind_framebuffer(cls->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo); glGenRenderbuffers(1, &cls->depth); glBindRenderbuffer(GL_RENDERBUFFER, cls->depth); @@ -1452,7 +698,7 @@ RID RasterizerStorageGLES3::canvas_light_shadow_buffer_create(int p_width) { GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); //printf("errnum: %x\n",status); - bind_framebuffer_system(); + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); if (status != GL_FRAMEBUFFER_COMPLETE) { memdelete(cls); @@ -1585,24 +831,14 @@ RS::InstanceType RasterizerStorageGLES3::get_base_type(RID p_rid) const { } bool RasterizerStorageGLES3::free(RID p_rid) { - if (render_target_owner.owns(p_rid)) { - GLES3::RenderTarget *rt = render_target_owner.get_or_null(p_rid); - _render_target_clear(rt); - - GLES3::Texture *t = GLES3::TextureStorage::get_singleton()->get_texture(rt->texture); - if (t) { - GLES3::TextureStorage::get_singleton()->texture_free(rt->texture); - memdelete(t); - } - render_target_owner.free(p_rid); - memdelete(rt); - + if (GLES3::TextureStorage::get_singleton()->owns_render_target(p_rid)) { + GLES3::TextureStorage::get_singleton()->render_target_free(p_rid); return true; } else if (GLES3::TextureStorage::get_singleton()->owns_texture(p_rid)) { GLES3::TextureStorage::get_singleton()->texture_free(p_rid); return true; - } else if (GLES3::CanvasTextureStorage::get_singleton()->owns_canvas_texture(p_rid)) { - GLES3::CanvasTextureStorage::get_singleton()->canvas_texture_free(p_rid); + } else if (GLES3::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) { + GLES3::TextureStorage::get_singleton()->canvas_texture_free(p_rid); return true; } else if (sky_owner.owns(p_rid)) { Sky *sky = sky_owner.get_or_null(p_rid); @@ -1859,84 +1095,12 @@ RenderingDevice::DeviceType RasterizerStorageGLES3::get_video_adapter_type() con } void RasterizerStorageGLES3::initialize() { - RasterizerStorageGLES3::system_fbo = 0; config = GLES3::Config::get_singleton(); - config->initialize(); - - //determine formats for depth textures (or renderbuffers) - if (config->support_depth_texture) { - // Will use texture for depth - // have to manually see if we can create a valid framebuffer texture using UNSIGNED_INT, - // as there is no extension to test for this. - GLuint fbo; - glGenFramebuffers(1, &fbo); - bind_framebuffer(fbo); - GLuint depth; - glGenTextures(1, &depth); - glBindTexture(GL_TEXTURE_2D, depth); - glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0); - - GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - - bind_framebuffer_system(); - glDeleteFramebuffers(1, &fbo); - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &depth); - - if (status != GL_FRAMEBUFFER_COMPLETE) { - // If it fails, test to see if it supports a framebuffer texture using UNSIGNED_SHORT - // This is needed because many OSX devices don't support either UNSIGNED_INT or UNSIGNED_SHORT -#ifdef GLES_OVER_GL - config->depth_internalformat = GL_DEPTH_COMPONENT16; -#else - // OES_depth_texture extension only specifies GL_DEPTH_COMPONENT. - config->depth_internalformat = GL_DEPTH_COMPONENT; -#endif - config->depth_type = GL_UNSIGNED_SHORT; - - glGenFramebuffers(1, &fbo); - bind_framebuffer(fbo); - - glGenTextures(1, &depth); - glBindTexture(GL_TEXTURE_2D, depth); - glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0); - - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - //if it fails again depth textures aren't supported, use rgba shadows and renderbuffer for depth - config->support_depth_texture = false; - config->use_rgba_3d_shadows = true; - } - - bind_framebuffer_system(); - glDeleteFramebuffers(1, &fbo); - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures(1, &depth); - } - } + // config->initialize(); //picky requirements for these config->support_shadow_cubemaps = config->support_depth_texture && config->support_write_depth && config->support_depth_cubemaps; - frame.count = 0; - frame.delta = 0; - frame.current_rt = nullptr; - frame.clear_request = false; - // the use skeleton software path should be used if either float texture is not supported, // OR max_vertex_texture_image_units is zero config->use_skeleton_software = (config->float_texture_supported == false) || (config->max_vertex_texture_image_units == 0); @@ -2105,7 +1269,6 @@ void RasterizerStorageGLES3::update_dirty_resources() { } RasterizerStorageGLES3::RasterizerStorageGLES3() { - RasterizerStorageGLES3::system_fbo = 0; } RasterizerStorageGLES3::~RasterizerStorageGLES3() { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index 105529ee3d..a335177632 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -40,10 +40,8 @@ #include "servers/rendering/renderer_storage.h" #include "servers/rendering/shader_compiler.h" #include "servers/rendering/shader_language.h" -#include "storage/canvas_texture_storage.h" #include "storage/config.h" #include "storage/material_storage.h" -#include "storage/render_target_storage.h" #include "storage/texture_storage.h" // class RasterizerCanvasGLES3; @@ -54,8 +52,6 @@ public: // RasterizerCanvasGLES3 *canvas; // RasterizerSceneGLES3 *scene; - static GLuint system_fbo; - GLES3::Config *config; struct Resources { @@ -363,43 +359,6 @@ public: AABB visibility_notifier_get_aabb(RID p_notifier) const override; void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override; - // RENDER TARGET - - mutable RID_PtrOwner<GLES3::RenderTarget> render_target_owner; - - void _render_target_clear(GLES3::RenderTarget *rt); - void _render_target_allocate(GLES3::RenderTarget *rt); - void _set_current_render_target(RID p_render_target); - - RID render_target_create() override; - void render_target_set_position(RID p_render_target, int p_x, int p_y) override; - void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override; - Size2i render_target_get_size(RID p_render_target); - RID render_target_get_texture(RID p_render_target) override; - void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override; - - void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override; - bool render_target_was_used(RID p_render_target) override; - void render_target_clear_used(RID p_render_target); - void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa); - void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa); - void render_target_set_use_debanding(RID p_render_target, bool p_debanding); - - // new - void render_target_set_as_unused(RID p_render_target) override { - render_target_clear_used(p_render_target); - } - - void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override; - bool render_target_is_clear_requested(RID p_render_target) override; - Color render_target_get_clear_request_color(RID p_render_target) override; - void render_target_disable_clear_request(RID p_render_target) override; - void render_target_do_clear_request(RID p_render_target) override; - - void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override; - Rect2i render_target_get_sdf_rect(RID p_render_target) const override; - void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override; - // access from canvas // GLES3::RenderTarget * render_target_get(RID p_render_target); @@ -439,24 +398,6 @@ public: bool free(RID p_rid) override; - struct Frame { - GLES3::RenderTarget *current_rt; - - // these 2 may have been superseded by the equivalents in the render target. - // these may be able to be removed. - bool clear_request; - Color clear_request_color; - - float time; - float delta; - uint64_t count; - - Frame() { - // current_rt = nullptr; - // clear_request = false; - } - } frame; - void initialize(); void finalize(); @@ -498,34 +439,9 @@ public: return String(); } - // make access easier to these - struct Dimensions { - // render target - int rt_width; - int rt_height; - - // window - int win_width; - int win_height; - Dimensions() { - rt_width = 0; - rt_height = 0; - win_width = 0; - win_height = 0; - } - } _dims; - void buffer_orphan_and_upload(unsigned int p_buffer_size, unsigned int p_offset, unsigned int p_data_size, const void *p_data, GLenum p_target = GL_ARRAY_BUFFER, GLenum p_usage = GL_DYNAMIC_DRAW, bool p_optional_orphan = false) const; bool safe_buffer_sub_data(unsigned int p_total_buffer_size, GLenum p_target, unsigned int p_offset, unsigned int p_data_size, const void *p_data, unsigned int &r_offset_after) const; - void bind_framebuffer(GLuint framebuffer) { - glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); - } - - void bind_framebuffer_system() { - glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo); - } - RasterizerStorageGLES3(); ~RasterizerStorageGLES3(); }; diff --git a/drivers/gles3/storage/canvas_texture_storage.cpp b/drivers/gles3/storage/canvas_texture_storage.cpp deleted file mode 100644 index fe12700c21..0000000000 --- a/drivers/gles3/storage/canvas_texture_storage.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************/ -/* canvas_texture_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 "canvas_texture_storage.h" - -using namespace GLES3; - -CanvasTextureStorage *CanvasTextureStorage::singleton = nullptr; - -CanvasTextureStorage *CanvasTextureStorage::get_singleton() { - return singleton; -} - -CanvasTextureStorage::CanvasTextureStorage() { - singleton = this; -} - -CanvasTextureStorage::~CanvasTextureStorage() { - singleton = nullptr; -} - -RID CanvasTextureStorage::canvas_texture_allocate() { - return canvas_texture_owner.allocate_rid(); -} - -void CanvasTextureStorage::canvas_texture_initialize(RID p_rid) { - canvas_texture_owner.initialize_rid(p_rid); -} - -void CanvasTextureStorage::canvas_texture_free(RID p_rid) { - canvas_texture_owner.free(p_rid); -} - -void CanvasTextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { - CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); - switch (p_channel) { - case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: { - ct->diffuse = p_texture; - } break; - case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: { - ct->normal_map = p_texture; - } break; - case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: { - ct->specular = p_texture; - } break; - } -} - -void CanvasTextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) { - CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); - ct->specular_color.r = p_specular_color.r; - ct->specular_color.g = p_specular_color.g; - ct->specular_color.b = p_specular_color.b; - ct->specular_color.a = p_shininess; -} - -void CanvasTextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { - CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); - ct->texture_filter = p_filter; -} - -void CanvasTextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { - CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); - ct->texture_repeat = p_repeat; -} - -#endif // !GLES3_ENABLED diff --git a/drivers/gles3/storage/canvas_texture_storage.h b/drivers/gles3/storage/canvas_texture_storage.h deleted file mode 100644 index 5930e927fe..0000000000 --- a/drivers/gles3/storage/canvas_texture_storage.h +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************/ -/* canvas_texture_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 CANVAS_TEXTURE_STORAGE_GLES3_H -#define CANVAS_TEXTURE_STORAGE_GLES3_H - -#ifdef GLES3_ENABLED - -#include "core/templates/rid_owner.h" -#include "servers/rendering/storage/canvas_texture_storage.h" - -namespace GLES3 { - -struct CanvasTexture { - RID diffuse; - RID normal_map; - RID specular; - Color specular_color = Color(1, 1, 1, 1); - float shininess = 1.0; - - RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; - RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; - - Size2i size_cache = Size2i(1, 1); - bool use_normal_cache = false; - bool use_specular_cache = false; - bool cleared_cache = true; -}; - -class CanvasTextureStorage : public RendererCanvasTextureStorage { -private: - static CanvasTextureStorage *singleton; - - RID_Owner<CanvasTexture, true> canvas_texture_owner; - -public: - static CanvasTextureStorage *get_singleton(); - - CanvasTextureStorage(); - virtual ~CanvasTextureStorage(); - - CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); }; - bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); }; - - virtual RID canvas_texture_allocate() override; - virtual void canvas_texture_initialize(RID p_rid) override; - virtual void canvas_texture_free(RID p_rid) override; - - virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override; - virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override; - - virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override; - virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override; -}; - -} // namespace GLES3 - -#endif // !GLES3_ENABLED - -#endif // !CANVAS_TEXTURE_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index 1f66401427..7b87ce7e4f 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -40,6 +40,10 @@ Config *Config::singleton = nullptr; Config::Config() { singleton = this; should_orphan = true; + + // If this is to early we need to change our code similar to what we're doing in RendererRD, + // and instantiate our storage classes when we are ready to do so in the order we want. + initialize(); } Config::~Config() { diff --git a/drivers/gles3/storage/decal_atlas_storage.cpp b/drivers/gles3/storage/decal_atlas_storage.cpp deleted file mode 100644 index 7bac34ea19..0000000000 --- a/drivers/gles3/storage/decal_atlas_storage.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************/ -/* 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 diff --git a/drivers/gles3/storage/decal_atlas_storage.h b/drivers/gles3/storage/decal_atlas_storage.h deleted file mode 100644 index f5dc36b1fb..0000000000 --- a/drivers/gles3/storage/decal_atlas_storage.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************/ -/* 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 diff --git a/drivers/gles3/storage/render_target_storage.h b/drivers/gles3/storage/render_target_storage.h deleted file mode 100644 index 816cc76e40..0000000000 --- a/drivers/gles3/storage/render_target_storage.h +++ /dev/null @@ -1,132 +0,0 @@ -/*************************************************************************/ -/* render_target_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 RENDER_TARGET_STORAGE_GLES3_H -#define RENDER_TARGET_STORAGE_GLES3_H - -#ifdef GLES3_ENABLED - -#include "core/templates/rid_owner.h" -#include "servers/rendering/renderer_compositor.h" -#include "servers/rendering/renderer_storage.h" // included until we move stuff into storage/render_target_storage.h -// #include "servers/rendering/storage/render_target_storage.h" - -// This must come first to avoid windows.h mess -#include "platform_config.h" -#ifndef OPENGL_INCLUDE_H -#include <GLES3/gl3.h> -#else -#include OPENGL_INCLUDE_H -#endif - -namespace GLES3 { - -// NOTE, this class currently is just a container for the the RenderTarget struct and is not yet implemented further, we'll do that next after we finish with TextureStorage - -struct RenderTarget { - RID self; - GLuint fbo = 0; - GLuint color = 0; - GLuint depth = 0; - - GLuint multisample_fbo = 0; - GLuint multisample_color = 0; - GLuint multisample_depth = 0; - bool multisample_active = false; - - struct Effect { - GLuint fbo = 0; - int width = 0; - int height = 0; - - GLuint color = 0; - }; - - Effect copy_screen_effect; - - struct MipMaps { - struct Size { - GLuint fbo = 0; - GLuint color = 0; - int width = 0; - int height = 0; - }; - - Vector<Size> sizes; - GLuint color = 0; - int levels = 0; - }; - - MipMaps mip_maps[2]; - - struct External { - GLuint fbo = 0; - GLuint color = 0; - GLuint depth = 0; - RID texture; - } external; - - int x = 0; - int y = 0; - int width = 0; - int height = 0; - - bool flags[RendererStorage::RENDER_TARGET_FLAG_MAX] = {}; - - // instead of allocating sized render targets immediately, - // defer this for faster startup - bool allocate_is_dirty = false; - bool used_in_frame = false; - RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; - - bool use_fxaa = false; - bool use_debanding = false; - - RID texture; - - bool used_dof_blur_near = false; - bool mip_maps_allocated = false; - - Color clear_color = Color(1, 1, 1, 1); - bool clear_requested = false; - - RenderTarget() { - for (int i = 0; i < RendererStorage::RENDER_TARGET_FLAG_MAX; ++i) { - flags[i] = false; - } - external.fbo = 0; - } -}; - -} // namespace GLES3 - -#endif // !GLES3_ENABLED - -#endif // !RENDER_TARGET_STORAGE_GLES3_H diff --git a/drivers/gles3/storage/texture_storage.cpp b/drivers/gles3/storage/texture_storage.cpp index d199b1032e..2a63c7ccad 100644 --- a/drivers/gles3/storage/texture_storage.cpp +++ b/drivers/gles3/storage/texture_storage.cpp @@ -43,6 +43,81 @@ TextureStorage *TextureStorage::get_singleton() { TextureStorage::TextureStorage() { singleton = this; + + system_fbo = 0; + + frame.count = 0; + frame.delta = 0; + frame.current_rt = nullptr; + frame.clear_request = false; + + Config *config = Config::get_singleton(); + + //determine formats for depth textures (or renderbuffers) + if (config->support_depth_texture) { + // Will use texture for depth + // have to manually see if we can create a valid framebuffer texture using UNSIGNED_INT, + // as there is no extension to test for this. + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + GLuint depth; + glGenTextures(1, &depth); + glBindTexture(GL_TEXTURE_2D, depth); + glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + glDeleteFramebuffers(1, &fbo); + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &depth); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + // If it fails, test to see if it supports a framebuffer texture using UNSIGNED_SHORT + // This is needed because many OSX devices don't support either UNSIGNED_INT or UNSIGNED_SHORT +#ifdef GLES_OVER_GL + config->depth_internalformat = GL_DEPTH_COMPONENT16; +#else + // OES_depth_texture extension only specifies GL_DEPTH_COMPONENT. + config->depth_internalformat = GL_DEPTH_COMPONENT; +#endif + config->depth_type = GL_UNSIGNED_SHORT; + + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + glGenTextures(1, &depth); + glBindTexture(GL_TEXTURE_2D, depth); + glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, 32, 32, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, nullptr); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0); + + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + //if it fails again depth textures aren't supported, use rgba shadows and renderbuffer for depth + config->support_depth_texture = false; + config->use_rgba_3d_shadows = true; + } + + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + glDeleteFramebuffers(1, &fbo); + glBindTexture(GL_TEXTURE_2D, 0); + glDeleteTextures(1, &depth); + } + } } TextureStorage::~TextureStorage() { @@ -65,6 +140,55 @@ bool TextureStorage::can_create_resources_async() const { return false; } +/* Canvas Texture API */ + +RID TextureStorage::canvas_texture_allocate() { + return canvas_texture_owner.allocate_rid(); +} + +void TextureStorage::canvas_texture_initialize(RID p_rid) { + canvas_texture_owner.initialize_rid(p_rid); +} + +void TextureStorage::canvas_texture_free(RID p_rid) { + canvas_texture_owner.free(p_rid); +} + +void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + switch (p_channel) { + case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: { + ct->diffuse = p_texture; + } break; + case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: { + ct->normal_map = p_texture; + } break; + case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: { + ct->specular = p_texture; + } break; + } +} + +void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + ct->specular_color.r = p_specular_color.r; + ct->specular_color.g = p_specular_color.g; + ct->specular_color.b = p_specular_color.b; + ct->specular_color.a = p_shininess; +} + +void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + ct->texture_filter = p_filter; +} + +void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) { + CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture); + ct->texture_repeat = p_repeat; +} + +/* Texture API */ + static const GLenum _cube_side_enum[6] = { GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_X, @@ -1208,4 +1332,812 @@ void TextureStorage::textures_keep_original(bool p_enable) { Config::get_singleton()->keep_original_textures = p_enable; } +/* DECAL API */ + +RID TextureStorage::decal_allocate() { + return RID(); +} + +void TextureStorage::decal_initialize(RID p_rid) { +} + +void TextureStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) { +} + +void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) { +} + +void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) { +} + +void TextureStorage::decal_set_albedo_mix(RID p_decal, float p_mix) { +} + +void TextureStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) { +} + +void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) { +} + +void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) { +} + +void TextureStorage::decal_set_fade(RID p_decal, float p_above, float p_below) { +} + +void TextureStorage::decal_set_normal_fade(RID p_decal, float p_fade) { +} + +AABB TextureStorage::decal_get_aabb(RID p_decal) const { + return AABB(); +} + +/* RENDER TARGET API */ + +GLuint TextureStorage::system_fbo = 0; + +void TextureStorage::_set_current_render_target(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + + if (rt) { + if (rt->allocate_is_dirty) { + rt->allocate_is_dirty = false; + _render_target_allocate(rt); + } + + frame.current_rt = rt; + ERR_FAIL_COND(!rt); + frame.clear_request = false; + + glViewport(0, 0, rt->width, rt->height); + + _dims.rt_width = rt->width; + _dims.rt_height = rt->height; + _dims.win_width = rt->width; + _dims.win_height = rt->height; + + } else { + frame.current_rt = nullptr; + frame.clear_request = false; + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + } +} + +void TextureStorage::_render_target_allocate(RenderTarget *rt) { + Config *config = Config::get_singleton(); + + // do not allocate a render target with no size + if (rt->width <= 0 || rt->height <= 0) { + return; + } + + // do not allocate a render target that is attached to the screen + if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { + rt->fbo = system_fbo; + return; + } + + GLuint color_internal_format; + GLuint color_format; + GLuint color_type = GL_UNSIGNED_BYTE; + Image::Format image_format; + + if (rt->flags[TextureStorage::RENDER_TARGET_TRANSPARENT]) { +#ifdef GLES_OVER_GL + color_internal_format = GL_RGBA8; +#else + color_internal_format = GL_RGBA; +#endif + color_format = GL_RGBA; + image_format = Image::FORMAT_RGBA8; + } else { +#ifdef GLES_OVER_GL + color_internal_format = GL_RGB8; +#else + color_internal_format = GL_RGB; +#endif + color_format = GL_RGB; + image_format = Image::FORMAT_RGB8; + } + + rt->used_dof_blur_near = false; + rt->mip_maps_allocated = false; + + { + /* Front FBO */ + + Texture *texture = get_texture(rt->texture); + ERR_FAIL_COND(!texture); + + // framebuffer + glGenFramebuffers(1, &rt->fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo); + + // color + glGenTextures(1, &rt->color); + glBindTexture(GL_TEXTURE_2D, rt->color); + + glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, nullptr); + + if (texture->flags & TEXTURE_FLAG_FILTER) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0); + + // depth + + if (config->support_depth_texture) { + glGenTextures(1, &rt->depth); + glBindTexture(GL_TEXTURE_2D, rt->depth); + glTexImage2D(GL_TEXTURE_2D, 0, config->depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config->depth_type, nullptr); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + } else { + glGenRenderbuffers(1, &rt->depth); + glBindRenderbuffer(GL_RENDERBUFFER, rt->depth); + + glRenderbufferStorage(GL_RENDERBUFFER, config->depth_buffer_internalformat, rt->width, rt->height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + glDeleteFramebuffers(1, &rt->fbo); + if (config->support_depth_texture) { + glDeleteTextures(1, &rt->depth); + } else { + glDeleteRenderbuffers(1, &rt->depth); + } + + glDeleteTextures(1, &rt->color); + rt->fbo = 0; + rt->width = 0; + rt->height = 0; + rt->color = 0; + rt->depth = 0; + texture->tex_id = 0; + texture->active = false; + WARN_PRINT("Could not create framebuffer!!"); + return; + } + + texture->format = image_format; + texture->gl_format_cache = color_format; + texture->gl_type_cache = GL_UNSIGNED_BYTE; + texture->gl_internal_format_cache = color_internal_format; + texture->tex_id = rt->color; + texture->width = rt->width; + texture->alloc_width = rt->width; + texture->height = rt->height; + texture->alloc_height = rt->height; + texture->active = true; + + texture_set_flags(rt->texture, texture->flags); + } + + /* BACK FBO */ + /* For MSAA */ + +#ifndef JAVASCRIPT_ENABLED + if (rt->msaa >= RS::VIEWPORT_MSAA_2X && rt->msaa <= RS::VIEWPORT_MSAA_8X) { + rt->multisample_active = true; + + static const int msaa_value[] = { 0, 2, 4, 8, 16 }; + int msaa = msaa_value[rt->msaa]; + + int max_samples = 0; + glGetIntegerv(GL_MAX_SAMPLES, &max_samples); + if (msaa > max_samples) { + WARN_PRINT("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples)); + msaa = max_samples; + } + + //regular fbo + glGenFramebuffers(1, &rt->multisample_fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->multisample_fbo); + + glGenRenderbuffers(1, &rt->multisample_depth); + glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_depth); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config->depth_buffer_internalformat, rt->width, rt->height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth); + + glGenRenderbuffers(1, &rt->multisample_color); + glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_color); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height); + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + // Delete allocated resources and default to no MSAA + WARN_PRINT_ONCE("Cannot allocate back framebuffer for MSAA"); + printf("err status: %x\n", status); + rt->multisample_active = false; + + glDeleteFramebuffers(1, &rt->multisample_fbo); + rt->multisample_fbo = 0; + + glDeleteRenderbuffers(1, &rt->multisample_depth); + rt->multisample_depth = 0; + + glDeleteRenderbuffers(1, &rt->multisample_color); + rt->multisample_color = 0; + } + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + } else +#endif // JAVASCRIPT_ENABLED + { + rt->multisample_active = false; + } + + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // copy texscreen buffers + // if (!(rt->flags[TextureStorage::RENDER_TARGET_NO_SAMPLING])) { + if (true) { + glGenTextures(1, &rt->copy_screen_effect.color); + glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color); + + if (rt->flags[TextureStorage::RENDER_TARGET_TRANSPARENT]) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glGenFramebuffers(1, &rt->copy_screen_effect.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->copy_screen_effect.fbo); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->copy_screen_effect.color, 0); + + glClearColor(0, 0, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + _render_target_clear(rt); + ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); + } + } + + // Allocate mipmap chains for post_process effects + // if (!rt->flags[RendererStorage::RENDER_TARGET_NO_3D] && rt->width >= 2 && rt->height >= 2) { + if (rt->width >= 2 && rt->height >= 2) { + for (int i = 0; i < 2; i++) { + ERR_FAIL_COND(rt->mip_maps[i].sizes.size()); + int w = rt->width; + int h = rt->height; + + if (i > 0) { + w >>= 1; + h >>= 1; + } + + int level = 0; + int fb_w = w; + int fb_h = h; + + while (true) { + RenderTarget::MipMaps::Size mm; + mm.width = w; + mm.height = h; + rt->mip_maps[i].sizes.push_back(mm); + + w >>= 1; + h >>= 1; + + if (w < 2 || h < 2) { + break; + } + + level++; + } + + GLsizei width = fb_w; + GLsizei height = fb_h; + + if (config->render_to_mipmap_supported) { + glGenTextures(1, &rt->mip_maps[i].color); + glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].color); + + for (int l = 0; l < level + 1; l++) { + glTexImage2D(GL_TEXTURE_2D, l, color_internal_format, width, height, 0, color_format, color_type, nullptr); + width = MAX(1, (width / 2)); + height = MAX(1, (height / 2)); + } +#ifdef GLES_OVER_GL + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level); +#endif + } else { + // Can't render to specific levels of a mipmap in ES 2.0 or Webgl so create a texture for each level + for (int l = 0; l < level + 1; l++) { + glGenTextures(1, &rt->mip_maps[i].sizes.write[l].color); + glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[l].color); + glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, width, height, 0, color_format, color_type, nullptr); + width = MAX(1, (width / 2)); + height = MAX(1, (height / 2)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + } + + glDisable(GL_SCISSOR_TEST); + glColorMask(1, 1, 1, 1); + glDepthMask(GL_TRUE); + + for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) { + RenderTarget::MipMaps::Size &mm = rt->mip_maps[i].sizes.write[j]; + + glGenFramebuffers(1, &mm.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo); + + if (config->render_to_mipmap_supported) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].color, j); + } else { + glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color, 0); + } + + bool used_depth = false; + if (j == 0 && i == 0) { //use always + if (config->support_depth_texture) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); + } + used_depth = true; + } + + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + WARN_PRINT_ONCE("Cannot allocate mipmaps for 3D post processing effects"); + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + return; + } + + glClearColor(1.0, 0.0, 1.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + if (used_depth) { + glClearDepth(1.0); + glClear(GL_DEPTH_BUFFER_BIT); + } + } + + rt->mip_maps[i].levels = level; + + if (config->render_to_mipmap_supported) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + } + rt->mip_maps_allocated = true; + } + + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); +} + +void TextureStorage::_render_target_clear(RenderTarget *rt) { + Config *config = Config::get_singleton(); + + // there is nothing to clear when DIRECT_TO_SCREEN is used + if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { + return; + } + + if (rt->fbo) { + glDeleteFramebuffers(1, &rt->fbo); + glDeleteTextures(1, &rt->color); + rt->fbo = 0; + } + + if (rt->external.fbo != 0) { + // free this + glDeleteFramebuffers(1, &rt->external.fbo); + + // clean up our texture + Texture *t = get_texture(rt->external.texture); + t->alloc_height = 0; + t->alloc_width = 0; + t->width = 0; + t->height = 0; + t->active = false; + texture_free(rt->external.texture); + memdelete(t); + + rt->external.fbo = 0; + } + + if (rt->depth) { + if (config->support_depth_texture) { + glDeleteTextures(1, &rt->depth); + } else { + glDeleteRenderbuffers(1, &rt->depth); + } + + rt->depth = 0; + } + + Texture *tex = get_texture(rt->texture); + tex->alloc_height = 0; + tex->alloc_width = 0; + tex->width = 0; + tex->height = 0; + tex->active = false; + + if (rt->copy_screen_effect.color) { + glDeleteFramebuffers(1, &rt->copy_screen_effect.fbo); + rt->copy_screen_effect.fbo = 0; + + glDeleteTextures(1, &rt->copy_screen_effect.color); + rt->copy_screen_effect.color = 0; + } + + for (int i = 0; i < 2; i++) { + if (rt->mip_maps[i].sizes.size()) { + for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) { + glDeleteFramebuffers(1, &rt->mip_maps[i].sizes[j].fbo); + glDeleteTextures(1, &rt->mip_maps[i].sizes[j].color); + } + + glDeleteTextures(1, &rt->mip_maps[i].color); + rt->mip_maps[i].sizes.clear(); + rt->mip_maps[i].levels = 0; + rt->mip_maps[i].color = 0; + } + } + + if (rt->multisample_active) { + glDeleteFramebuffers(1, &rt->multisample_fbo); + rt->multisample_fbo = 0; + + glDeleteRenderbuffers(1, &rt->multisample_depth); + rt->multisample_depth = 0; + + glDeleteRenderbuffers(1, &rt->multisample_color); + + rt->multisample_color = 0; + } +} + +RID TextureStorage::render_target_create() { + RenderTarget *rt = memnew(RenderTarget); + Texture *t = memnew(Texture); + + t->type = RenderingDevice::TEXTURE_TYPE_2D; + t->flags = 0; + t->width = 0; + t->height = 0; + t->alloc_height = 0; + t->alloc_width = 0; + t->format = Image::FORMAT_R8; + t->target = GL_TEXTURE_2D; + t->gl_format_cache = 0; + t->gl_internal_format_cache = 0; + t->gl_type_cache = 0; + t->data_size = 0; + t->total_data_size = 0; + t->ignore_mipmaps = false; + t->compressed = false; + t->mipmaps = 1; + t->active = true; + t->tex_id = 0; + t->render_target = rt; + + rt->texture = make_rid(t); + return render_target_owner.make_rid(rt); +} + +void TextureStorage::render_target_free(RID p_rid) { + RenderTarget *rt = render_target_owner.get_or_null(p_rid); + _render_target_clear(rt); + + Texture *t = get_texture(rt->texture); + if (t) { + texture_free(rt->texture); + memdelete(t); + } + render_target_owner.free(p_rid); + memdelete(rt); +} + +void TextureStorage::render_target_set_position(RID p_render_target, int p_x, int p_y) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + rt->x = p_x; + rt->y = p_y; +} + +void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + if (p_width == rt->width && p_height == rt->height) { + return; + } + + _render_target_clear(rt); + + rt->width = p_width; + rt->height = p_height; + + // print_line("render_target_set_size " + itos(p_render_target.get_id()) + ", w " + itos(p_width) + " h " + itos(p_height)); + + rt->allocate_is_dirty = true; + //_render_target_allocate(rt); +} + +// TODO: convert to Size2i internally +Size2i TextureStorage::render_target_get_size(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, Size2()); + + return Size2i(rt->width, rt->height); +} + +RID TextureStorage::render_target_get_texture(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, RID()); + + if (rt->external.fbo == 0) { + return rt->texture; + } else { + return rt->external.texture; + } +} + +void TextureStorage::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + Config *config = Config::get_singleton(); + + if (p_texture_id == 0) { + if (rt->external.fbo != 0) { + // free this + glDeleteFramebuffers(1, &rt->external.fbo); + + // and this + if (rt->external.depth != 0) { + glDeleteRenderbuffers(1, &rt->external.depth); + } + + // clean up our texture + Texture *t = get_texture(rt->external.texture); + t->alloc_height = 0; + t->alloc_width = 0; + t->width = 0; + t->height = 0; + t->active = false; + texture_free(rt->external.texture); + memdelete(t); + + rt->external.fbo = 0; + rt->external.color = 0; + rt->external.depth = 0; + } + } else { + Texture *t; + + if (rt->external.fbo == 0) { + // create our fbo + glGenFramebuffers(1, &rt->external.fbo); + glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo); + + // allocate a texture + t = memnew(Texture); + + t->type = RenderingDevice::TEXTURE_TYPE_2D; + t->flags = 0; + t->width = 0; + t->height = 0; + t->alloc_height = 0; + t->alloc_width = 0; + t->format = Image::FORMAT_RGBA8; + t->target = GL_TEXTURE_2D; + t->gl_format_cache = 0; + t->gl_internal_format_cache = 0; + t->gl_type_cache = 0; + t->data_size = 0; + t->compressed = false; + t->srgb = false; + t->total_data_size = 0; + t->ignore_mipmaps = false; + t->mipmaps = 1; + t->active = true; + t->tex_id = 0; + t->render_target = rt; + + rt->external.texture = make_rid(t); + + } else { + // bind our frame buffer + glBindFramebuffer(GL_FRAMEBUFFER, rt->external.fbo); + + // find our texture + t = get_texture(rt->external.texture); + } + + // set our texture + t->tex_id = p_texture_id; + rt->external.color = p_texture_id; + + // size shouldn't be different + t->width = rt->width; + t->height = rt->height; + t->alloc_height = rt->width; + t->alloc_width = rt->height; + + // Switch our texture on our frame buffer + { + // set our texture as the destination for our framebuffer + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_texture_id, 0); + + // seeing we're rendering into this directly, better also use our depth buffer, just use our existing one :) + if (config->support_depth_texture) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0); + } else { + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth); + } + } + + // check status and unbind + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo); + + if (status != GL_FRAMEBUFFER_COMPLETE) { + printf("framebuffer fail, status: %x\n", status); + } + + ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE); + } +} + +void TextureStorage::render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + // When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as + // those functions change how they operate depending on the value of DIRECT_TO_SCREEN + if (p_flag == RENDER_TARGET_DIRECT_TO_SCREEN && p_value != rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN]) { + _render_target_clear(rt); + rt->flags[p_flag] = p_value; + _render_target_allocate(rt); + } + + rt->flags[p_flag] = p_value; + + switch (p_flag) { + case RENDER_TARGET_TRANSPARENT: + /* + case RENDER_TARGET_HDR: + case RENDER_TARGET_NO_3D: + case RENDER_TARGET_NO_SAMPLING: + case RENDER_TARGET_NO_3D_EFFECTS: */ + { + //must reset for these formats + _render_target_clear(rt); + _render_target_allocate(rt); + } + break; + default: { + } + } +} + +bool TextureStorage::render_target_was_used(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, false); + + return rt->used_in_frame; +} + +void TextureStorage::render_target_clear_used(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + rt->used_in_frame = false; +} + +void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + if (rt->msaa == p_msaa) { + return; + } + + _render_target_clear(rt); + rt->msaa = p_msaa; + _render_target_allocate(rt); +} + +void TextureStorage::render_target_set_use_fxaa(RID p_render_target, bool p_fxaa) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + rt->use_fxaa = p_fxaa; +} + +void TextureStorage::render_target_set_use_debanding(RID p_render_target, bool p_debanding) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + + if (p_debanding) { + WARN_PRINT_ONCE("Debanding is not supported in the OpenGL backend. Switch to the Vulkan backend and make sure HDR is enabled."); + } + + rt->use_debanding = p_debanding; +} + +void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + rt->clear_requested = true; + rt->clear_color = p_clear_color; + + // ERR_FAIL_COND(!frame.current_rt); + // frame.clear_request = true; + // frame.clear_request_color = p_color; +} + +bool TextureStorage::render_target_is_clear_requested(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, false); + return rt->clear_requested; +} +Color TextureStorage::render_target_get_clear_request_color(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND_V(!rt, Color()); + return rt->clear_color; +} + +void TextureStorage::render_target_disable_clear_request(RID p_render_target) { + RenderTarget *rt = render_target_owner.get_or_null(p_render_target); + ERR_FAIL_COND(!rt); + rt->clear_requested = false; +} + +void TextureStorage::render_target_do_clear_request(RID p_render_target) { +} + +void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) { +} + +Rect2i TextureStorage::render_target_get_sdf_rect(RID p_render_target) const { + return Rect2i(); +} + +void TextureStorage::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) { +} + #endif // GLES3_ENABLED diff --git a/drivers/gles3/storage/texture_storage.h b/drivers/gles3/storage/texture_storage.h index 7656cdf67e..7a5140a290 100644 --- a/drivers/gles3/storage/texture_storage.h +++ b/drivers/gles3/storage/texture_storage.h @@ -33,13 +33,20 @@ #ifdef GLES3_ENABLED -#include "canvas_texture_storage.h" #include "config.h" #include "core/os/os.h" #include "core/templates/rid_owner.h" -#include "render_target_storage.h" +#include "servers/rendering/renderer_compositor.h" #include "servers/rendering/storage/texture_storage.h" +// This must come first to avoid windows.h mess +#include "platform_config.h" +#ifndef OPENGL_INCLUDE_H +#include <GLES3/gl3.h> +#else +#include OPENGL_INCLUDE_H +#endif + namespace GLES3 { #define _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 @@ -90,6 +97,24 @@ enum OpenGLTextureFlags { TEXTURE_FLAGS_DEFAULT = TEXTURE_FLAG_REPEAT | TEXTURE_FLAG_MIPMAPS | TEXTURE_FLAG_FILTER }; +struct CanvasTexture { + RID diffuse; + RID normal_map; + RID specular; + Color specular_color = Color(1, 1, 1, 1); + float shininess = 1.0; + + RS::CanvasItemTextureFilter texture_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT; + RS::CanvasItemTextureRepeat texture_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT; + + Size2i size_cache = Size2i(1, 1); + bool use_normal_cache = false; + bool use_specular_cache = false; + bool cleared_cache = true; +}; + +struct RenderTarget; + struct Texture { RID self; @@ -296,6 +321,81 @@ private: RS::CanvasItemTextureRepeat state_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; }; +struct RenderTarget { + RID self; + GLuint fbo = 0; + GLuint color = 0; + GLuint depth = 0; + + GLuint multisample_fbo = 0; + GLuint multisample_color = 0; + GLuint multisample_depth = 0; + bool multisample_active = false; + + struct Effect { + GLuint fbo = 0; + int width = 0; + int height = 0; + + GLuint color = 0; + }; + + Effect copy_screen_effect; + + struct MipMaps { + struct Size { + GLuint fbo = 0; + GLuint color = 0; + int width = 0; + int height = 0; + }; + + Vector<Size> sizes; + GLuint color = 0; + int levels = 0; + }; + + MipMaps mip_maps[2]; + + struct External { + GLuint fbo = 0; + GLuint color = 0; + GLuint depth = 0; + RID texture; + } external; + + int x = 0; + int y = 0; + int width = 0; + int height = 0; + + bool flags[RendererTextureStorage::RENDER_TARGET_FLAG_MAX] = {}; + + // instead of allocating sized render targets immediately, + // defer this for faster startup + bool allocate_is_dirty = false; + bool used_in_frame = false; + RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED; + + bool use_fxaa = false; + bool use_debanding = false; + + RID texture; + + bool used_dof_blur_near = false; + bool mip_maps_allocated = false; + + Color clear_color = Color(1, 1, 1, 1); + bool clear_requested = false; + + RenderTarget() { + for (int i = 0; i < RendererTextureStorage::RENDER_TARGET_FLAG_MAX; ++i) { + flags[i] = false; + } + external.fbo = 0; + } +}; + class TextureStorage : public RendererTextureStorage { private: static TextureStorage *singleton; @@ -303,6 +403,12 @@ private: Thread::ID _main_thread_id = 0; bool _is_main_thread(); + /* Canvas Texture API */ + + RID_Owner<CanvasTexture, true> canvas_texture_owner; + + /* Texture API */ + mutable RID_PtrOwner<Texture> texture_owner; Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const; @@ -310,12 +416,50 @@ private: void texture_set_proxy(RID p_texture, RID p_proxy); + /* Render Target API */ + + mutable RID_PtrOwner<RenderTarget> render_target_owner; + + // make access easier to these + struct Dimensions { + // render target + int rt_width; + int rt_height; + + // window + int win_width; + int win_height; + Dimensions() { + rt_width = 0; + rt_height = 0; + win_width = 0; + win_height = 0; + } + } _dims; + public: static TextureStorage *get_singleton(); TextureStorage(); virtual ~TextureStorage(); + /* Canvas Texture API */ + + CanvasTexture *get_canvas_texture(RID p_rid) { return canvas_texture_owner.get_or_null(p_rid); }; + bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); }; + + virtual RID canvas_texture_allocate() override; + virtual void canvas_texture_initialize(RID p_rid) override; + virtual void canvas_texture_free(RID p_rid) override; + + virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) override; + virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) override; + + virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) override; + virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) override; + + /* Texture API */ + Texture *get_texture(RID p_rid) { return texture_owner.get_or_null(p_rid); }; bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); }; RID make_rid(Texture *p_texture) { return texture_owner.make_rid(p_texture); }; @@ -380,6 +524,86 @@ public: void texture_set_shrink_all_x2_on_set_data(bool p_enable); RID texture_create_radiance_cubemap(RID p_source, int p_resolution = -1) const; void textures_keep_original(bool p_enable); + + /* DECAL API */ + + 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 {} + + /* RENDER TARGET API */ + + static GLuint system_fbo; + + struct Frame { + GLES3::RenderTarget *current_rt; + + // these 2 may have been superseded by the equivalents in the render target. + // these may be able to be removed. + bool clear_request; + Color clear_request_color; + + float time; + float delta; + uint64_t count; + + Frame() { + // current_rt = nullptr; + // clear_request = false; + } + } frame; + + RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); }; + bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); }; + + void _render_target_clear(RenderTarget *rt); + void _render_target_allocate(RenderTarget *rt); + void _set_current_render_target(RID p_render_target); + + virtual RID render_target_create() override; + virtual void render_target_free(RID p_rid) override; + virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) override; + virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) override; + Size2i render_target_get_size(RID p_render_target); + virtual RID render_target_get_texture(RID p_render_target) override; + virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) override; + + virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) override; + virtual bool render_target_was_used(RID p_render_target) override; + void render_target_clear_used(RID p_render_target); + void render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa); + void render_target_set_use_fxaa(RID p_render_target, bool p_fxaa); + void render_target_set_use_debanding(RID p_render_target, bool p_debanding); + + // new + void render_target_set_as_unused(RID p_render_target) override { + render_target_clear_used(p_render_target); + } + + void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override; + bool render_target_is_clear_requested(RID p_render_target) override; + Color render_target_get_clear_request_color(RID p_render_target) override; + void render_target_disable_clear_request(RID p_render_target) override; + void render_target_do_clear_request(RID p_render_target) override; + + void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override; + Rect2i render_target_get_sdf_rect(RID p_render_target) const override; + void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override; }; } // namespace GLES3 |