summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp46
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h1
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp21
-rw-r--r--drivers/gles3/rasterizer_gles3.h7
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp851
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h84
-rw-r--r--drivers/gles3/storage/canvas_texture_storage.cpp96
-rw-r--r--drivers/gles3/storage/canvas_texture_storage.h87
-rw-r--r--drivers/gles3/storage/config.cpp4
-rw-r--r--drivers/gles3/storage/decal_atlas_storage.cpp75
-rw-r--r--drivers/gles3/storage/decal_atlas_storage.h67
-rw-r--r--drivers/gles3/storage/render_target_storage.h132
-rw-r--r--drivers/gles3/storage/texture_storage.cpp932
-rw-r--r--drivers/gles3/storage/texture_storage.h228
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