Merge canvas and decal into TextureStorage and add render target
This commit is contained in:
parent
f7ca732df1
commit
6b28d94e77
49 changed files with 3143 additions and 3696 deletions
|
@ -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();
|
||||
|
||||
storage->_set_current_render_target(p_to_render_target);
|
||||
texture_storage->frame.current_rt = nullptr;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "../openxr_api.h"
|
||||
#include "../openxr_util.h"
|
||||
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/rendering_server_globals.h"
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
|
@ -439,7 +440,7 @@ bool OpenXRVulkanExtension::copy_render_target_to_image(RID p_from_render_target
|
|||
ERR_FAIL_COND_V(p_from_render_target.is_null(), false);
|
||||
ERR_FAIL_NULL_V(RendererStorageRD::base_singleton, false);
|
||||
|
||||
RID source_image = RendererStorageRD::base_singleton->render_target_get_rd_texture(p_from_render_target);
|
||||
RID source_image = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(p_from_render_target);
|
||||
ERR_FAIL_COND_V(source_image.is_null(), false);
|
||||
|
||||
RID depth_image; // TODO implement
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
#include "servers/rendering/dummy/rasterizer_canvas_dummy.h"
|
||||
#include "servers/rendering/dummy/rasterizer_scene_dummy.h"
|
||||
#include "servers/rendering/dummy/rasterizer_storage_dummy.h"
|
||||
#include "servers/rendering/dummy/storage/canvas_texture_storage.h"
|
||||
#include "servers/rendering/dummy/storage/decal_atlas_storage.h"
|
||||
#include "servers/rendering/dummy/storage/material_storage.h"
|
||||
#include "servers/rendering/dummy/storage/mesh_storage.h"
|
||||
#include "servers/rendering/dummy/storage/texture_storage.h"
|
||||
|
@ -52,20 +50,16 @@ private:
|
|||
|
||||
protected:
|
||||
RasterizerCanvasDummy canvas;
|
||||
RendererDummy::CanvasTextureStorage canvas_texture_storage;
|
||||
RendererDummy::MaterialStorage material_storage;
|
||||
RendererDummy::MeshStorage mesh_storage;
|
||||
RendererDummy::TextureStorage texture_storage;
|
||||
RendererDummy::DecalAtlasStorage decal_atlas_storage;
|
||||
RasterizerStorageDummy storage;
|
||||
RasterizerSceneDummy scene;
|
||||
|
||||
public:
|
||||
RendererCanvasTextureStorage *get_canvas_texture_storage() override { return &canvas_texture_storage; };
|
||||
RendererMaterialStorage *get_material_storage() override { return &material_storage; };
|
||||
RendererMeshStorage *get_mesh_storage() override { return &mesh_storage; };
|
||||
RendererTextureStorage *get_texture_storage() override { return &texture_storage; };
|
||||
RendererDecalAtlasStorage *get_decal_atlas_storage() override { return &decal_atlas_storage; };
|
||||
RendererStorage *get_storage() override { return &storage; }
|
||||
RendererCanvasRender *get_canvas() override { return &canvas; }
|
||||
RendererSceneRender *get_scene() override { return &scene; }
|
||||
|
|
|
@ -268,26 +268,7 @@ public:
|
|||
virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override { return AABB(); }
|
||||
virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override {}
|
||||
|
||||
/* RENDER TARGET */
|
||||
|
||||
RID render_target_create() override { return RID(); }
|
||||
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 {}
|
||||
RID render_target_get_texture(RID p_render_target) override { return RID(); }
|
||||
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 { return false; }
|
||||
void render_target_set_as_unused(RID p_render_target) override {}
|
||||
|
||||
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 { return false; }
|
||||
Color render_target_get_clear_request_color(RID p_render_target) override { return Color(); }
|
||||
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 { return Rect2i(); }
|
||||
void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override {}
|
||||
/* STORAGE */
|
||||
|
||||
RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; }
|
||||
bool free(RID p_rid) override {
|
||||
|
|
|
@ -1,53 +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_DUMMY_H
|
||||
#define CANVAS_TEXTURE_STORAGE_DUMMY_H
|
||||
|
||||
#include "servers/rendering/storage/canvas_texture_storage.h"
|
||||
|
||||
namespace RendererDummy {
|
||||
|
||||
class CanvasTextureStorage : public RendererCanvasTextureStorage {
|
||||
public:
|
||||
virtual RID canvas_texture_allocate() override { return RID(); };
|
||||
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 RendererDummy
|
||||
|
||||
#endif // !CANVAS_TEXTURE_STORAGE_DUMMY_H
|
|
@ -1,62 +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_DUMMY_H
|
||||
#define DECAL_ATLAS_STORAGE_DUMMY_H
|
||||
|
||||
#include "servers/rendering/storage/decal_atlas_storage.h"
|
||||
|
||||
namespace RendererDummy {
|
||||
|
||||
class DecalAtlasStorage : public RendererDecalAtlasStorage {
|
||||
public:
|
||||
virtual RID decal_allocate() override { return RID(); }
|
||||
virtual void decal_initialize(RID p_rid) override {}
|
||||
virtual void decal_free(RID p_rid) override{};
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override {}
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override {}
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override {}
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override {}
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override {}
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override {}
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
};
|
||||
|
||||
} // namespace RendererDummy
|
||||
|
||||
#endif // !DECAL_ATLAS_STORAGE_DUMMY_H
|
|
@ -52,6 +52,20 @@ public:
|
|||
|
||||
virtual bool can_create_resources_async() const override { return false; }
|
||||
|
||||
/* Canvas Texture API */
|
||||
|
||||
virtual RID canvas_texture_allocate() override { return RID(); };
|
||||
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 */
|
||||
|
||||
DummyTexture *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); };
|
||||
|
||||
|
@ -109,6 +123,48 @@ public:
|
|||
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) override{};
|
||||
|
||||
virtual Size2 texture_size_with_proxy(RID p_proxy) override { return Size2(); };
|
||||
|
||||
/* DECAL API */
|
||||
virtual RID decal_allocate() override { return RID(); }
|
||||
virtual void decal_initialize(RID p_rid) override {}
|
||||
virtual void decal_free(RID p_rid) override{};
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override {}
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override {}
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override {}
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override {}
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override {}
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override {}
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override {}
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override {}
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override {}
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const override { return AABB(); }
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
|
||||
/* RENDER TARGET */
|
||||
|
||||
virtual RID render_target_create() override { return RID(); }
|
||||
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 {}
|
||||
virtual RID render_target_get_texture(RID p_render_target) override { return RID(); }
|
||||
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 { return false; }
|
||||
virtual void render_target_set_as_unused(RID p_render_target) override {}
|
||||
|
||||
virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override {}
|
||||
virtual bool render_target_is_clear_requested(RID p_render_target) override { return false; }
|
||||
virtual Color render_target_get_clear_request_color(RID p_render_target) override { return Color(); }
|
||||
virtual void render_target_disable_clear_request(RID p_render_target) override {}
|
||||
virtual void render_target_do_clear_request(RID p_render_target) override {}
|
||||
|
||||
virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override {}
|
||||
virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const override { return Rect2i(); }
|
||||
virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override {}
|
||||
};
|
||||
|
||||
} // namespace RendererDummy
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "renderer_viewport.h"
|
||||
#include "rendering_server_default.h"
|
||||
#include "rendering_server_globals.h"
|
||||
#include "servers/rendering/storage/canvas_texture_storage.h"
|
||||
#include "servers/rendering/storage/texture_storage.h"
|
||||
|
||||
static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
|
||||
|
||||
|
@ -1851,26 +1851,26 @@ void RendererCanvasCull::canvas_set_shadow_texture_size(int p_size) {
|
|||
}
|
||||
|
||||
RID RendererCanvasCull::canvas_texture_allocate() {
|
||||
return RSG::canvas_texture_storage->canvas_texture_allocate();
|
||||
return RSG::texture_storage->canvas_texture_allocate();
|
||||
}
|
||||
void RendererCanvasCull::canvas_texture_initialize(RID p_rid) {
|
||||
RSG::canvas_texture_storage->canvas_texture_initialize(p_rid);
|
||||
RSG::texture_storage->canvas_texture_initialize(p_rid);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
|
||||
RSG::canvas_texture_storage->canvas_texture_set_channel(p_canvas_texture, p_channel, p_texture);
|
||||
RSG::texture_storage->canvas_texture_set_channel(p_canvas_texture, p_channel, p_texture);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) {
|
||||
RSG::canvas_texture_storage->canvas_texture_set_shading_parameters(p_canvas_texture, p_base_color, p_shininess);
|
||||
RSG::texture_storage->canvas_texture_set_shading_parameters(p_canvas_texture, p_base_color, p_shininess);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
|
||||
RSG::canvas_texture_storage->canvas_texture_set_texture_filter(p_canvas_texture, p_filter);
|
||||
RSG::texture_storage->canvas_texture_set_texture_filter(p_canvas_texture, p_filter);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
|
||||
RSG::canvas_texture_storage->canvas_texture_set_texture_repeat(p_canvas_texture, p_repeat);
|
||||
RSG::texture_storage->canvas_texture_set_texture_repeat(p_canvas_texture, p_repeat);
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) {
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "servers/rendering/renderer_canvas_render.h"
|
||||
#include "servers/rendering/renderer_scene.h"
|
||||
#include "servers/rendering/renderer_storage.h"
|
||||
#include "servers/rendering/storage/canvas_texture_storage.h"
|
||||
#include "servers/rendering/storage/decal_atlas_storage.h"
|
||||
#include "servers/rendering/storage/material_storage.h"
|
||||
#include "servers/rendering/storage/mesh_storage.h"
|
||||
#include "servers/rendering/storage/texture_storage.h"
|
||||
|
@ -75,11 +73,9 @@ protected:
|
|||
public:
|
||||
static RendererCompositor *create();
|
||||
|
||||
virtual RendererCanvasTextureStorage *get_canvas_texture_storage() = 0;
|
||||
virtual RendererMaterialStorage *get_material_storage() = 0;
|
||||
virtual RendererMeshStorage *get_mesh_storage() = 0;
|
||||
virtual RendererTextureStorage *get_texture_storage() = 0;
|
||||
virtual RendererDecalAtlasStorage *get_decal_atlas_storage() = 0;
|
||||
virtual RendererStorage *get_storage() = 0;
|
||||
virtual RendererCanvasRender *get_canvas() = 0;
|
||||
virtual RendererSceneRender *get_scene() = 0;
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
#include "render_forward_clustered.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
|
@ -2167,7 +2167,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
|
|||
RD::Uniform u;
|
||||
u.binding = 11;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
|
||||
RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture();
|
||||
u.append_id(decal_atlas);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
@ -2175,7 +2175,7 @@ void RenderForwardClustered::_update_render_base_uniform_set() {
|
|||
RD::Uniform u;
|
||||
u.binding = 12;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_srgb();
|
||||
RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_srgb();
|
||||
u.append_id(decal_atlas);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
#include "render_forward_mobile.h"
|
||||
#include "core/config/project_settings.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
|
||||
|
@ -1279,7 +1279,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
|||
RD::Uniform u;
|
||||
u.binding = 11;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
|
||||
RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture();
|
||||
u.append_id(decal_atlas);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
@ -1287,7 +1287,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
|||
RD::Uniform u;
|
||||
u.binding = 12;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_srgb();
|
||||
RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_srgb();
|
||||
u.append_id(decal_atlas);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
#include "core/math/math_defs.h"
|
||||
#include "core/math/math_funcs.h"
|
||||
#include "renderer_compositor_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
|
@ -364,7 +362,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI
|
|||
bool use_normal;
|
||||
bool use_specular;
|
||||
|
||||
bool success = RendererRD::CanvasTextureStorage::get_singleton()->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular);
|
||||
bool success = RendererRD::TextureStorage::get_singleton()->canvas_texture_get_uniform_set(p_texture, p_base_filter, p_base_repeat, shader.default_version_rd_shader, CANVAS_TEXTURE_UNIFORM_SET, uniform_set, size, specular_shininess, use_normal, use_specular);
|
||||
//something odd happened
|
||||
if (!success) {
|
||||
_bind_canvas_texture(p_draw_list, default_canvas_texture, p_base_filter, p_base_repeat, r_last_texture, push_constant, r_texpixel_size);
|
||||
|
@ -401,6 +399,7 @@ void RendererCanvasRenderRD::_bind_canvas_texture(RD::DrawListID p_draw_list, RI
|
|||
|
||||
void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_render_target, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *¤t_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) {
|
||||
//create an empty push constant
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
|
||||
|
||||
RS::CanvasItemTextureFilter current_filter = default_filter;
|
||||
|
@ -809,7 +808,7 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
|||
mesh = storage->particles_get_draw_pass_mesh(pt->particles, 0); //higher ones are ignored
|
||||
texture = pt->texture;
|
||||
|
||||
if (storage->particles_has_collision(pt->particles) && storage->render_target_is_sdf_enabled(p_render_target)) {
|
||||
if (storage->particles_has_collision(pt->particles) && texture_storage->render_target_is_sdf_enabled(p_render_target)) {
|
||||
//pass collision information
|
||||
Transform2D xform;
|
||||
if (local_coords) {
|
||||
|
@ -818,11 +817,11 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
|||
xform = p_canvas_transform_inverse;
|
||||
}
|
||||
|
||||
RID sdf_texture = storage->render_target_get_sdf_texture(p_render_target);
|
||||
RID sdf_texture = texture_storage->render_target_get_sdf_texture(p_render_target);
|
||||
|
||||
Rect2 to_screen;
|
||||
{
|
||||
Rect2 sdf_rect = storage->render_target_get_sdf_rect(p_render_target);
|
||||
Rect2 sdf_rect = texture_storage->render_target_get_sdf_rect(p_render_target);
|
||||
|
||||
to_screen.size = Vector2(1.0 / sdf_rect.size.width, 1.0 / sdf_rect.size.height);
|
||||
to_screen.position = -sdf_rect.position * to_screen.size;
|
||||
|
@ -931,6 +930,8 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
|||
}
|
||||
|
||||
RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, bool p_backbuffer) {
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
|
||||
//re create canvas state
|
||||
Vector<RD::Uniform> uniforms;
|
||||
|
||||
|
@ -954,7 +955,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
|
|||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.binding = 3;
|
||||
u.append_id(RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture());
|
||||
u.append_id(RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
|
@ -980,9 +981,9 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
|
|||
u.binding = 6;
|
||||
RID screen;
|
||||
if (p_backbuffer) {
|
||||
screen = storage->render_target_get_rd_texture(p_to_render_target);
|
||||
screen = texture_storage->render_target_get_rd_texture(p_to_render_target);
|
||||
} else {
|
||||
screen = storage->render_target_get_rd_backbuffer(p_to_render_target);
|
||||
screen = texture_storage->render_target_get_rd_backbuffer(p_to_render_target);
|
||||
if (screen.is_null()) { //unallocated backbuffer
|
||||
screen = RendererRD::TextureStorage::get_singleton()->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_WHITE);
|
||||
}
|
||||
|
@ -995,7 +996,7 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
|
|||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.binding = 7;
|
||||
RID sdf = storage->render_target_get_sdf_texture(p_to_render_target);
|
||||
RID sdf = texture_storage->render_target_get_sdf_texture(p_to_render_target);
|
||||
u.append_id(sdf);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
@ -1033,9 +1034,9 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
|
|||
|
||||
RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, BASE_UNIFORM_SET);
|
||||
if (p_backbuffer) {
|
||||
storage->render_target_set_backbuffer_uniform_set(p_to_render_target, uniform_set);
|
||||
texture_storage->render_target_set_backbuffer_uniform_set(p_to_render_target, uniform_set);
|
||||
} else {
|
||||
storage->render_target_set_framebuffer_uniform_set(p_to_render_target, uniform_set);
|
||||
texture_storage->render_target_set_framebuffer_uniform_set(p_to_render_target, uniform_set);
|
||||
}
|
||||
|
||||
return uniform_set;
|
||||
|
@ -1043,6 +1044,8 @@ RID RendererCanvasRenderRD::_create_base_uniform_set(RID p_to_render_target, boo
|
|||
|
||||
void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool p_to_backbuffer) {
|
||||
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
|
||||
Item *current_clip = nullptr;
|
||||
|
||||
Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
|
||||
|
@ -1053,21 +1056,21 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
|
|||
Vector<Color> clear_colors;
|
||||
|
||||
if (p_to_backbuffer) {
|
||||
framebuffer = storage->render_target_get_rd_backbuffer_framebuffer(p_to_render_target);
|
||||
fb_uniform_set = storage->render_target_get_backbuffer_uniform_set(p_to_render_target);
|
||||
framebuffer = texture_storage->render_target_get_rd_backbuffer_framebuffer(p_to_render_target);
|
||||
fb_uniform_set = texture_storage->render_target_get_backbuffer_uniform_set(p_to_render_target);
|
||||
} else {
|
||||
framebuffer = storage->render_target_get_rd_framebuffer(p_to_render_target);
|
||||
framebuffer = texture_storage->render_target_get_rd_framebuffer(p_to_render_target);
|
||||
|
||||
if (storage->render_target_is_clear_requested(p_to_render_target)) {
|
||||
if (texture_storage->render_target_is_clear_requested(p_to_render_target)) {
|
||||
clear = true;
|
||||
clear_colors.push_back(storage->render_target_get_clear_request_color(p_to_render_target));
|
||||
storage->render_target_disable_clear_request(p_to_render_target);
|
||||
clear_colors.push_back(texture_storage->render_target_get_clear_request_color(p_to_render_target));
|
||||
texture_storage->render_target_disable_clear_request(p_to_render_target);
|
||||
}
|
||||
#ifndef _MSC_VER
|
||||
#warning TODO obtain from framebuffer format eventually when this is implemented
|
||||
#endif
|
||||
|
||||
fb_uniform_set = storage->render_target_get_framebuffer_uniform_set(p_to_render_target);
|
||||
fb_uniform_set = texture_storage->render_target_get_framebuffer_uniform_set(p_to_render_target);
|
||||
}
|
||||
|
||||
if (fb_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(fb_uniform_set)) {
|
||||
|
@ -1136,6 +1139,7 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co
|
|||
}
|
||||
|
||||
void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RenderingServer::CanvasItemTextureFilter p_default_filter, RenderingServer::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used) {
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
||||
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
|
||||
|
||||
|
@ -1264,7 +1268,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
|
|||
}
|
||||
|
||||
if (clight->texture.is_valid()) {
|
||||
Rect2 atlas_rect = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture_rect(clight->texture);
|
||||
Rect2 atlas_rect = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture_rect(clight->texture);
|
||||
state.light_uniforms[index].atlas_rect[0] = atlas_rect.position.x;
|
||||
state.light_uniforms[index].atlas_rect[1] = atlas_rect.position.y;
|
||||
state.light_uniforms[index].atlas_rect[2] = atlas_rect.size.width;
|
||||
|
@ -1294,7 +1298,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
|
|||
//update canvas state uniform buffer
|
||||
State::Buffer 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);
|
||||
|
@ -1313,7 +1317,7 @@ void RendererCanvasRenderRD::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;
|
||||
|
||||
|
@ -1330,7 +1334,7 @@ void RendererCanvasRenderRD::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;
|
||||
|
@ -1420,9 +1424,9 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
|
|||
Rect2i group_rect = ci->canvas_group_owner->global_rect_cache;
|
||||
|
||||
if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_OPAQUE) {
|
||||
storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false);
|
||||
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false);
|
||||
} else {
|
||||
storage->render_target_clear_back_buffer(p_to_render_target, group_rect, Color(0, 0, 0, 0));
|
||||
texture_storage->render_target_clear_back_buffer(p_to_render_target, group_rect, Color(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
backbuffer_copy = false;
|
||||
|
@ -1442,7 +1446,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
|
|||
item_count = 0;
|
||||
|
||||
if (ci->canvas_group->blur_mipmaps) {
|
||||
storage->render_target_gen_back_buffer_mipmaps(p_to_render_target, ci->global_rect_cache);
|
||||
texture_storage->render_target_gen_back_buffer_mipmaps(p_to_render_target, ci->global_rect_cache);
|
||||
}
|
||||
|
||||
canvas_group_owner = nullptr;
|
||||
|
@ -1457,7 +1461,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p
|
|||
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list);
|
||||
item_count = 0;
|
||||
|
||||
storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, true);
|
||||
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, true);
|
||||
|
||||
backbuffer_copy = false;
|
||||
material_screen_texture_found = true; //after a backbuffer copy, screen texture makes no further copies
|
||||
|
@ -1490,7 +1494,7 @@ RID RendererCanvasRenderRD::light_create() {
|
|||
}
|
||||
|
||||
void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) {
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
|
||||
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
|
||||
ERR_FAIL_COND(!cl);
|
||||
|
@ -1498,12 +1502,12 @@ void RendererCanvasRenderRD::light_set_texture(RID p_rid, RID p_texture) {
|
|||
return;
|
||||
}
|
||||
if (cl->texture.is_valid()) {
|
||||
decal_atlas_storage->texture_remove_from_decal_atlas(cl->texture);
|
||||
texture_storage->texture_remove_from_decal_atlas(cl->texture);
|
||||
}
|
||||
cl->texture = p_texture;
|
||||
|
||||
if (cl->texture.is_valid()) {
|
||||
decal_atlas_storage->texture_add_to_decal_atlas(cl->texture);
|
||||
texture_storage->texture_add_to_decal_atlas(cl->texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1703,8 +1707,10 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh
|
|||
}
|
||||
|
||||
void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) {
|
||||
RID fb = storage->render_target_get_sdf_framebuffer(p_render_target);
|
||||
Rect2i rect = storage->render_target_get_sdf_rect(p_render_target);
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
|
||||
RID fb = texture_storage->render_target_get_sdf_framebuffer(p_render_target);
|
||||
Rect2i rect = texture_storage->render_target_get_sdf_rect(p_render_target);
|
||||
|
||||
Transform2D to_sdf;
|
||||
to_sdf.elements[0] *= rect.size.width;
|
||||
|
@ -1761,7 +1767,7 @@ void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstan
|
|||
|
||||
RD::get_singleton()->draw_list_end();
|
||||
|
||||
storage->render_target_sdf_process(p_render_target); //done rendering, process it
|
||||
texture_storage->render_target_sdf_process(p_render_target); //done rendering, process it
|
||||
}
|
||||
|
||||
RID RendererCanvasRenderRD::occluder_polygon_create() {
|
||||
|
@ -2258,7 +2264,7 @@ void RendererCanvasRenderRD::update() {
|
|||
}
|
||||
|
||||
RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
|
||||
RendererRD::CanvasTextureStorage *canvas_texture_storage = RendererRD::CanvasTextureStorage::get_singleton();
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
||||
storage = p_storage;
|
||||
|
||||
|
@ -2590,8 +2596,8 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
|
|||
state.default_transforms_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.default_version_rd_shader, TRANSFORMS_UNIFORM_SET);
|
||||
}
|
||||
|
||||
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.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size");
|
||||
|
||||
|
@ -2712,6 +2718,6 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() {
|
|||
}
|
||||
RD::get_singleton()->free(state.shadow_texture);
|
||||
|
||||
RendererRD::CanvasTextureStorage::get_singleton()->canvas_texture_free(default_canvas_texture);
|
||||
RendererRD::TextureStorage::get_singleton()->canvas_texture_free(default_canvas_texture);
|
||||
//pipelines don't need freeing, they are all gone after shaders are gone
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ void RendererCompositorRD::blit_render_targets_to_screen(DisplayServer::WindowID
|
|||
}
|
||||
|
||||
for (int i = 0; i < p_amount; i++) {
|
||||
RID texture = storage->render_target_get_texture(p_render_targets[i].render_target);
|
||||
RID texture = texture_storage->render_target_get_texture(p_render_targets[i].render_target);
|
||||
ERR_CONTINUE(texture.is_null());
|
||||
RID rd_texture = texture_storage->texture_get_rd_texture(texture);
|
||||
ERR_CONTINUE(rd_texture.is_null());
|
||||
|
@ -155,11 +155,9 @@ void RendererCompositorRD::finalize() {
|
|||
memdelete(scene);
|
||||
memdelete(canvas);
|
||||
memdelete(storage);
|
||||
memdelete(decal_atlas_storage);
|
||||
memdelete(mesh_storage);
|
||||
memdelete(material_storage);
|
||||
memdelete(texture_storage);
|
||||
memdelete(canvas_texture_storage);
|
||||
|
||||
//only need to erase these, the rest are erased by cascade
|
||||
blit.shader.version_free(blit.shader_version);
|
||||
|
@ -288,9 +286,7 @@ RendererCompositorRD::RendererCompositorRD() {
|
|||
singleton = this;
|
||||
time = 0;
|
||||
|
||||
canvas_texture_storage = memnew(RendererRD::CanvasTextureStorage);
|
||||
texture_storage = memnew(RendererRD::TextureStorage);
|
||||
decal_atlas_storage = memnew(RendererRD::DecalAtlasStorage);
|
||||
material_storage = memnew(RendererRD::MaterialStorage);
|
||||
mesh_storage = memnew(RendererRD::MeshStorage);
|
||||
storage = memnew(RendererStorageRD);
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
#include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h"
|
||||
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
|
@ -50,11 +48,9 @@ class RendererCompositorRD : public RendererCompositor {
|
|||
protected:
|
||||
UniformSetCacheRD *uniform_set_cache = nullptr;
|
||||
RendererCanvasRenderRD *canvas = nullptr;
|
||||
RendererRD::CanvasTextureStorage *canvas_texture_storage;
|
||||
RendererRD::MaterialStorage *material_storage;
|
||||
RendererRD::MeshStorage *mesh_storage;
|
||||
RendererRD::TextureStorage *texture_storage;
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage;
|
||||
RendererStorageRD *storage = nullptr;
|
||||
RendererSceneRenderRD *scene = nullptr;
|
||||
|
||||
|
@ -98,8 +94,6 @@ protected:
|
|||
static uint64_t frame;
|
||||
|
||||
public:
|
||||
RendererCanvasTextureStorage *get_canvas_texture_storage() { return canvas_texture_storage; }
|
||||
RendererDecalAtlasStorage *get_decal_atlas_storage() { return decal_atlas_storage; }
|
||||
RendererMaterialStorage *get_material_storage() { return material_storage; };
|
||||
RendererMeshStorage *get_mesh_storage() { return mesh_storage; };
|
||||
RendererTextureStorage *get_texture_storage() { return texture_storage; };
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "core/config/project_settings.h"
|
||||
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
|
||||
const Vector3i RendererSceneGIRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
|
||||
|
@ -1245,8 +1246,8 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons
|
|||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1);
|
||||
RD::get_singleton()->compute_list_end();
|
||||
|
||||
Size2 rtsize = storage->render_target_get_size(p_render_target);
|
||||
storage->get_effects()->copy_to_fb_rect(p_texture, storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(p_render_target);
|
||||
storage->get_effects()->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true);
|
||||
}
|
||||
|
||||
void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) {
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
#include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/voxel_gi.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/renderer_scene_render.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "core/config/project_settings.h"
|
||||
#include "core/os/os.h"
|
||||
#include "renderer_compositor_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
|
@ -2557,7 +2556,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
|
|||
tonemap.luminance_multiplier = _render_buffers_get_luminance_multiplier();
|
||||
tonemap.view_count = p_render_data->view_count;
|
||||
|
||||
storage->get_effects()->tonemapper(rb->internal_texture, storage->render_target_get_rd_framebuffer(rb->render_target), tonemap);
|
||||
storage->get_effects()->tonemapper(rb->internal_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), tonemap);
|
||||
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
}
|
||||
|
@ -2570,7 +2569,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
|
|||
RD::get_singleton()->draw_command_end_label();
|
||||
}
|
||||
|
||||
storage->render_target_disable_clear_request(rb->render_target);
|
||||
texture_storage->render_target_disable_clear_request(rb->render_target);
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::_post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data) {
|
||||
|
@ -2647,7 +2646,8 @@ void RendererSceneRenderRD::_disable_clear_request(const RenderDataRD *p_render_
|
|||
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_data->render_buffers);
|
||||
ERR_FAIL_COND(!rb);
|
||||
|
||||
storage->render_target_disable_clear_request(rb->render_target);
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
texture_storage->render_target_disable_clear_request(rb->render_target);
|
||||
}
|
||||
|
||||
void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer) {
|
||||
|
@ -2665,64 +2665,64 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
|
|||
shadow_atlas_texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK);
|
||||
}
|
||||
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS) {
|
||||
if (directional_shadow_get_texture().is_valid()) {
|
||||
RID shadow_atlas_texture = directional_shadow_get_texture();
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
|
||||
|
||||
effects->copy_to_fb_rect(shadow_atlas_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
|
||||
effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_DECAL_ATLAS) {
|
||||
RID decal_atlas = RendererRD::DecalAtlasStorage::get_singleton()->decal_atlas_get_texture();
|
||||
RID decal_atlas = RendererRD::TextureStorage::get_singleton()->decal_atlas_get_texture();
|
||||
|
||||
if (decal_atlas.is_valid()) {
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
|
||||
|
||||
effects->copy_to_fb_rect(decal_atlas, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, false, true);
|
||||
effects->copy_to_fb_rect(decal_atlas, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE) {
|
||||
if (rb->luminance.current.is_valid()) {
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
|
||||
|
||||
effects->copy_to_fb_rect(rb->luminance.current, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true);
|
||||
effects->copy_to_fb_rect(rb->luminance.current, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ss_effects.ssao.ao_final.is_valid()) {
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(rb->ss_effects.ssao.ao_final, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(rb->ss_effects.ssao.ao_final, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true);
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSIL && rb->ss_effects.ssil.ssil_final.is_valid()) {
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(rb->ss_effects.ssil.ssil_final, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(rb->ss_effects.ssil.ssil_final, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER && _render_buffers_get_normal_texture(p_render_buffers).is_valid()) {
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->ambient_buffer.is_valid()) {
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
|
||||
RID ambient_texture = rb->ambient_buffer;
|
||||
RID reflection_texture = rb->reflection_buffer;
|
||||
effects->copy_to_fb_rect(ambient_texture, storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture);
|
||||
effects->copy_to_fb_rect(ambient_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture);
|
||||
}
|
||||
|
||||
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS) {
|
||||
if (p_occlusion_buffer.is_valid()) {
|
||||
Size2 rtsize = storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_occlusion_buffer), storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize), true, false);
|
||||
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
|
||||
effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_occlusion_buffer), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize), true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2943,6 +2943,8 @@ bool RendererSceneRenderRD::_render_buffers_can_be_storage() {
|
|||
}
|
||||
|
||||
void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_internal_width, int p_internal_height, int p_width, int p_height, float p_fsr_sharpness, float p_fsr_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_debanding, uint32_t p_view_count) {
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
|
||||
ERR_FAIL_COND_MSG(p_view_count == 0, "Must have at least 1 view");
|
||||
|
||||
if (!_render_buffers_can_be_storage()) {
|
||||
|
@ -3040,7 +3042,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
|
|||
rb->texture_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, rb->view_count);
|
||||
}
|
||||
|
||||
RID target_texture = storage->render_target_get_rd_texture(rb->render_target);
|
||||
RID target_texture = texture_storage->render_target_get_rd_texture(rb->render_target);
|
||||
rb->data->configure(rb->internal_texture, rb->depth_texture, target_texture, p_internal_width, p_internal_height, p_msaa, p_view_count);
|
||||
|
||||
if (is_clustered_enabled()) {
|
||||
|
@ -3268,7 +3270,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
|
|||
}
|
||||
|
||||
void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows) {
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
|
||||
Transform3D inverse_transform = p_camera_transform.affine_inverse();
|
||||
|
||||
|
@ -3553,7 +3555,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
|||
RID projector = storage->light_get_projector(base);
|
||||
|
||||
if (projector.is_valid()) {
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(projector);
|
||||
Rect2 rect = texture_storage->decal_atlas_get_texture_rect(projector);
|
||||
|
||||
if (type == RS::LIGHT_SPOT) {
|
||||
light_data.projector_rect[0] = rect.position.x;
|
||||
|
@ -3669,7 +3671,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
|
|||
}
|
||||
|
||||
void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform) {
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
|
||||
Transform3D uv_xform;
|
||||
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
|
||||
|
@ -3694,9 +3696,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
|||
|
||||
real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
|
||||
|
||||
if (decal_atlas_storage->decal_is_distance_fade_enabled(decal)) {
|
||||
float fade_begin = decal_atlas_storage->decal_get_distance_fade_begin(decal);
|
||||
float fade_length = decal_atlas_storage->decal_get_distance_fade_length(decal);
|
||||
if (texture_storage->decal_is_distance_fade_enabled(decal)) {
|
||||
float fade_begin = texture_storage->decal_get_distance_fade_begin(decal);
|
||||
float fade_length = texture_storage->decal_get_distance_fade_length(decal);
|
||||
|
||||
if (distance > fade_begin) {
|
||||
if (distance > fade_begin + fade_length) {
|
||||
|
@ -3724,15 +3726,15 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
|||
_map_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id, i);
|
||||
}
|
||||
|
||||
di->cull_mask = decal_atlas_storage->decal_get_cull_mask(decal);
|
||||
di->cull_mask = texture_storage->decal_get_cull_mask(decal);
|
||||
|
||||
Transform3D xform = di->transform;
|
||||
float fade = 1.0;
|
||||
|
||||
if (decal_atlas_storage->decal_is_distance_fade_enabled(decal)) {
|
||||
if (texture_storage->decal_is_distance_fade_enabled(decal)) {
|
||||
real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
|
||||
float fade_begin = decal_atlas_storage->decal_get_distance_fade_begin(decal);
|
||||
float fade_length = decal_atlas_storage->decal_get_distance_fade_length(decal);
|
||||
float fade_begin = texture_storage->decal_get_distance_fade_begin(decal);
|
||||
float fade_length = texture_storage->decal_get_distance_fade_length(decal);
|
||||
|
||||
if (distance > fade_begin) {
|
||||
fade = 1.0 - (distance - fade_begin) / fade_length;
|
||||
|
@ -3741,7 +3743,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
|||
|
||||
Cluster::DecalData &dd = cluster.decals[i];
|
||||
|
||||
Vector3 decal_extents = decal_atlas_storage->decal_get_extents(decal);
|
||||
Vector3 decal_extents = texture_storage->decal_get_extents(decal);
|
||||
|
||||
Transform3D scale_xform;
|
||||
scale_xform.basis.scale(decal_extents);
|
||||
|
@ -3754,12 +3756,12 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
|||
dd.normal[0] = normal.x;
|
||||
dd.normal[1] = normal.y;
|
||||
dd.normal[2] = normal.z;
|
||||
dd.normal_fade = decal_atlas_storage->decal_get_normal_fade(decal);
|
||||
dd.normal_fade = texture_storage->decal_get_normal_fade(decal);
|
||||
|
||||
RID albedo_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO);
|
||||
RID emission_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION);
|
||||
RID albedo_tex = texture_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ALBEDO);
|
||||
RID emission_tex = texture_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_EMISSION);
|
||||
if (albedo_tex.is_valid()) {
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(albedo_tex);
|
||||
Rect2 rect = texture_storage->decal_atlas_get_texture_rect(albedo_tex);
|
||||
dd.albedo_rect[0] = rect.position.x;
|
||||
dd.albedo_rect[1] = rect.position.y;
|
||||
dd.albedo_rect[2] = rect.size.x;
|
||||
|
@ -3774,10 +3776,10 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
|||
dd.albedo_rect[3] = 0;
|
||||
}
|
||||
|
||||
RID normal_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL);
|
||||
RID normal_tex = texture_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_NORMAL);
|
||||
|
||||
if (normal_tex.is_valid()) {
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(normal_tex);
|
||||
Rect2 rect = texture_storage->decal_atlas_get_texture_rect(normal_tex);
|
||||
dd.normal_rect[0] = rect.position.x;
|
||||
dd.normal_rect[1] = rect.position.y;
|
||||
dd.normal_rect[2] = rect.size.x;
|
||||
|
@ -3792,9 +3794,9 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
|||
dd.normal_rect[3] = 0;
|
||||
}
|
||||
|
||||
RID orm_tex = decal_atlas_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM);
|
||||
RID orm_tex = texture_storage->decal_get_texture(decal, RS::DECAL_TEXTURE_ORM);
|
||||
if (orm_tex.is_valid()) {
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(orm_tex);
|
||||
Rect2 rect = texture_storage->decal_atlas_get_texture_rect(orm_tex);
|
||||
dd.orm_rect[0] = rect.position.x;
|
||||
dd.orm_rect[1] = rect.position.y;
|
||||
dd.orm_rect[2] = rect.size.x;
|
||||
|
@ -3807,7 +3809,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
|||
}
|
||||
|
||||
if (emission_tex.is_valid()) {
|
||||
Rect2 rect = decal_atlas_storage->decal_atlas_get_texture_rect(emission_tex);
|
||||
Rect2 rect = texture_storage->decal_atlas_get_texture_rect(emission_tex);
|
||||
dd.emission_rect[0] = rect.position.x;
|
||||
dd.emission_rect[1] = rect.position.y;
|
||||
dd.emission_rect[2] = rect.size.x;
|
||||
|
@ -3819,16 +3821,16 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
|
|||
dd.emission_rect[3] = 0;
|
||||
}
|
||||
|
||||
Color modulate = decal_atlas_storage->decal_get_modulate(decal);
|
||||
Color modulate = texture_storage->decal_get_modulate(decal);
|
||||
dd.modulate[0] = modulate.r;
|
||||
dd.modulate[1] = modulate.g;
|
||||
dd.modulate[2] = modulate.b;
|
||||
dd.modulate[3] = modulate.a * fade;
|
||||
dd.emission_energy = decal_atlas_storage->decal_get_emission_energy(decal) * fade;
|
||||
dd.albedo_mix = decal_atlas_storage->decal_get_albedo_mix(decal);
|
||||
dd.mask = decal_atlas_storage->decal_get_cull_mask(decal);
|
||||
dd.upper_fade = decal_atlas_storage->decal_get_upper_fade(decal);
|
||||
dd.lower_fade = decal_atlas_storage->decal_get_lower_fade(decal);
|
||||
dd.emission_energy = texture_storage->decal_get_emission_energy(decal) * fade;
|
||||
dd.albedo_mix = texture_storage->decal_get_albedo_mix(decal);
|
||||
dd.mask = texture_storage->decal_get_cull_mask(decal);
|
||||
dd.upper_fade = texture_storage->decal_get_upper_fade(decal);
|
||||
dd.lower_fade = texture_storage->decal_get_lower_fade(decal);
|
||||
|
||||
if (current_cluster_builder != nullptr) {
|
||||
current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_DECAL, xform, decal_extents);
|
||||
|
@ -4974,6 +4976,8 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
|
|||
}
|
||||
|
||||
void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData *p_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data, RendererScene::RenderInfo *r_render_info) {
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
|
||||
// getting this here now so we can direct call a bunch of things more easily
|
||||
RenderBuffers *rb = nullptr;
|
||||
if (p_render_buffers.is_valid()) {
|
||||
|
@ -5052,7 +5056,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData
|
|||
|
||||
Color clear_color;
|
||||
if (p_render_buffers.is_valid()) {
|
||||
clear_color = storage->render_target_get_clear_request_color(rb->render_target);
|
||||
clear_color = texture_storage->render_target_get_clear_request_color(rb->render_target);
|
||||
} else {
|
||||
clear_color = storage->get_default_clear_color();
|
||||
}
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
#include "core/io/resource_loader.h"
|
||||
#include "core/math/math_defs.h"
|
||||
#include "renderer_compositor_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/canvas_texture_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/decal_atlas_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/rendering_server_globals.h"
|
||||
|
@ -2030,7 +2028,7 @@ void RendererStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
|
|||
}
|
||||
|
||||
void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
|
||||
RendererRD::DecalAtlasStorage *decal_atlas_storage = RendererRD::DecalAtlasStorage::get_singleton();
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
Light *light = light_owner.get_or_null(p_light);
|
||||
ERR_FAIL_COND(!light);
|
||||
|
||||
|
@ -2039,14 +2037,14 @@ void RendererStorageRD::light_set_projector(RID p_light, RID p_texture) {
|
|||
}
|
||||
|
||||
if (light->type != RS::LIGHT_DIRECTIONAL && light->projector.is_valid()) {
|
||||
decal_atlas_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
|
||||
texture_storage->texture_remove_from_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
|
||||
}
|
||||
|
||||
light->projector = p_texture;
|
||||
|
||||
if (light->type != RS::LIGHT_DIRECTIONAL) {
|
||||
if (light->projector.is_valid()) {
|
||||
decal_atlas_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
|
||||
texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
|
||||
}
|
||||
light->dependency.changed_notify(DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
|
||||
}
|
||||
|
@ -2950,698 +2948,6 @@ AABB RendererStorageRD::lightmap_get_aabb(RID p_lightmap) const {
|
|||
return lm->bounds;
|
||||
}
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
void RendererStorageRD::_clear_render_target(RenderTarget *rt) {
|
||||
//free in reverse dependency order
|
||||
if (rt->framebuffer.is_valid()) {
|
||||
RD::get_singleton()->free(rt->framebuffer);
|
||||
rt->framebuffer_uniform_set = RID(); //chain deleted
|
||||
}
|
||||
|
||||
if (rt->color.is_valid()) {
|
||||
RD::get_singleton()->free(rt->color);
|
||||
}
|
||||
|
||||
if (rt->backbuffer.is_valid()) {
|
||||
RD::get_singleton()->free(rt->backbuffer);
|
||||
rt->backbuffer = RID();
|
||||
rt->backbuffer_mipmaps.clear();
|
||||
rt->backbuffer_uniform_set = RID(); //chain deleted
|
||||
}
|
||||
|
||||
_render_target_clear_sdf(rt);
|
||||
|
||||
rt->framebuffer = RID();
|
||||
rt->color = RID();
|
||||
}
|
||||
|
||||
void RendererStorageRD::_update_render_target(RenderTarget *rt) {
|
||||
if (rt->texture.is_null()) {
|
||||
//create a placeholder until updated
|
||||
rt->texture = RendererRD::TextureStorage::get_singleton()->texture_allocate();
|
||||
RendererRD::TextureStorage::get_singleton()->texture_2d_placeholder_initialize(rt->texture);
|
||||
RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(rt->texture);
|
||||
tex->is_render_target = true;
|
||||
}
|
||||
|
||||
_clear_render_target(rt);
|
||||
|
||||
if (rt->size.width == 0 || rt->size.height == 0) {
|
||||
return;
|
||||
}
|
||||
//until we implement support for HDR monitors (and render target is attached to screen), this is enough.
|
||||
rt->color_format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
rt->color_format_srgb = RD::DATA_FORMAT_R8G8B8A8_SRGB;
|
||||
rt->image_format = rt->flags[RENDER_TARGET_TRANSPARENT] ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8;
|
||||
|
||||
RD::TextureFormat rd_format;
|
||||
RD::TextureView rd_view;
|
||||
{ //attempt register
|
||||
rd_format.format = rt->color_format;
|
||||
rd_format.width = rt->size.width;
|
||||
rd_format.height = rt->size.height;
|
||||
rd_format.depth = 1;
|
||||
rd_format.array_layers = rt->view_count; // for stereo we create two (or more) layers, need to see if we can make fallback work like this too if we don't have multiview
|
||||
rd_format.mipmaps = 1;
|
||||
if (rd_format.array_layers > 1) { // why are we not using rt->texture_type ??
|
||||
rd_format.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
|
||||
} else {
|
||||
rd_format.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
}
|
||||
rd_format.samples = RD::TEXTURE_SAMPLES_1;
|
||||
rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
|
||||
rd_format.shareable_formats.push_back(rt->color_format);
|
||||
rd_format.shareable_formats.push_back(rt->color_format_srgb);
|
||||
}
|
||||
|
||||
rt->color = RD::get_singleton()->texture_create(rd_format, rd_view);
|
||||
ERR_FAIL_COND(rt->color.is_null());
|
||||
|
||||
Vector<RID> fb_textures;
|
||||
fb_textures.push_back(rt->color);
|
||||
rt->framebuffer = RD::get_singleton()->framebuffer_create(fb_textures, RenderingDevice::INVALID_ID, rt->view_count);
|
||||
if (rt->framebuffer.is_null()) {
|
||||
_clear_render_target(rt);
|
||||
ERR_FAIL_COND(rt->framebuffer.is_null());
|
||||
}
|
||||
|
||||
{ //update texture
|
||||
|
||||
RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(rt->texture);
|
||||
|
||||
//free existing textures
|
||||
if (RD::get_singleton()->texture_is_valid(tex->rd_texture)) {
|
||||
RD::get_singleton()->free(tex->rd_texture);
|
||||
}
|
||||
if (RD::get_singleton()->texture_is_valid(tex->rd_texture_srgb)) {
|
||||
RD::get_singleton()->free(tex->rd_texture_srgb);
|
||||
}
|
||||
|
||||
tex->rd_texture = RID();
|
||||
tex->rd_texture_srgb = RID();
|
||||
|
||||
//create shared textures to the color buffer,
|
||||
//so transparent can be supported
|
||||
RD::TextureView view;
|
||||
view.format_override = rt->color_format;
|
||||
if (!rt->flags[RENDER_TARGET_TRANSPARENT]) {
|
||||
view.swizzle_a = RD::TEXTURE_SWIZZLE_ONE;
|
||||
}
|
||||
tex->rd_texture = RD::get_singleton()->texture_create_shared(view, rt->color);
|
||||
if (rt->color_format_srgb != RD::DATA_FORMAT_MAX) {
|
||||
view.format_override = rt->color_format_srgb;
|
||||
tex->rd_texture_srgb = RD::get_singleton()->texture_create_shared(view, rt->color);
|
||||
}
|
||||
tex->rd_view = view;
|
||||
tex->width = rt->size.width;
|
||||
tex->height = rt->size.height;
|
||||
tex->width_2d = rt->size.width;
|
||||
tex->height_2d = rt->size.height;
|
||||
tex->rd_format = rt->color_format;
|
||||
tex->rd_format_srgb = rt->color_format_srgb;
|
||||
tex->format = rt->image_format;
|
||||
|
||||
Vector<RID> proxies = tex->proxies; //make a copy, since update may change it
|
||||
for (int i = 0; i < proxies.size(); i++) {
|
||||
RendererRD::TextureStorage::get_singleton()->texture_proxy_update(proxies[i], rt->texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RendererStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
|
||||
ERR_FAIL_COND(rt->backbuffer.is_valid());
|
||||
|
||||
uint32_t mipmaps_required = Image::get_image_required_mipmaps(rt->size.width, rt->size.height, Image::FORMAT_RGBA8);
|
||||
RD::TextureFormat tf;
|
||||
tf.format = rt->color_format;
|
||||
tf.width = rt->size.width;
|
||||
tf.height = rt->size.height;
|
||||
tf.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
|
||||
tf.mipmaps = mipmaps_required;
|
||||
|
||||
rt->backbuffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
|
||||
RD::get_singleton()->set_resource_name(rt->backbuffer, "Render Target Back Buffer");
|
||||
rt->backbuffer_mipmap0 = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, 0);
|
||||
RD::get_singleton()->set_resource_name(rt->backbuffer_mipmap0, "Back Buffer slice mipmap 0");
|
||||
|
||||
{
|
||||
Vector<RID> fb_tex;
|
||||
fb_tex.push_back(rt->backbuffer_mipmap0);
|
||||
rt->backbuffer_fb = RD::get_singleton()->framebuffer_create(fb_tex);
|
||||
}
|
||||
|
||||
if (rt->framebuffer_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rt->framebuffer_uniform_set)) {
|
||||
//the new one will require the backbuffer.
|
||||
RD::get_singleton()->free(rt->framebuffer_uniform_set);
|
||||
rt->framebuffer_uniform_set = RID();
|
||||
}
|
||||
//create mipmaps
|
||||
for (uint32_t i = 1; i < mipmaps_required; i++) {
|
||||
RID mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i);
|
||||
RD::get_singleton()->set_resource_name(mipmap, "Back Buffer slice mip: " + itos(i));
|
||||
|
||||
rt->backbuffer_mipmaps.push_back(mipmap);
|
||||
}
|
||||
}
|
||||
|
||||
RID RendererStorageRD::render_target_create() {
|
||||
RenderTarget render_target;
|
||||
|
||||
render_target.was_used = false;
|
||||
render_target.clear_requested = false;
|
||||
|
||||
for (int i = 0; i < RENDER_TARGET_FLAG_MAX; i++) {
|
||||
render_target.flags[i] = false;
|
||||
}
|
||||
_update_render_target(&render_target);
|
||||
return render_target_owner.make_rid(render_target);
|
||||
}
|
||||
|
||||
void RendererStorageRD::render_target_set_position(RID p_render_target, int p_x, int p_y) {
|
||||
//unused for this render target
|
||||
}
|
||||
|
||||
void RendererStorageRD::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 (rt->size.x != p_width || rt->size.y != p_height || rt->view_count != p_view_count) {
|
||||
rt->size.x = p_width;
|
||||
rt->size.y = p_height;
|
||||
rt->view_count = p_view_count;
|
||||
_update_render_target(rt);
|
||||
}
|
||||
}
|
||||
|
||||
RID RendererStorageRD::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());
|
||||
|
||||
return rt->texture;
|
||||
}
|
||||
|
||||
void RendererStorageRD::render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) {
|
||||
}
|
||||
|
||||
void RendererStorageRD::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);
|
||||
rt->flags[p_flag] = p_value;
|
||||
_update_render_target(rt);
|
||||
}
|
||||
|
||||
bool RendererStorageRD::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->was_used;
|
||||
}
|
||||
|
||||
void RendererStorageRD::render_target_set_as_unused(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
rt->was_used = false;
|
||||
}
|
||||
|
||||
Size2 RendererStorageRD::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 rt->size;
|
||||
}
|
||||
|
||||
RID RendererStorageRD::render_target_get_rd_framebuffer(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
|
||||
return rt->framebuffer;
|
||||
}
|
||||
|
||||
RID RendererStorageRD::render_target_get_rd_texture(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
|
||||
return rt->color;
|
||||
}
|
||||
|
||||
RID RendererStorageRD::render_target_get_rd_backbuffer(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
return rt->backbuffer;
|
||||
}
|
||||
|
||||
RID RendererStorageRD::render_target_get_rd_backbuffer_framebuffer(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
|
||||
if (!rt->backbuffer.is_valid()) {
|
||||
_create_render_target_backbuffer(rt);
|
||||
}
|
||||
|
||||
return rt->backbuffer_fb;
|
||||
}
|
||||
|
||||
void RendererStorageRD::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;
|
||||
}
|
||||
|
||||
bool RendererStorageRD::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 RendererStorageRD::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 RendererStorageRD::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 RendererStorageRD::render_target_do_clear_request(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
if (!rt->clear_requested) {
|
||||
return;
|
||||
}
|
||||
Vector<Color> clear_colors;
|
||||
clear_colors.push_back(rt->clear_color);
|
||||
RD::get_singleton()->draw_list_begin(rt->framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, clear_colors);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
rt->clear_requested = false;
|
||||
}
|
||||
|
||||
void RendererStorageRD::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) {
|
||||
return;
|
||||
}
|
||||
|
||||
rt->sdf_oversize = p_size;
|
||||
rt->sdf_scale = p_scale;
|
||||
|
||||
_render_target_clear_sdf(rt);
|
||||
}
|
||||
|
||||
Rect2i RendererStorageRD::_render_target_get_sdf_rect(const RenderTarget *rt) const {
|
||||
Size2i margin;
|
||||
int scale;
|
||||
switch (rt->sdf_oversize) {
|
||||
case RS::VIEWPORT_SDF_OVERSIZE_100_PERCENT: {
|
||||
scale = 100;
|
||||
} break;
|
||||
case RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT: {
|
||||
scale = 120;
|
||||
} break;
|
||||
case RS::VIEWPORT_SDF_OVERSIZE_150_PERCENT: {
|
||||
scale = 150;
|
||||
} break;
|
||||
case RS::VIEWPORT_SDF_OVERSIZE_200_PERCENT: {
|
||||
scale = 200;
|
||||
} break;
|
||||
default: {
|
||||
}
|
||||
}
|
||||
|
||||
margin = (rt->size * scale / 100) - rt->size;
|
||||
|
||||
Rect2i r(Vector2i(), rt->size);
|
||||
r.position -= margin;
|
||||
r.size += margin * 2;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
Rect2i RendererStorageRD::render_target_get_sdf_rect(RID p_render_target) const {
|
||||
const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, Rect2i());
|
||||
|
||||
return _render_target_get_sdf_rect(rt);
|
||||
}
|
||||
|
||||
void RendererStorageRD::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
|
||||
rt->sdf_enabled = p_enabled;
|
||||
}
|
||||
|
||||
bool RendererStorageRD::render_target_is_sdf_enabled(RID p_render_target) const {
|
||||
const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, false);
|
||||
|
||||
return rt->sdf_enabled;
|
||||
}
|
||||
|
||||
RID RendererStorageRD::render_target_get_sdf_texture(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
if (rt->sdf_buffer_read.is_null()) {
|
||||
// no texture, create a dummy one for the 2D uniform set
|
||||
RD::TextureFormat tformat;
|
||||
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
tformat.width = 4;
|
||||
tformat.height = 4;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT;
|
||||
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
|
||||
Vector<uint8_t> pv;
|
||||
pv.resize(16 * 4);
|
||||
memset(pv.ptrw(), 0, 16 * 4);
|
||||
Vector<Vector<uint8_t>> vpv;
|
||||
|
||||
rt->sdf_buffer_read = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
|
||||
}
|
||||
|
||||
return rt->sdf_buffer_read;
|
||||
}
|
||||
|
||||
void RendererStorageRD::_render_target_allocate_sdf(RenderTarget *rt) {
|
||||
ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_valid());
|
||||
if (rt->sdf_buffer_read.is_valid()) {
|
||||
RD::get_singleton()->free(rt->sdf_buffer_read);
|
||||
rt->sdf_buffer_read = RID();
|
||||
}
|
||||
|
||||
Size2i size = _render_target_get_sdf_rect(rt).size;
|
||||
|
||||
RD::TextureFormat tformat;
|
||||
tformat.format = RD::DATA_FORMAT_R8_UNORM;
|
||||
tformat.width = size.width;
|
||||
tformat.height = size.height;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
|
||||
rt->sdf_buffer_write = RD::get_singleton()->texture_create(tformat, RD::TextureView());
|
||||
|
||||
{
|
||||
Vector<RID> write_fb;
|
||||
write_fb.push_back(rt->sdf_buffer_write);
|
||||
rt->sdf_buffer_write_fb = RD::get_singleton()->framebuffer_create(write_fb);
|
||||
}
|
||||
|
||||
int scale;
|
||||
switch (rt->sdf_scale) {
|
||||
case RS::VIEWPORT_SDF_SCALE_100_PERCENT: {
|
||||
scale = 100;
|
||||
} break;
|
||||
case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
|
||||
scale = 50;
|
||||
} break;
|
||||
case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
|
||||
scale = 25;
|
||||
} break;
|
||||
default: {
|
||||
scale = 100;
|
||||
} break;
|
||||
}
|
||||
|
||||
rt->process_size = size * scale / 100;
|
||||
rt->process_size.x = MAX(rt->process_size.x, 1);
|
||||
rt->process_size.y = MAX(rt->process_size.y, 1);
|
||||
|
||||
tformat.format = RD::DATA_FORMAT_R16G16_SINT;
|
||||
tformat.width = rt->process_size.width;
|
||||
tformat.height = rt->process_size.height;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT;
|
||||
|
||||
rt->sdf_buffer_process[0] = RD::get_singleton()->texture_create(tformat, RD::TextureView());
|
||||
rt->sdf_buffer_process[1] = RD::get_singleton()->texture_create(tformat, RD::TextureView());
|
||||
|
||||
tformat.format = RD::DATA_FORMAT_R16_SNORM;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
|
||||
|
||||
rt->sdf_buffer_read = RD::get_singleton()->texture_create(tformat, RD::TextureView());
|
||||
|
||||
{
|
||||
Vector<RD::Uniform> uniforms;
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 1;
|
||||
u.append_id(rt->sdf_buffer_write);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 2;
|
||||
u.append_id(rt->sdf_buffer_read);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 3;
|
||||
u.append_id(rt->sdf_buffer_process[0]);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
|
||||
u.binding = 4;
|
||||
u.append_id(rt->sdf_buffer_process[1]);
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
rt->sdf_buffer_process_uniform_sets[0] = RD::get_singleton()->uniform_set_create(uniforms, rt_sdf.shader.version_get_shader(rt_sdf.shader_version, 0), 0);
|
||||
RID aux2 = uniforms.write[2].get_id(0);
|
||||
RID aux3 = uniforms.write[3].get_id(0);
|
||||
uniforms.write[2].set_id(0, aux3);
|
||||
uniforms.write[3].set_id(0, aux2);
|
||||
rt->sdf_buffer_process_uniform_sets[1] = RD::get_singleton()->uniform_set_create(uniforms, rt_sdf.shader.version_get_shader(rt_sdf.shader_version, 0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RendererStorageRD::_render_target_clear_sdf(RenderTarget *rt) {
|
||||
if (rt->sdf_buffer_read.is_valid()) {
|
||||
RD::get_singleton()->free(rt->sdf_buffer_read);
|
||||
rt->sdf_buffer_read = RID();
|
||||
}
|
||||
if (rt->sdf_buffer_write_fb.is_valid()) {
|
||||
RD::get_singleton()->free(rt->sdf_buffer_write);
|
||||
RD::get_singleton()->free(rt->sdf_buffer_process[0]);
|
||||
RD::get_singleton()->free(rt->sdf_buffer_process[1]);
|
||||
rt->sdf_buffer_write = RID();
|
||||
rt->sdf_buffer_write_fb = RID();
|
||||
rt->sdf_buffer_process[0] = RID();
|
||||
rt->sdf_buffer_process[1] = RID();
|
||||
rt->sdf_buffer_process_uniform_sets[0] = RID();
|
||||
rt->sdf_buffer_process_uniform_sets[1] = RID();
|
||||
}
|
||||
}
|
||||
|
||||
RID RendererStorageRD::render_target_get_sdf_framebuffer(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
|
||||
if (rt->sdf_buffer_write_fb.is_null()) {
|
||||
_render_target_allocate_sdf(rt);
|
||||
}
|
||||
|
||||
return rt->sdf_buffer_write_fb;
|
||||
}
|
||||
void RendererStorageRD::render_target_sdf_process(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
ERR_FAIL_COND(rt->sdf_buffer_write_fb.is_null());
|
||||
|
||||
RenderTargetSDF::PushConstant push_constant;
|
||||
|
||||
Rect2i r = _render_target_get_sdf_rect(rt);
|
||||
|
||||
push_constant.size[0] = r.size.width;
|
||||
push_constant.size[1] = r.size.height;
|
||||
push_constant.stride = 0;
|
||||
push_constant.shift = 0;
|
||||
push_constant.base_size[0] = r.size.width;
|
||||
push_constant.base_size[1] = r.size.height;
|
||||
|
||||
bool shrink = false;
|
||||
|
||||
switch (rt->sdf_scale) {
|
||||
case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
|
||||
push_constant.size[0] >>= 1;
|
||||
push_constant.size[1] >>= 1;
|
||||
push_constant.shift = 1;
|
||||
shrink = true;
|
||||
} break;
|
||||
case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
|
||||
push_constant.size[0] >>= 2;
|
||||
push_constant.size[1] >>= 2;
|
||||
push_constant.shift = 2;
|
||||
shrink = true;
|
||||
} break;
|
||||
default: {
|
||||
};
|
||||
}
|
||||
|
||||
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
|
||||
|
||||
/* Load */
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_LOAD_SHRINK : RenderTargetSDF::SHADER_LOAD]);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[1], 0); //fill [0]
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
|
||||
|
||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
|
||||
|
||||
/* Process */
|
||||
|
||||
int stride = nearest_power_of_2_templated(MAX(push_constant.size[0], push_constant.size[1]) / 2);
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[RenderTargetSDF::SHADER_PROCESS]);
|
||||
|
||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
||||
bool swap = false;
|
||||
|
||||
//jumpflood
|
||||
while (stride > 0) {
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
|
||||
push_constant.stride = stride;
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
|
||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
|
||||
stride /= 2;
|
||||
swap = !swap;
|
||||
RD::get_singleton()->compute_list_add_barrier(compute_list);
|
||||
}
|
||||
|
||||
/* Store */
|
||||
|
||||
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, rt_sdf.pipelines[shrink ? RenderTargetSDF::SHADER_STORE_SHRINK : RenderTargetSDF::SHADER_STORE]);
|
||||
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rt->sdf_buffer_process_uniform_sets[swap ? 1 : 0], 0);
|
||||
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RenderTargetSDF::PushConstant));
|
||||
RD::get_singleton()->compute_list_dispatch_threads(compute_list, push_constant.size[0], push_constant.size[1], 1);
|
||||
|
||||
RD::get_singleton()->compute_list_end();
|
||||
}
|
||||
|
||||
void RendererStorageRD::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
if (!rt->backbuffer.is_valid()) {
|
||||
_create_render_target_backbuffer(rt);
|
||||
}
|
||||
|
||||
Rect2i region;
|
||||
if (p_region == Rect2i()) {
|
||||
region.size = rt->size;
|
||||
} else {
|
||||
region = Rect2i(Size2i(), rt->size).intersection(p_region);
|
||||
if (region.size == Size2i()) {
|
||||
return; //nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
//single texture copy for backbuffer
|
||||
//RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true);
|
||||
effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true);
|
||||
|
||||
if (!p_gen_mipmaps) {
|
||||
return;
|
||||
}
|
||||
RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps");
|
||||
//then mipmap blur
|
||||
RID prev_texture = rt->color; //use color, not backbuffer, as bb has mipmaps.
|
||||
|
||||
for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
|
||||
region.position.x >>= 1;
|
||||
region.position.y >>= 1;
|
||||
region.size.x = MAX(1, region.size.x >> 1);
|
||||
region.size.y = MAX(1, region.size.y >> 1);
|
||||
|
||||
RID mipmap = rt->backbuffer_mipmaps[i];
|
||||
effects->gaussian_blur(prev_texture, mipmap, region, true);
|
||||
prev_texture = mipmap;
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
}
|
||||
|
||||
void RendererStorageRD::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
if (!rt->backbuffer.is_valid()) {
|
||||
_create_render_target_backbuffer(rt);
|
||||
}
|
||||
|
||||
Rect2i region;
|
||||
if (p_region == Rect2i()) {
|
||||
region.size = rt->size;
|
||||
} else {
|
||||
region = Rect2i(Size2i(), rt->size).intersection(p_region);
|
||||
if (region.size == Size2i()) {
|
||||
return; //nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
//single texture copy for backbuffer
|
||||
effects->set_color(rt->backbuffer_mipmap0, p_color, region, true);
|
||||
}
|
||||
|
||||
void RendererStorageRD::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
if (!rt->backbuffer.is_valid()) {
|
||||
_create_render_target_backbuffer(rt);
|
||||
}
|
||||
|
||||
Rect2i region;
|
||||
if (p_region == Rect2i()) {
|
||||
region.size = rt->size;
|
||||
} else {
|
||||
region = Rect2i(Size2i(), rt->size).intersection(p_region);
|
||||
if (region.size == Size2i()) {
|
||||
return; //nothing to do
|
||||
}
|
||||
}
|
||||
RD::get_singleton()->draw_command_begin_label("Gaussian Blur Mipmaps2");
|
||||
//then mipmap blur
|
||||
RID prev_texture = rt->backbuffer_mipmap0;
|
||||
|
||||
for (int i = 0; i < rt->backbuffer_mipmaps.size(); i++) {
|
||||
region.position.x >>= 1;
|
||||
region.position.y >>= 1;
|
||||
region.size.x = MAX(1, region.size.x >> 1);
|
||||
region.size.y = MAX(1, region.size.y >> 1);
|
||||
|
||||
RID mipmap = rt->backbuffer_mipmaps[i];
|
||||
effects->gaussian_blur(prev_texture, mipmap, region, true);
|
||||
prev_texture = mipmap;
|
||||
}
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
}
|
||||
|
||||
RID RendererStorageRD::render_target_get_framebuffer_uniform_set(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
return rt->framebuffer_uniform_set;
|
||||
}
|
||||
RID RendererStorageRD::render_target_get_backbuffer_uniform_set(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
return rt->backbuffer_uniform_set;
|
||||
}
|
||||
|
||||
void RendererStorageRD::render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
rt->framebuffer_uniform_set = p_uniform_set;
|
||||
}
|
||||
void RendererStorageRD::render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
rt->backbuffer_uniform_set = p_uniform_set;
|
||||
}
|
||||
|
||||
void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
|
||||
if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_base)) {
|
||||
RendererRD::Mesh *mesh = RendererRD::MeshStorage::get_singleton()->get_mesh(p_base);
|
||||
|
@ -3655,8 +2961,8 @@ void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_
|
|||
} else if (reflection_probe_owner.owns(p_base)) {
|
||||
ReflectionProbe *rp = reflection_probe_owner.get_or_null(p_base);
|
||||
p_instance->update_dependency(&rp->dependency);
|
||||
} else if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_base)) {
|
||||
RendererRD::Decal *decal = RendererRD::DecalAtlasStorage::get_singleton()->get_decal(p_base);
|
||||
} else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_base)) {
|
||||
RendererRD::Decal *decal = RendererRD::TextureStorage::get_singleton()->get_decal(p_base);
|
||||
p_instance->update_dependency(&decal->dependency);
|
||||
} else if (voxel_gi_owner.owns(p_base)) {
|
||||
VoxelGI *gip = voxel_gi_owner.get_or_null(p_base);
|
||||
|
@ -3692,7 +2998,7 @@ RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
|
|||
if (reflection_probe_owner.owns(p_rid)) {
|
||||
return RS::INSTANCE_REFLECTION_PROBE;
|
||||
}
|
||||
if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_rid)) {
|
||||
if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
|
||||
return RS::INSTANCE_DECAL;
|
||||
}
|
||||
if (voxel_gi_owner.owns(p_rid)) {
|
||||
|
@ -3725,7 +3031,7 @@ void RendererStorageRD::update_dirty_resources() {
|
|||
RendererRD::MaterialStorage::get_singleton()->_update_queued_materials();
|
||||
RendererRD::MeshStorage::get_singleton()->_update_dirty_multimeshes();
|
||||
RendererRD::MeshStorage::get_singleton()->_update_dirty_skeletons();
|
||||
RendererRD::DecalAtlasStorage::get_singleton()->update_decal_atlas();
|
||||
RendererRD::TextureStorage::get_singleton()->update_decal_atlas();
|
||||
}
|
||||
|
||||
bool RendererStorageRD::has_os_feature(const String &p_feature) const {
|
||||
|
@ -3751,8 +3057,8 @@ bool RendererStorageRD::has_os_feature(const String &p_feature) const {
|
|||
bool RendererStorageRD::free(RID p_rid) {
|
||||
if (RendererRD::TextureStorage::get_singleton()->owns_texture(p_rid)) {
|
||||
RendererRD::TextureStorage::get_singleton()->texture_free(p_rid);
|
||||
} else if (RendererRD::CanvasTextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
|
||||
RendererRD::CanvasTextureStorage::get_singleton()->canvas_texture_free(p_rid);
|
||||
} else if (RendererRD::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
|
||||
RendererRD::TextureStorage::get_singleton()->canvas_texture_free(p_rid);
|
||||
} else if (RendererRD::MaterialStorage::get_singleton()->owns_shader(p_rid)) {
|
||||
RendererRD::MaterialStorage::get_singleton()->shader_free(p_rid);
|
||||
} else if (RendererRD::MaterialStorage::get_singleton()->owns_material(p_rid)) {
|
||||
|
@ -3769,8 +3075,8 @@ bool RendererStorageRD::free(RID p_rid) {
|
|||
ReflectionProbe *reflection_probe = reflection_probe_owner.get_or_null(p_rid);
|
||||
reflection_probe->dependency.deleted_notify(p_rid);
|
||||
reflection_probe_owner.free(p_rid);
|
||||
} else if (RendererRD::DecalAtlasStorage::get_singleton()->owns_decal(p_rid)) {
|
||||
RendererRD::DecalAtlasStorage::get_singleton()->decal_free(p_rid);
|
||||
} else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
|
||||
RendererRD::TextureStorage::get_singleton()->decal_free(p_rid);
|
||||
} else if (voxel_gi_owner.owns(p_rid)) {
|
||||
voxel_gi_allocate_data(p_rid, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
|
||||
VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_rid);
|
||||
|
@ -3813,18 +3119,8 @@ bool RendererStorageRD::free(RID p_rid) {
|
|||
FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid);
|
||||
fog_volume->dependency.deleted_notify(p_rid);
|
||||
fog_volume_owner.free(p_rid);
|
||||
} else if (render_target_owner.owns(p_rid)) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_rid);
|
||||
|
||||
_clear_render_target(rt);
|
||||
|
||||
if (rt->texture.is_valid()) {
|
||||
RendererRD::Texture *tex = RendererRD::TextureStorage::get_singleton()->get_texture(rt->texture);
|
||||
tex->is_render_target = false;
|
||||
free(rt->texture);
|
||||
}
|
||||
|
||||
render_target_owner.free(p_rid);
|
||||
} else if (RendererRD::TextureStorage::get_singleton()->owns_render_target(p_rid)) {
|
||||
RendererRD::TextureStorage::get_singleton()->render_target_free(p_rid);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -4159,24 +3455,6 @@ void process() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Vector<String> sdf_modes;
|
||||
sdf_modes.push_back("\n#define MODE_LOAD\n");
|
||||
sdf_modes.push_back("\n#define MODE_LOAD_SHRINK\n");
|
||||
sdf_modes.push_back("\n#define MODE_PROCESS\n");
|
||||
sdf_modes.push_back("\n#define MODE_PROCESS_OPTIMIZED\n");
|
||||
sdf_modes.push_back("\n#define MODE_STORE\n");
|
||||
sdf_modes.push_back("\n#define MODE_STORE_SHRINK\n");
|
||||
|
||||
rt_sdf.shader.initialize(sdf_modes);
|
||||
|
||||
rt_sdf.shader_version = rt_sdf.shader.version_create();
|
||||
|
||||
for (int i = 0; i < RenderTargetSDF::SHADER_MAX; i++) {
|
||||
rt_sdf.pipelines[i] = RD::get_singleton()->compute_pipeline_create(rt_sdf.shader.version_get_shader(rt_sdf.shader_version, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RendererStorageRD::~RendererStorageRD() {
|
||||
|
@ -4199,7 +3477,6 @@ RendererStorageRD::~RendererStorageRD() {
|
|||
}
|
||||
|
||||
particles_shader.copy_shader.version_free(particles_shader.copy_shader_version);
|
||||
rt_sdf.shader.version_free(rt_sdf.shader_version);
|
||||
|
||||
material_storage->material_free(particles_shader.default_material);
|
||||
material_storage->shader_free(particles_shader.default_shader);
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "core/templates/rid_owner.h"
|
||||
#include "servers/rendering/renderer_compositor.h"
|
||||
#include "servers/rendering/renderer_rd/effects_rd.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h"
|
||||
|
@ -627,83 +626,6 @@ private:
|
|||
|
||||
float lightmap_probe_capture_update_speed = 4;
|
||||
|
||||
/* RENDER TARGET */
|
||||
|
||||
struct RenderTarget {
|
||||
Size2i size;
|
||||
uint32_t view_count;
|
||||
RID framebuffer;
|
||||
RID color;
|
||||
|
||||
//used for retrieving from CPU
|
||||
RD::DataFormat color_format = RD::DATA_FORMAT_R4G4_UNORM_PACK8;
|
||||
RD::DataFormat color_format_srgb = RD::DATA_FORMAT_R4G4_UNORM_PACK8;
|
||||
Image::Format image_format = Image::FORMAT_L8;
|
||||
|
||||
bool flags[RENDER_TARGET_FLAG_MAX];
|
||||
|
||||
bool sdf_enabled = false;
|
||||
|
||||
RID backbuffer; //used for effects
|
||||
RID backbuffer_fb;
|
||||
RID backbuffer_mipmap0;
|
||||
|
||||
Vector<RID> backbuffer_mipmaps;
|
||||
|
||||
RID framebuffer_uniform_set;
|
||||
RID backbuffer_uniform_set;
|
||||
|
||||
RID sdf_buffer_write;
|
||||
RID sdf_buffer_write_fb;
|
||||
RID sdf_buffer_process[2];
|
||||
RID sdf_buffer_read;
|
||||
RID sdf_buffer_process_uniform_sets[2];
|
||||
RS::ViewportSDFOversize sdf_oversize = RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT;
|
||||
RS::ViewportSDFScale sdf_scale = RS::VIEWPORT_SDF_SCALE_50_PERCENT;
|
||||
Size2i process_size;
|
||||
|
||||
//texture generated for this owner (nor RD).
|
||||
RID texture;
|
||||
bool was_used;
|
||||
|
||||
//clear request
|
||||
bool clear_requested;
|
||||
Color clear_color;
|
||||
};
|
||||
|
||||
mutable RID_Owner<RenderTarget> render_target_owner;
|
||||
|
||||
void _clear_render_target(RenderTarget *rt);
|
||||
void _update_render_target(RenderTarget *rt);
|
||||
void _create_render_target_backbuffer(RenderTarget *rt);
|
||||
void _render_target_allocate_sdf(RenderTarget *rt);
|
||||
void _render_target_clear_sdf(RenderTarget *rt);
|
||||
Rect2i _render_target_get_sdf_rect(const RenderTarget *rt) const;
|
||||
|
||||
struct RenderTargetSDF {
|
||||
enum {
|
||||
SHADER_LOAD,
|
||||
SHADER_LOAD_SHRINK,
|
||||
SHADER_PROCESS,
|
||||
SHADER_PROCESS_OPTIMIZED,
|
||||
SHADER_STORE,
|
||||
SHADER_STORE_SHRINK,
|
||||
SHADER_MAX
|
||||
};
|
||||
|
||||
struct PushConstant {
|
||||
int32_t size[2];
|
||||
int32_t stride;
|
||||
int32_t shift;
|
||||
int32_t base_size[2];
|
||||
int32_t pad[2];
|
||||
};
|
||||
|
||||
CanvasSdfShaderRD shader;
|
||||
RID shader_version;
|
||||
RID pipelines[SHADER_MAX];
|
||||
} rt_sdf;
|
||||
|
||||
/* EFFECTS */
|
||||
|
||||
EffectsRD *effects = nullptr;
|
||||
|
@ -1149,48 +1071,6 @@ public:
|
|||
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform);
|
||||
virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active);
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
RID render_target_create();
|
||||
void render_target_set_position(RID p_render_target, int p_x, int p_y);
|
||||
void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count);
|
||||
RID render_target_get_texture(RID p_render_target);
|
||||
void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id);
|
||||
void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value);
|
||||
bool render_target_was_used(RID p_render_target);
|
||||
void render_target_set_as_unused(RID p_render_target);
|
||||
void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps);
|
||||
void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color);
|
||||
void render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region);
|
||||
|
||||
RID render_target_get_back_buffer_uniform_set(RID p_render_target, RID p_base_shader);
|
||||
|
||||
virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color);
|
||||
virtual bool render_target_is_clear_requested(RID p_render_target);
|
||||
virtual Color render_target_get_clear_request_color(RID p_render_target);
|
||||
virtual void render_target_disable_clear_request(RID p_render_target);
|
||||
virtual void render_target_do_clear_request(RID p_render_target);
|
||||
|
||||
virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale);
|
||||
RID render_target_get_sdf_texture(RID p_render_target);
|
||||
RID render_target_get_sdf_framebuffer(RID p_render_target);
|
||||
void render_target_sdf_process(RID p_render_target);
|
||||
virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const;
|
||||
void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled);
|
||||
bool render_target_is_sdf_enabled(RID p_render_target) const;
|
||||
|
||||
Size2 render_target_get_size(RID p_render_target);
|
||||
RID render_target_get_rd_framebuffer(RID p_render_target);
|
||||
RID render_target_get_rd_texture(RID p_render_target);
|
||||
RID render_target_get_rd_backbuffer(RID p_render_target);
|
||||
RID render_target_get_rd_backbuffer_framebuffer(RID p_render_target);
|
||||
|
||||
RID render_target_get_framebuffer_uniform_set(RID p_render_target);
|
||||
RID render_target_get_backbuffer_uniform_set(RID p_render_target);
|
||||
|
||||
void render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set);
|
||||
void render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set);
|
||||
|
||||
RS::InstanceType get_base_type(RID p_rid) const;
|
||||
|
||||
bool free(RID p_rid);
|
||||
|
|
|
@ -1,235 +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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "canvas_texture_storage.h"
|
||||
#include "texture_storage.h"
|
||||
|
||||
// Until we move things into their own storage classes, also include our old class
|
||||
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
|
||||
|
||||
using namespace RendererRD;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// CanvasTexture
|
||||
|
||||
void CanvasTexture::clear_sets() {
|
||||
if (cleared_cache) {
|
||||
return;
|
||||
}
|
||||
for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
|
||||
for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
|
||||
if (RD::get_singleton()->uniform_set_is_valid(uniform_sets[i][j])) {
|
||||
RD::get_singleton()->free(uniform_sets[i][j]);
|
||||
uniform_sets[i][j] = RID();
|
||||
}
|
||||
}
|
||||
}
|
||||
cleared_cache = true;
|
||||
}
|
||||
|
||||
CanvasTexture::~CanvasTexture() {
|
||||
clear_sets();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// CanvasTextureStorage
|
||||
|
||||
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);
|
||||
ERR_FAIL_NULL(ct);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ct->clear_sets();
|
||||
}
|
||||
|
||||
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);
|
||||
ERR_FAIL_NULL(ct);
|
||||
|
||||
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;
|
||||
ct->clear_sets();
|
||||
}
|
||||
|
||||
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);
|
||||
ERR_FAIL_NULL(ct);
|
||||
|
||||
ct->texture_filter = p_filter;
|
||||
ct->clear_sets();
|
||||
}
|
||||
|
||||
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);
|
||||
ERR_FAIL_NULL(ct);
|
||||
ct->texture_repeat = p_repeat;
|
||||
ct->clear_sets();
|
||||
}
|
||||
|
||||
bool CanvasTextureStorage::canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular) {
|
||||
RendererStorageRD *storage = RendererStorageRD::base_singleton;
|
||||
|
||||
CanvasTexture *ct = nullptr;
|
||||
TextureStorage *texture_storage = TextureStorage::get_singleton();
|
||||
Texture *t = texture_storage->get_texture(p_texture);
|
||||
|
||||
// TODO once we have our texture storage split off we'll look into moving this code into canvas_texture
|
||||
|
||||
if (t) {
|
||||
//regular texture
|
||||
if (!t->canvas_texture) {
|
||||
t->canvas_texture = memnew(CanvasTexture);
|
||||
t->canvas_texture->diffuse = p_texture;
|
||||
}
|
||||
|
||||
ct = t->canvas_texture;
|
||||
} else {
|
||||
ct = get_canvas_texture(p_texture);
|
||||
}
|
||||
|
||||
if (!ct) {
|
||||
return false; //invalid texture RID
|
||||
}
|
||||
|
||||
RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter;
|
||||
ERR_FAIL_COND_V(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, false);
|
||||
|
||||
RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat;
|
||||
ERR_FAIL_COND_V(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, false);
|
||||
|
||||
RID uniform_set = ct->uniform_sets[filter][repeat];
|
||||
if (!RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
|
||||
//create and update
|
||||
Vector<RD::Uniform> uniforms;
|
||||
{ //diffuse
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.binding = 0;
|
||||
|
||||
t = texture_storage->get_texture(ct->diffuse);
|
||||
if (!t) {
|
||||
u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
|
||||
ct->size_cache = Size2i(1, 1);
|
||||
} else {
|
||||
u.append_id(t->rd_texture);
|
||||
ct->size_cache = Size2i(t->width_2d, t->height_2d);
|
||||
}
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{ //normal
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.binding = 1;
|
||||
|
||||
t = texture_storage->get_texture(ct->normal_map);
|
||||
if (!t) {
|
||||
u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_NORMAL));
|
||||
ct->use_normal_cache = false;
|
||||
} else {
|
||||
u.append_id(t->rd_texture);
|
||||
ct->use_normal_cache = true;
|
||||
}
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{ //specular
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
u.binding = 2;
|
||||
|
||||
t = texture_storage->get_texture(ct->specular);
|
||||
if (!t) {
|
||||
u.append_id(texture_storage->texture_rd_get_default(DEFAULT_RD_TEXTURE_WHITE));
|
||||
ct->use_specular_cache = false;
|
||||
} else {
|
||||
u.append_id(t->rd_texture);
|
||||
ct->use_specular_cache = true;
|
||||
}
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{ //sampler
|
||||
RD::Uniform u;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
|
||||
u.binding = 3;
|
||||
u.append_id(storage->sampler_rd_get_default(filter, repeat));
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, p_base_shader, p_base_set);
|
||||
ct->uniform_sets[filter][repeat] = uniform_set;
|
||||
ct->cleared_cache = false;
|
||||
}
|
||||
|
||||
r_uniform_set = uniform_set;
|
||||
r_size = ct->size_cache;
|
||||
r_specular_shininess = ct->specular_color;
|
||||
r_use_normal = ct->use_normal_cache;
|
||||
r_use_specular = ct->use_specular_cache;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,90 +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_RD_H
|
||||
#define CANVAS_TEXTURE_STORAGE_RD_H
|
||||
|
||||
#include "core/templates/rid_owner.h"
|
||||
#include "servers/rendering/storage/canvas_texture_storage.h"
|
||||
|
||||
namespace RendererRD {
|
||||
|
||||
class CanvasTexture {
|
||||
public:
|
||||
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;
|
||||
RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
|
||||
|
||||
Size2i size_cache = Size2i(1, 1);
|
||||
bool use_normal_cache = false;
|
||||
bool use_specular_cache = false;
|
||||
bool cleared_cache = true;
|
||||
|
||||
void clear_sets();
|
||||
~CanvasTexture();
|
||||
};
|
||||
|
||||
class CanvasTextureStorage : public RendererCanvasTextureStorage {
|
||||
private:
|
||||
static CanvasTextureStorage *singleton;
|
||||
|
||||
RID_Owner<RendererRD::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;
|
||||
|
||||
bool canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular);
|
||||
};
|
||||
|
||||
} // namespace RendererRD
|
||||
|
||||
#endif // !CANVAS_TEXTURE_STORAGE_RD_H
|
|
@ -1,437 +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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "decal_atlas_storage.h"
|
||||
#include "texture_storage.h"
|
||||
|
||||
// Should be able to remove this once we move effects into their own file and include the correct effects
|
||||
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
|
||||
|
||||
using namespace RendererRD;
|
||||
|
||||
DecalAtlasStorage *DecalAtlasStorage::singleton = nullptr;
|
||||
|
||||
DecalAtlasStorage *DecalAtlasStorage::get_singleton() {
|
||||
return singleton;
|
||||
}
|
||||
|
||||
DecalAtlasStorage::DecalAtlasStorage() {
|
||||
singleton = this;
|
||||
|
||||
{ // default atlas texture
|
||||
RD::TextureFormat tformat;
|
||||
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
tformat.width = 4;
|
||||
tformat.height = 4;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
|
||||
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
|
||||
Vector<uint8_t> pv;
|
||||
pv.resize(16 * 4);
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
pv.set(i * 4 + 0, 0);
|
||||
pv.set(i * 4 + 1, 0);
|
||||
pv.set(i * 4 + 2, 0);
|
||||
pv.set(i * 4 + 3, 255);
|
||||
}
|
||||
|
||||
{
|
||||
//take the chance and initialize decal atlas to something
|
||||
Vector<Vector<uint8_t>> vpv;
|
||||
vpv.push_back(pv);
|
||||
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
|
||||
decal_atlas.texture_srgb = decal_atlas.texture;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecalAtlasStorage::~DecalAtlasStorage() {
|
||||
if (decal_atlas.textures.size()) {
|
||||
ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
|
||||
}
|
||||
|
||||
if (decal_atlas.texture.is_valid()) {
|
||||
RD::get_singleton()->free(decal_atlas.texture);
|
||||
}
|
||||
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
RID DecalAtlasStorage::decal_atlas_get_texture() const {
|
||||
return decal_atlas.texture;
|
||||
}
|
||||
|
||||
RID DecalAtlasStorage::decal_atlas_get_texture_srgb() const {
|
||||
return decal_atlas.texture_srgb;
|
||||
}
|
||||
|
||||
RID DecalAtlasStorage::decal_allocate() {
|
||||
return decal_owner.allocate_rid();
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_initialize(RID p_decal) {
|
||||
decal_owner.initialize_rid(p_decal, Decal());
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_free(RID p_rid) {
|
||||
Decal *decal = decal_owner.get_or_null(p_rid);
|
||||
for (int i = 0; i < RS::DECAL_TEXTURE_MAX; i++) {
|
||||
if (decal->textures[i].is_valid() && TextureStorage::get_singleton()->owns_texture(decal->textures[i])) {
|
||||
texture_remove_from_decal_atlas(decal->textures[i]);
|
||||
}
|
||||
}
|
||||
decal->dependency.deleted_notify(p_rid);
|
||||
decal_owner.free(p_rid);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->extents = p_extents;
|
||||
decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
ERR_FAIL_INDEX(p_type, RS::DECAL_TEXTURE_MAX);
|
||||
|
||||
if (decal->textures[p_type] == p_texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
ERR_FAIL_COND(p_texture.is_valid() && !TextureStorage::get_singleton()->owns_texture(p_texture));
|
||||
|
||||
if (decal->textures[p_type].is_valid() && TextureStorage::get_singleton()->owns_texture(decal->textures[p_type])) {
|
||||
texture_remove_from_decal_atlas(decal->textures[p_type]);
|
||||
}
|
||||
|
||||
decal->textures[p_type] = p_texture;
|
||||
|
||||
if (decal->textures[p_type].is_valid()) {
|
||||
texture_add_to_decal_atlas(decal->textures[p_type]);
|
||||
}
|
||||
|
||||
decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_DECAL);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->emission_energy = p_energy;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->albedo_mix = p_mix;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->modulate = p_modulate;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->cull_mask = p_layers;
|
||||
decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->distance_fade = p_enabled;
|
||||
decal->distance_fade_begin = p_begin;
|
||||
decal->distance_fade_length = p_length;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->upper_fade = p_above;
|
||||
decal->lower_fade = p_below;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND(!decal);
|
||||
decal->normal_fade = p_fade;
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_atlas_mark_dirty_on_texture(RID p_texture) {
|
||||
if (decal_atlas.textures.has(p_texture)) {
|
||||
//belongs to decal atlas..
|
||||
|
||||
decal_atlas.dirty = true; //mark it dirty since it was most likely modified
|
||||
}
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::decal_atlas_remove_texture(RID p_texture) {
|
||||
if (decal_atlas.textures.has(p_texture)) {
|
||||
decal_atlas.textures.erase(p_texture);
|
||||
//there is not much a point of making it dirty, just let it be.
|
||||
}
|
||||
}
|
||||
|
||||
AABB DecalAtlasStorage::decal_get_aabb(RID p_decal) const {
|
||||
Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
ERR_FAIL_COND_V(!decal, AABB());
|
||||
|
||||
return AABB(-decal->extents, decal->extents * 2.0);
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::update_decal_atlas() {
|
||||
EffectsRD *effects = RendererStorageRD::base_singleton->get_effects();
|
||||
|
||||
if (!decal_atlas.dirty) {
|
||||
return; //nothing to do
|
||||
}
|
||||
|
||||
decal_atlas.dirty = false;
|
||||
|
||||
if (decal_atlas.texture.is_valid()) {
|
||||
RD::get_singleton()->free(decal_atlas.texture);
|
||||
decal_atlas.texture = RID();
|
||||
decal_atlas.texture_srgb = RID();
|
||||
decal_atlas.texture_mipmaps.clear();
|
||||
}
|
||||
|
||||
int border = 1 << decal_atlas.mipmaps;
|
||||
|
||||
if (decal_atlas.textures.size()) {
|
||||
//generate atlas
|
||||
Vector<DecalAtlas::SortItem> itemsv;
|
||||
itemsv.resize(decal_atlas.textures.size());
|
||||
int base_size = 8;
|
||||
const RID *K = nullptr;
|
||||
|
||||
int idx = 0;
|
||||
while ((K = decal_atlas.textures.next(K))) {
|
||||
DecalAtlas::SortItem &si = itemsv.write[idx];
|
||||
|
||||
Texture *src_tex = TextureStorage::get_singleton()->get_texture(*K);
|
||||
|
||||
si.size.width = (src_tex->width / border) + 1;
|
||||
si.size.height = (src_tex->height / border) + 1;
|
||||
si.pixel_size = Size2i(src_tex->width, src_tex->height);
|
||||
|
||||
if (base_size < si.size.width) {
|
||||
base_size = nearest_power_of_2_templated(si.size.width);
|
||||
}
|
||||
|
||||
si.texture = *K;
|
||||
idx++;
|
||||
}
|
||||
|
||||
//sort items by size
|
||||
itemsv.sort();
|
||||
|
||||
//attempt to create atlas
|
||||
int item_count = itemsv.size();
|
||||
DecalAtlas::SortItem *items = itemsv.ptrw();
|
||||
|
||||
int atlas_height = 0;
|
||||
|
||||
while (true) {
|
||||
Vector<int> v_offsetsv;
|
||||
v_offsetsv.resize(base_size);
|
||||
|
||||
int *v_offsets = v_offsetsv.ptrw();
|
||||
memset(v_offsets, 0, sizeof(int) * base_size);
|
||||
|
||||
int max_height = 0;
|
||||
|
||||
for (int i = 0; i < item_count; i++) {
|
||||
//best fit
|
||||
DecalAtlas::SortItem &si = items[i];
|
||||
int best_idx = -1;
|
||||
int best_height = 0x7FFFFFFF;
|
||||
for (int j = 0; j <= base_size - si.size.width; j++) {
|
||||
int height = 0;
|
||||
for (int k = 0; k < si.size.width; k++) {
|
||||
int h = v_offsets[k + j];
|
||||
if (h > height) {
|
||||
height = h;
|
||||
if (height > best_height) {
|
||||
break; //already bad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (height < best_height) {
|
||||
best_height = height;
|
||||
best_idx = j;
|
||||
}
|
||||
}
|
||||
|
||||
//update
|
||||
for (int k = 0; k < si.size.width; k++) {
|
||||
v_offsets[k + best_idx] = best_height + si.size.height;
|
||||
}
|
||||
|
||||
si.pos.x = best_idx;
|
||||
si.pos.y = best_height;
|
||||
|
||||
if (si.pos.y + si.size.height > max_height) {
|
||||
max_height = si.pos.y + si.size.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (max_height <= base_size * 2) {
|
||||
atlas_height = max_height;
|
||||
break; //good ratio, break;
|
||||
}
|
||||
|
||||
base_size *= 2;
|
||||
}
|
||||
|
||||
decal_atlas.size.width = base_size * border;
|
||||
decal_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
|
||||
|
||||
for (int i = 0; i < item_count; i++) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
|
||||
t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
|
||||
t->uv_rect.size = items[i].pixel_size;
|
||||
|
||||
t->uv_rect.position /= Size2(decal_atlas.size);
|
||||
t->uv_rect.size /= Size2(decal_atlas.size);
|
||||
}
|
||||
} else {
|
||||
//use border as size, so it at least has enough mipmaps
|
||||
decal_atlas.size.width = border;
|
||||
decal_atlas.size.height = border;
|
||||
}
|
||||
|
||||
//blit textures
|
||||
|
||||
RD::TextureFormat tformat;
|
||||
tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
|
||||
tformat.width = decal_atlas.size.width;
|
||||
tformat.height = decal_atlas.size.height;
|
||||
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
|
||||
tformat.texture_type = RD::TEXTURE_TYPE_2D;
|
||||
tformat.mipmaps = decal_atlas.mipmaps;
|
||||
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_UNORM);
|
||||
tformat.shareable_formats.push_back(RD::DATA_FORMAT_R8G8B8A8_SRGB);
|
||||
|
||||
decal_atlas.texture = RD::get_singleton()->texture_create(tformat, RD::TextureView());
|
||||
RD::get_singleton()->texture_clear(decal_atlas.texture, Color(0, 0, 0, 0), 0, decal_atlas.mipmaps, 0, 1);
|
||||
|
||||
{
|
||||
//create the framebuffer
|
||||
|
||||
Size2i s = decal_atlas.size;
|
||||
|
||||
for (int i = 0; i < decal_atlas.mipmaps; i++) {
|
||||
DecalAtlas::MipMap mm;
|
||||
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), decal_atlas.texture, 0, i);
|
||||
Vector<RID> fb;
|
||||
fb.push_back(mm.texture);
|
||||
mm.fb = RD::get_singleton()->framebuffer_create(fb);
|
||||
mm.size = s;
|
||||
decal_atlas.texture_mipmaps.push_back(mm);
|
||||
|
||||
s.width = MAX(1, s.width >> 1);
|
||||
s.height = MAX(1, s.height >> 1);
|
||||
}
|
||||
{
|
||||
//create the SRGB variant
|
||||
RD::TextureView rd_view;
|
||||
rd_view.format_override = RD::DATA_FORMAT_R8G8B8A8_SRGB;
|
||||
decal_atlas.texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, decal_atlas.texture);
|
||||
}
|
||||
}
|
||||
|
||||
RID prev_texture;
|
||||
for (int i = 0; i < decal_atlas.texture_mipmaps.size(); i++) {
|
||||
const DecalAtlas::MipMap &mm = decal_atlas.texture_mipmaps[i];
|
||||
|
||||
Color clear_color(0, 0, 0, 0);
|
||||
|
||||
if (decal_atlas.textures.size()) {
|
||||
if (i == 0) {
|
||||
Vector<Color> cc;
|
||||
cc.push_back(clear_color);
|
||||
|
||||
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
|
||||
|
||||
const RID *K = nullptr;
|
||||
while ((K = decal_atlas.textures.next(K))) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K);
|
||||
Texture *src_tex = TextureStorage::get_singleton()->get_texture(*K);
|
||||
effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0);
|
||||
}
|
||||
|
||||
RD::get_singleton()->draw_list_end();
|
||||
|
||||
prev_texture = mm.texture;
|
||||
} else {
|
||||
effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
|
||||
prev_texture = mm.texture;
|
||||
}
|
||||
} else {
|
||||
RD::get_singleton()->texture_clear(mm.texture, clear_color, 0, 1, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
|
||||
if (!decal_atlas.textures.has(p_texture)) {
|
||||
DecalAtlas::Texture t;
|
||||
t.users = 1;
|
||||
t.panorama_to_dp_users = p_panorama_to_dp ? 1 : 0;
|
||||
decal_atlas.textures[p_texture] = t;
|
||||
decal_atlas.dirty = true;
|
||||
} else {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
|
||||
t->users++;
|
||||
if (p_panorama_to_dp) {
|
||||
t->panorama_to_dp_users++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecalAtlasStorage::texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
|
||||
ERR_FAIL_COND(!t);
|
||||
t->users--;
|
||||
if (p_panorama_to_dp) {
|
||||
ERR_FAIL_COND(t->panorama_to_dp_users == 0);
|
||||
t->panorama_to_dp_users--;
|
||||
}
|
||||
if (t->users == 0) {
|
||||
decal_atlas.textures.erase(p_texture);
|
||||
//do not mark it dirty, there is no need to since it remains working
|
||||
}
|
||||
}
|
|
@ -1,211 +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_RD_H
|
||||
#define DECAL_ATLAS_STORAGE_RD_H
|
||||
|
||||
#include "core/templates/rid_owner.h"
|
||||
#include "servers/rendering/renderer_storage.h"
|
||||
#include "servers/rendering/storage/decal_atlas_storage.h"
|
||||
|
||||
namespace RendererRD {
|
||||
|
||||
struct DecalAtlas {
|
||||
struct Texture {
|
||||
int panorama_to_dp_users;
|
||||
int users;
|
||||
Rect2 uv_rect;
|
||||
};
|
||||
|
||||
struct SortItem {
|
||||
RID texture;
|
||||
Size2i pixel_size;
|
||||
Size2i size;
|
||||
Point2i pos;
|
||||
|
||||
bool operator<(const SortItem &p_item) const {
|
||||
//sort larger to smaller
|
||||
if (size.height == p_item.size.height) {
|
||||
return size.width > p_item.size.width;
|
||||
} else {
|
||||
return size.height > p_item.size.height;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
HashMap<RID, Texture> textures;
|
||||
bool dirty = true;
|
||||
int mipmaps = 5;
|
||||
|
||||
RID texture;
|
||||
RID texture_srgb;
|
||||
struct MipMap {
|
||||
RID fb;
|
||||
RID texture;
|
||||
Size2i size;
|
||||
};
|
||||
Vector<MipMap> texture_mipmaps;
|
||||
|
||||
Size2i size;
|
||||
};
|
||||
|
||||
struct Decal {
|
||||
Vector3 extents = Vector3(1, 1, 1);
|
||||
RID textures[RS::DECAL_TEXTURE_MAX];
|
||||
float emission_energy = 1.0;
|
||||
float albedo_mix = 1.0;
|
||||
Color modulate = Color(1, 1, 1, 1);
|
||||
uint32_t cull_mask = (1 << 20) - 1;
|
||||
float upper_fade = 0.3;
|
||||
float lower_fade = 0.3;
|
||||
bool distance_fade = false;
|
||||
float distance_fade_begin = 10;
|
||||
float distance_fade_length = 1;
|
||||
float normal_fade = 0.0;
|
||||
|
||||
RendererStorage::Dependency dependency;
|
||||
};
|
||||
|
||||
class DecalAtlasStorage : public RendererDecalAtlasStorage {
|
||||
private:
|
||||
static DecalAtlasStorage *singleton;
|
||||
|
||||
DecalAtlas decal_atlas;
|
||||
|
||||
mutable RID_Owner<Decal, true> decal_owner;
|
||||
|
||||
public:
|
||||
static DecalAtlasStorage *get_singleton();
|
||||
|
||||
void update_decal_atlas();
|
||||
|
||||
DecalAtlasStorage();
|
||||
virtual ~DecalAtlasStorage();
|
||||
|
||||
Decal *get_decal(RID p_rid) { return decal_owner.get_or_null(p_rid); };
|
||||
bool owns_decal(RID p_rid) { return decal_owner.owns(p_rid); };
|
||||
|
||||
RID decal_atlas_get_texture() const;
|
||||
RID decal_atlas_get_texture_srgb() const;
|
||||
_FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
|
||||
if (!t) {
|
||||
return Rect2();
|
||||
}
|
||||
|
||||
return t->uv_rect;
|
||||
}
|
||||
|
||||
virtual RID decal_allocate() override;
|
||||
virtual void decal_initialize(RID p_decal) override;
|
||||
virtual void decal_free(RID p_rid) override;
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
|
||||
|
||||
void decal_atlas_mark_dirty_on_texture(RID p_texture);
|
||||
void decal_atlas_remove_texture(RID p_texture);
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
|
||||
|
||||
_FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->extents;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->textures[p_texture];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color decal_get_modulate(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->modulate;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->emission_energy;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->albedo_mix;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->cull_mask;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->upper_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->lower_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->normal_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade_begin;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade_length;
|
||||
}
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const override;
|
||||
};
|
||||
|
||||
} // namespace RendererRD
|
||||
|
||||
#endif // !DECAL_ATLAS_STORAGE_RD_H
|
File diff suppressed because it is too large
Load diff
|
@ -31,8 +31,9 @@
|
|||
#ifndef TEXTURE_STORAGE_RD_H
|
||||
#define TEXTURE_STORAGE_RD_H
|
||||
|
||||
#include "canvas_texture_storage.h"
|
||||
#include "core/templates/rid_owner.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_storage.h"
|
||||
#include "servers/rendering/storage/texture_storage.h"
|
||||
|
||||
namespace RendererRD {
|
||||
|
@ -54,6 +55,27 @@ enum DefaultRDTexture {
|
|||
DEFAULT_RD_TEXTURE_MAX
|
||||
};
|
||||
|
||||
class CanvasTexture {
|
||||
public:
|
||||
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;
|
||||
RID uniform_sets[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX];
|
||||
|
||||
Size2i size_cache = Size2i(1, 1);
|
||||
bool use_normal_cache = false;
|
||||
bool use_specular_cache = false;
|
||||
bool cleared_cache = true;
|
||||
|
||||
void clear_sets();
|
||||
~CanvasTexture();
|
||||
};
|
||||
|
||||
class Texture {
|
||||
public:
|
||||
enum Type {
|
||||
|
@ -118,10 +140,138 @@ public:
|
|||
void cleanup();
|
||||
};
|
||||
|
||||
struct DecalAtlas {
|
||||
struct Texture {
|
||||
int panorama_to_dp_users;
|
||||
int users;
|
||||
Rect2 uv_rect;
|
||||
};
|
||||
|
||||
struct SortItem {
|
||||
RID texture;
|
||||
Size2i pixel_size;
|
||||
Size2i size;
|
||||
Point2i pos;
|
||||
|
||||
bool operator<(const SortItem &p_item) const {
|
||||
//sort larger to smaller
|
||||
if (size.height == p_item.size.height) {
|
||||
return size.width > p_item.size.width;
|
||||
} else {
|
||||
return size.height > p_item.size.height;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
HashMap<RID, Texture> textures;
|
||||
bool dirty = true;
|
||||
int mipmaps = 5;
|
||||
|
||||
RID texture;
|
||||
RID texture_srgb;
|
||||
struct MipMap {
|
||||
RID fb;
|
||||
RID texture;
|
||||
Size2i size;
|
||||
};
|
||||
Vector<MipMap> texture_mipmaps;
|
||||
|
||||
Size2i size;
|
||||
};
|
||||
|
||||
struct Decal {
|
||||
Vector3 extents = Vector3(1, 1, 1);
|
||||
RID textures[RS::DECAL_TEXTURE_MAX];
|
||||
float emission_energy = 1.0;
|
||||
float albedo_mix = 1.0;
|
||||
Color modulate = Color(1, 1, 1, 1);
|
||||
uint32_t cull_mask = (1 << 20) - 1;
|
||||
float upper_fade = 0.3;
|
||||
float lower_fade = 0.3;
|
||||
bool distance_fade = false;
|
||||
float distance_fade_begin = 10;
|
||||
float distance_fade_length = 1;
|
||||
float normal_fade = 0.0;
|
||||
|
||||
RendererStorage::Dependency dependency;
|
||||
};
|
||||
|
||||
struct RenderTarget {
|
||||
Size2i size;
|
||||
uint32_t view_count;
|
||||
RID framebuffer;
|
||||
RID color;
|
||||
|
||||
//used for retrieving from CPU
|
||||
RD::DataFormat color_format = RD::DATA_FORMAT_R4G4_UNORM_PACK8;
|
||||
RD::DataFormat color_format_srgb = RD::DATA_FORMAT_R4G4_UNORM_PACK8;
|
||||
Image::Format image_format = Image::FORMAT_L8;
|
||||
|
||||
bool flags[RendererTextureStorage::RENDER_TARGET_FLAG_MAX];
|
||||
|
||||
bool sdf_enabled = false;
|
||||
|
||||
RID backbuffer; //used for effects
|
||||
RID backbuffer_fb;
|
||||
RID backbuffer_mipmap0;
|
||||
|
||||
Vector<RID> backbuffer_mipmaps;
|
||||
|
||||
RID framebuffer_uniform_set;
|
||||
RID backbuffer_uniform_set;
|
||||
|
||||
RID sdf_buffer_write;
|
||||
RID sdf_buffer_write_fb;
|
||||
RID sdf_buffer_process[2];
|
||||
RID sdf_buffer_read;
|
||||
RID sdf_buffer_process_uniform_sets[2];
|
||||
RS::ViewportSDFOversize sdf_oversize = RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT;
|
||||
RS::ViewportSDFScale sdf_scale = RS::VIEWPORT_SDF_SCALE_50_PERCENT;
|
||||
Size2i process_size;
|
||||
|
||||
//texture generated for this owner (nor RD).
|
||||
RID texture;
|
||||
bool was_used;
|
||||
|
||||
//clear request
|
||||
bool clear_requested;
|
||||
Color clear_color;
|
||||
};
|
||||
|
||||
struct RenderTargetSDF {
|
||||
enum {
|
||||
SHADER_LOAD,
|
||||
SHADER_LOAD_SHRINK,
|
||||
SHADER_PROCESS,
|
||||
SHADER_PROCESS_OPTIMIZED,
|
||||
SHADER_STORE,
|
||||
SHADER_STORE_SHRINK,
|
||||
SHADER_MAX
|
||||
};
|
||||
|
||||
struct PushConstant {
|
||||
int32_t size[2];
|
||||
int32_t stride;
|
||||
int32_t shift;
|
||||
int32_t base_size[2];
|
||||
int32_t pad[2];
|
||||
};
|
||||
|
||||
CanvasSdfShaderRD shader;
|
||||
RID shader_version;
|
||||
RID pipelines[SHADER_MAX];
|
||||
};
|
||||
|
||||
class TextureStorage : public RendererTextureStorage {
|
||||
private:
|
||||
static TextureStorage *singleton;
|
||||
|
||||
/* Canvas Texture API */
|
||||
|
||||
RID_Owner<RendererRD::CanvasTexture, true> canvas_texture_owner;
|
||||
|
||||
/* Texture API */
|
||||
|
||||
//textures can be created from threads, so this RID_Owner is thread safe
|
||||
mutable RID_Owner<Texture, true> texture_owner;
|
||||
|
||||
|
@ -145,6 +295,25 @@ private:
|
|||
Ref<Image> _validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format);
|
||||
void _texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0, bool p_immediate = false);
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
DecalAtlas decal_atlas;
|
||||
|
||||
mutable RID_Owner<Decal, true> decal_owner;
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
mutable RID_Owner<RenderTarget> render_target_owner;
|
||||
|
||||
void _clear_render_target(RenderTarget *rt);
|
||||
void _update_render_target(RenderTarget *rt);
|
||||
void _create_render_target_backbuffer(RenderTarget *rt);
|
||||
void _render_target_allocate_sdf(RenderTarget *rt);
|
||||
void _render_target_clear_sdf(RenderTarget *rt);
|
||||
Rect2i _render_target_get_sdf_rect(const RenderTarget *rt) const;
|
||||
|
||||
RenderTargetSDF rt_sdf;
|
||||
|
||||
public:
|
||||
static TextureStorage *get_singleton();
|
||||
|
||||
|
@ -157,6 +326,25 @@ public:
|
|||
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;
|
||||
|
||||
bool canvas_texture_get_uniform_set(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, RID p_base_shader, int p_base_set, RID &r_uniform_set, Size2i &r_size, Color &r_specular_shininess, bool &r_use_normal, bool &r_use_specular);
|
||||
|
||||
/* 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); };
|
||||
|
||||
|
@ -224,6 +412,153 @@ public:
|
|||
}
|
||||
return Size2i(tex->width_2d, tex->height_2d);
|
||||
}
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
void update_decal_atlas();
|
||||
|
||||
Decal *get_decal(RID p_rid) { return decal_owner.get_or_null(p_rid); };
|
||||
bool owns_decal(RID p_rid) { return decal_owner.owns(p_rid); };
|
||||
|
||||
RID decal_atlas_get_texture() const;
|
||||
RID decal_atlas_get_texture_srgb() const;
|
||||
_FORCE_INLINE_ Rect2 decal_atlas_get_texture_rect(RID p_texture) {
|
||||
DecalAtlas::Texture *t = decal_atlas.textures.getptr(p_texture);
|
||||
if (!t) {
|
||||
return Rect2();
|
||||
}
|
||||
|
||||
return t->uv_rect;
|
||||
}
|
||||
|
||||
virtual RID decal_allocate() override;
|
||||
virtual void decal_initialize(RID p_decal) override;
|
||||
virtual void decal_free(RID p_rid) override;
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) override;
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) override;
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) override;
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) override;
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) override;
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) override;
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) override;
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) override;
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) override;
|
||||
|
||||
void decal_atlas_mark_dirty_on_texture(RID p_texture);
|
||||
void decal_atlas_remove_texture(RID p_texture);
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override;
|
||||
|
||||
_FORCE_INLINE_ Vector3 decal_get_extents(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->extents;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID decal_get_texture(RID p_decal, RS::DecalTexture p_texture) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->textures[p_texture];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Color decal_get_modulate(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->modulate;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_emission_energy(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->emission_energy;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_albedo_mix(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->albedo_mix;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t decal_get_cull_mask(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->cull_mask;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_upper_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->upper_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_lower_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->lower_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_normal_fade(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->normal_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool decal_is_distance_fade_enabled(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_distance_fade_begin(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade_begin;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float decal_get_distance_fade_length(RID p_decal) {
|
||||
const Decal *decal = decal_owner.get_or_null(p_decal);
|
||||
return decal->distance_fade_length;
|
||||
}
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const override;
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
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); };
|
||||
|
||||
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;
|
||||
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;
|
||||
virtual void render_target_set_as_unused(RID p_render_target) override;
|
||||
|
||||
void render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps);
|
||||
void render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color);
|
||||
void render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region);
|
||||
RID render_target_get_back_buffer_uniform_set(RID p_render_target, RID p_base_shader);
|
||||
|
||||
virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) override;
|
||||
virtual bool render_target_is_clear_requested(RID p_render_target) override;
|
||||
virtual Color render_target_get_clear_request_color(RID p_render_target) override;
|
||||
virtual void render_target_disable_clear_request(RID p_render_target) override;
|
||||
virtual void render_target_do_clear_request(RID p_render_target) override;
|
||||
|
||||
virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) override;
|
||||
RID render_target_get_sdf_texture(RID p_render_target);
|
||||
RID render_target_get_sdf_framebuffer(RID p_render_target);
|
||||
void render_target_sdf_process(RID p_render_target);
|
||||
virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const override;
|
||||
virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) override;
|
||||
bool render_target_is_sdf_enabled(RID p_render_target) const;
|
||||
|
||||
Size2 render_target_get_size(RID p_render_target);
|
||||
RID render_target_get_rd_framebuffer(RID p_render_target);
|
||||
RID render_target_get_rd_texture(RID p_render_target);
|
||||
RID render_target_get_rd_backbuffer(RID p_render_target);
|
||||
RID render_target_get_rd_backbuffer_framebuffer(RID p_render_target);
|
||||
|
||||
RID render_target_get_framebuffer_uniform_set(RID p_render_target);
|
||||
RID render_target_get_backbuffer_uniform_set(RID p_render_target);
|
||||
|
||||
void render_target_set_framebuffer_uniform_set(RID p_render_target, RID p_uniform_set);
|
||||
void render_target_set_backbuffer_uniform_set(RID p_render_target, RID p_uniform_set);
|
||||
};
|
||||
|
||||
} // namespace RendererRD
|
||||
|
|
|
@ -1887,7 +1887,7 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
|
|||
|
||||
} break;
|
||||
case RenderingServer::INSTANCE_DECAL: {
|
||||
new_aabb = RSG::decal_atlas_storage->decal_get_aabb(p_instance->base);
|
||||
new_aabb = RSG::texture_storage->decal_get_aabb(p_instance->base);
|
||||
|
||||
} break;
|
||||
case RenderingServer::INSTANCE_VOXEL_GI: {
|
||||
|
|
|
@ -360,33 +360,6 @@ public:
|
|||
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform3D &p_transform) = 0;
|
||||
virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0;
|
||||
|
||||
/* RENDER TARGET */
|
||||
|
||||
enum RenderTargetFlags {
|
||||
RENDER_TARGET_TRANSPARENT,
|
||||
RENDER_TARGET_DIRECT_TO_SCREEN,
|
||||
RENDER_TARGET_FLAG_MAX
|
||||
};
|
||||
|
||||
virtual RID render_target_create() = 0;
|
||||
virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0;
|
||||
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) = 0;
|
||||
virtual RID render_target_get_texture(RID p_render_target) = 0;
|
||||
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0;
|
||||
virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0;
|
||||
virtual bool render_target_was_used(RID p_render_target) = 0;
|
||||
virtual void render_target_set_as_unused(RID p_render_target) = 0;
|
||||
|
||||
virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0;
|
||||
virtual bool render_target_is_clear_requested(RID p_render_target) = 0;
|
||||
virtual Color render_target_get_clear_request_color(RID p_render_target) = 0;
|
||||
virtual void render_target_disable_clear_request(RID p_render_target) = 0;
|
||||
virtual void render_target_do_clear_request(RID p_render_target) = 0;
|
||||
|
||||
virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0;
|
||||
virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0;
|
||||
virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) = 0;
|
||||
|
||||
virtual RS::InstanceType get_base_type(RID p_rid) const = 0;
|
||||
virtual bool free(RID p_rid) = 0;
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "renderer_canvas_cull.h"
|
||||
#include "renderer_scene_cull.h"
|
||||
#include "rendering_server_globals.h"
|
||||
#include "storage/texture_storage.h"
|
||||
|
||||
static Transform2D _canvas_get_transform(RendererViewport::Viewport *p_viewport, RendererCanvasCull::Canvas *p_canvas, RendererViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) {
|
||||
Transform2D xf = p_viewport->global_transform;
|
||||
|
@ -222,7 +223,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
|||
_configure_3d_render_buffers(p_viewport);
|
||||
}
|
||||
|
||||
RSG::storage->render_target_request_clear(p_viewport->render_target, bgcolor);
|
||||
RSG::texture_storage->render_target_request_clear(p_viewport->render_target, bgcolor);
|
||||
|
||||
if (!scenario_draw_canvas_bg && can_draw_3d) {
|
||||
_draw_3d(p_viewport);
|
||||
|
@ -243,7 +244,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
|||
if (p_viewport->sdf_active) {
|
||||
//process SDF
|
||||
|
||||
Rect2 sdf_rect = RSG::storage->render_target_get_sdf_rect(p_viewport->render_target);
|
||||
Rect2 sdf_rect = RSG::texture_storage->render_target_get_sdf_rect(p_viewport->render_target);
|
||||
|
||||
RendererCanvasRender::LightOccluderInstance *occluders = nullptr;
|
||||
|
||||
|
@ -266,11 +267,11 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
|||
}
|
||||
|
||||
RSG::canvas_render->render_sdf(p_viewport->render_target, occluders);
|
||||
RSG::storage->render_target_mark_sdf_enabled(p_viewport->render_target, true);
|
||||
RSG::texture_storage->render_target_mark_sdf_enabled(p_viewport->render_target, true);
|
||||
|
||||
p_viewport->sdf_active = false; // if used, gets set active again
|
||||
} else {
|
||||
RSG::storage->render_target_mark_sdf_enabled(p_viewport->render_target, false);
|
||||
RSG::texture_storage->render_target_mark_sdf_enabled(p_viewport->render_target, false);
|
||||
}
|
||||
|
||||
Rect2 shadow_rect;
|
||||
|
@ -529,9 +530,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
|
|||
}
|
||||
}
|
||||
|
||||
if (RSG::storage->render_target_is_clear_requested(p_viewport->render_target)) {
|
||||
if (RSG::texture_storage->render_target_is_clear_requested(p_viewport->render_target)) {
|
||||
//was never cleared in the end, force clear it
|
||||
RSG::storage->render_target_do_clear_request(p_viewport->render_target);
|
||||
RSG::texture_storage->render_target_do_clear_request(p_viewport->render_target);
|
||||
}
|
||||
|
||||
if (p_viewport->measure_render_time) {
|
||||
|
@ -595,7 +596,7 @@ void RendererViewport::draw_viewports() {
|
|||
vp->occlusion_buffer_dirty = vp->occlusion_buffer_dirty || (vp->size != xr_size);
|
||||
vp->size = xr_size;
|
||||
uint32_t view_count = xr_interface->get_view_count();
|
||||
RSG::storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
|
||||
RSG::texture_storage->render_target_set_size(vp->render_target, vp->size.x, vp->size.y, view_count);
|
||||
|
||||
// Inform xr interface we're about to render its viewport, if this returns false we don't render
|
||||
visible = xr_interface->pre_draw_viewport(vp->render_target);
|
||||
|
@ -610,7 +611,7 @@ void RendererViewport::draw_viewports() {
|
|||
visible = true;
|
||||
}
|
||||
|
||||
if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_VISIBLE && RSG::storage->render_target_was_used(vp->render_target)) {
|
||||
if (vp->update_mode == RS::VIEWPORT_UPDATE_WHEN_VISIBLE && RSG::texture_storage->render_target_was_used(vp->render_target)) {
|
||||
visible = true;
|
||||
}
|
||||
|
||||
|
@ -641,11 +642,11 @@ void RendererViewport::draw_viewports() {
|
|||
|
||||
RENDER_TIMESTAMP("> Render Viewport " + itos(i));
|
||||
|
||||
RSG::storage->render_target_set_as_unused(vp->render_target);
|
||||
RSG::texture_storage->render_target_set_as_unused(vp->render_target);
|
||||
if (vp->use_xr && xr_interface.is_valid()) {
|
||||
// check for an external texture destination (disabled for now, not yet supported)
|
||||
// RSG::storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(leftOrMono));
|
||||
RSG::storage->render_target_set_external_texture(vp->render_target, 0);
|
||||
// RSG::texture_storage->render_target_set_external_texture(vp->render_target, xr_interface->get_external_texture_for_eye(leftOrMono));
|
||||
RSG::texture_storage->render_target_set_external_texture(vp->render_target, 0);
|
||||
|
||||
// render...
|
||||
RSG::scene->set_debug_draw_mode(vp->debug_draw);
|
||||
|
@ -667,7 +668,7 @@ void RendererViewport::draw_viewports() {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
RSG::storage->render_target_set_external_texture(vp->render_target, 0);
|
||||
RSG::texture_storage->render_target_set_external_texture(vp->render_target, 0);
|
||||
|
||||
RSG::scene->set_debug_draw_mode(vp->debug_draw);
|
||||
|
||||
|
@ -726,7 +727,7 @@ void RendererViewport::viewport_initialize(RID p_rid) {
|
|||
viewport_owner.initialize_rid(p_rid);
|
||||
Viewport *viewport = viewport_owner.get_or_null(p_rid);
|
||||
viewport->self = p_rid;
|
||||
viewport->render_target = RSG::storage->render_target_create();
|
||||
viewport->render_target = RSG::texture_storage->render_target_create();
|
||||
viewport->shadow_atlas = RSG::scene->shadow_atlas_create();
|
||||
viewport->viewport_render_direct_to_screen = false;
|
||||
|
||||
|
@ -808,7 +809,7 @@ void RendererViewport::viewport_set_size(RID p_viewport, int p_width, int p_heig
|
|||
viewport->size = Size2(p_width, p_height);
|
||||
|
||||
uint32_t view_count = viewport->get_view_count();
|
||||
RSG::storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count);
|
||||
RSG::texture_storage->render_target_set_size(viewport->render_target, p_width, p_height, view_count);
|
||||
_configure_3d_render_buffers(viewport);
|
||||
|
||||
viewport->occlusion_buffer_dirty = true;
|
||||
|
@ -849,8 +850,8 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_
|
|||
// If using OpenGL we can optimize this operation by rendering directly to system_fbo
|
||||
// instead of rendering to fbo and copying to system_fbo after
|
||||
if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
|
||||
RSG::storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y, viewport->get_view_count());
|
||||
RSG::storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y);
|
||||
RSG::texture_storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y, viewport->get_view_count());
|
||||
RSG::texture_storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y);
|
||||
}
|
||||
|
||||
viewport->viewport_to_screen_rect = p_rect;
|
||||
|
@ -858,8 +859,8 @@ void RendererViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_
|
|||
} else {
|
||||
// if render_direct_to_screen was used, reset size and position
|
||||
if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
|
||||
RSG::storage->render_target_set_position(viewport->render_target, 0, 0);
|
||||
RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
|
||||
RSG::texture_storage->render_target_set_position(viewport->render_target, 0, 0);
|
||||
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
|
||||
}
|
||||
|
||||
viewport->viewport_to_screen_rect = Rect2();
|
||||
|
@ -877,17 +878,17 @@ void RendererViewport::viewport_set_render_direct_to_screen(RID p_viewport, bool
|
|||
|
||||
// if disabled, reset render_target size and position
|
||||
if (!p_enable) {
|
||||
RSG::storage->render_target_set_position(viewport->render_target, 0, 0);
|
||||
RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
|
||||
RSG::texture_storage->render_target_set_position(viewport->render_target, 0, 0);
|
||||
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y, viewport->get_view_count());
|
||||
}
|
||||
|
||||
RSG::storage->render_target_set_flag(viewport->render_target, RendererStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
|
||||
RSG::texture_storage->render_target_set_flag(viewport->render_target, RendererTextureStorage::RENDER_TARGET_DIRECT_TO_SCREEN, p_enable);
|
||||
viewport->viewport_render_direct_to_screen = p_enable;
|
||||
|
||||
// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
|
||||
if (RSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) {
|
||||
RSG::storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y, viewport->get_view_count());
|
||||
RSG::storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y);
|
||||
RSG::texture_storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y, viewport->get_view_count());
|
||||
RSG::texture_storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -902,7 +903,7 @@ RID RendererViewport::viewport_get_texture(RID p_viewport) const {
|
|||
const Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
||||
ERR_FAIL_COND_V(!viewport, RID());
|
||||
|
||||
return RSG::storage->render_target_get_texture(viewport->render_target);
|
||||
return RSG::texture_storage->render_target_get_texture(viewport->render_target);
|
||||
}
|
||||
|
||||
RID RendererViewport::viewport_get_occluder_debug_texture(RID p_viewport) const {
|
||||
|
@ -995,7 +996,7 @@ void RendererViewport::viewport_set_transparent_background(RID p_viewport, bool
|
|||
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
RSG::storage->render_target_set_flag(viewport->render_target, RendererStorage::RENDER_TARGET_TRANSPARENT, p_enabled);
|
||||
RSG::texture_storage->render_target_set_flag(viewport->render_target, RendererTextureStorage::RENDER_TARGET_TRANSPARENT, p_enabled);
|
||||
viewport->transparent_bg = p_enabled;
|
||||
}
|
||||
|
||||
|
@ -1178,14 +1179,14 @@ void RendererViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::V
|
|||
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
RSG::storage->render_target_set_sdf_size_and_scale(viewport->render_target, p_size, p_scale);
|
||||
RSG::texture_storage->render_target_set_sdf_size_and_scale(viewport->render_target, p_size, p_scale);
|
||||
}
|
||||
|
||||
bool RendererViewport::free(RID p_rid) {
|
||||
if (viewport_owner.owns(p_rid)) {
|
||||
Viewport *viewport = viewport_owner.get_or_null(p_rid);
|
||||
|
||||
RSG::storage->free(viewport->render_target);
|
||||
RSG::texture_storage->render_target_free(viewport->render_target);
|
||||
RSG::scene->free(viewport->shadow_atlas);
|
||||
if (viewport->render_buffers.is_valid()) {
|
||||
RSG::scene->free(viewport->render_buffers);
|
||||
|
|
|
@ -398,8 +398,6 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
|
|||
RendererSceneCull *sr = memnew(RendererSceneCull);
|
||||
RSG::scene = sr;
|
||||
RSG::rasterizer = RendererCompositor::create();
|
||||
RSG::canvas_texture_storage = RSG::rasterizer->get_canvas_texture_storage();
|
||||
RSG::decal_atlas_storage = RSG::rasterizer->get_decal_atlas_storage();
|
||||
RSG::material_storage = RSG::rasterizer->get_material_storage();
|
||||
RSG::mesh_storage = RSG::rasterizer->get_mesh_storage();
|
||||
RSG::texture_storage = RSG::rasterizer->get_texture_storage();
|
||||
|
|
|
@ -399,8 +399,8 @@ public:
|
|||
#undef ServerName
|
||||
#undef server_name
|
||||
|
||||
#define ServerName RendererDecalAtlasStorage
|
||||
#define server_name RSG::decal_atlas_storage
|
||||
#define ServerName RendererTextureStorage
|
||||
#define server_name RSG::texture_storage
|
||||
|
||||
FUNCRIDSPLIT(decal)
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
|
||||
bool RenderingServerGlobals::threaded = false;
|
||||
|
||||
RendererCanvasTextureStorage *RenderingServerGlobals::canvas_texture_storage = nullptr;
|
||||
RendererDecalAtlasStorage *RenderingServerGlobals::decal_atlas_storage = nullptr;
|
||||
RendererMaterialStorage *RenderingServerGlobals::material_storage = nullptr;
|
||||
RendererMeshStorage *RenderingServerGlobals::mesh_storage = nullptr;
|
||||
RendererTextureStorage *RenderingServerGlobals::texture_storage = nullptr;
|
||||
|
|
|
@ -34,8 +34,6 @@
|
|||
#include "servers/rendering/renderer_canvas_cull.h"
|
||||
#include "servers/rendering/renderer_canvas_render.h"
|
||||
#include "servers/rendering/renderer_scene.h"
|
||||
#include "servers/rendering/storage/canvas_texture_storage.h"
|
||||
#include "servers/rendering/storage/decal_atlas_storage.h"
|
||||
#include "servers/rendering/storage/material_storage.h"
|
||||
#include "servers/rendering/storage/mesh_storage.h"
|
||||
#include "servers/rendering/storage/texture_storage.h"
|
||||
|
@ -48,11 +46,9 @@ class RenderingServerGlobals {
|
|||
public:
|
||||
static bool threaded;
|
||||
|
||||
static RendererCanvasTextureStorage *canvas_texture_storage;
|
||||
static RendererMaterialStorage *material_storage;
|
||||
static RendererMeshStorage *mesh_storage;
|
||||
static RendererTextureStorage *texture_storage;
|
||||
static RendererDecalAtlasStorage *decal_atlas_storage;
|
||||
static RendererStorage *storage;
|
||||
static RendererCanvasRender *canvas_render;
|
||||
static RendererCompositor *rasterizer;
|
||||
|
|
|
@ -1,51 +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_H
|
||||
#define CANVAS_TEXTURE_STORAGE_H
|
||||
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
class RendererCanvasTextureStorage {
|
||||
public:
|
||||
virtual ~RendererCanvasTextureStorage(){};
|
||||
|
||||
virtual RID canvas_texture_allocate() = 0;
|
||||
virtual void canvas_texture_initialize(RID p_rid) = 0;
|
||||
virtual void canvas_texture_free(RID p_rid) = 0;
|
||||
|
||||
virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0;
|
||||
virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
|
||||
|
||||
virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0;
|
||||
virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0;
|
||||
};
|
||||
|
||||
#endif // !CANVAS_TEXTURE_STORAGE_H
|
|
@ -1,60 +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_H
|
||||
#define DECAL_ATLAS_STORAGE_H
|
||||
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
class RendererDecalAtlasStorage {
|
||||
public:
|
||||
virtual ~RendererDecalAtlasStorage(){};
|
||||
|
||||
virtual RID decal_allocate() = 0;
|
||||
virtual void decal_initialize(RID p_rid) = 0;
|
||||
virtual void decal_free(RID p_rid) = 0;
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const = 0;
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
};
|
||||
|
||||
#endif // !DECAL_ATLAS_STORAGE_H
|
|
@ -35,6 +35,19 @@
|
|||
|
||||
class RendererTextureStorage {
|
||||
public:
|
||||
/* Canvas Texture API */
|
||||
|
||||
virtual RID canvas_texture_allocate() = 0;
|
||||
virtual void canvas_texture_initialize(RID p_rid) = 0;
|
||||
virtual void canvas_texture_free(RID p_rid) = 0;
|
||||
|
||||
virtual void canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) = 0;
|
||||
virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
|
||||
|
||||
virtual void canvas_texture_set_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) = 0;
|
||||
virtual void canvas_texture_set_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) = 0;
|
||||
|
||||
/* Texture API */
|
||||
virtual bool can_create_resources_async() const = 0;
|
||||
|
||||
virtual ~RendererTextureStorage(){};
|
||||
|
@ -75,6 +88,55 @@ public:
|
|||
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) = 0;
|
||||
|
||||
virtual Size2 texture_size_with_proxy(RID p_proxy) = 0;
|
||||
|
||||
/* Decal API */
|
||||
virtual RID decal_allocate() = 0;
|
||||
virtual void decal_initialize(RID p_rid) = 0;
|
||||
virtual void decal_free(RID p_rid) = 0;
|
||||
|
||||
virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) = 0;
|
||||
virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) = 0;
|
||||
virtual void decal_set_emission_energy(RID p_decal, float p_energy) = 0;
|
||||
virtual void decal_set_albedo_mix(RID p_decal, float p_mix) = 0;
|
||||
virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) = 0;
|
||||
virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) = 0;
|
||||
virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) = 0;
|
||||
virtual void decal_set_fade(RID p_decal, float p_above, float p_below) = 0;
|
||||
virtual void decal_set_normal_fade(RID p_decal, float p_fade) = 0;
|
||||
|
||||
virtual AABB decal_get_aabb(RID p_decal) const = 0;
|
||||
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
|
||||
/* RENDER TARGET */
|
||||
|
||||
enum RenderTargetFlags {
|
||||
RENDER_TARGET_TRANSPARENT,
|
||||
RENDER_TARGET_DIRECT_TO_SCREEN,
|
||||
RENDER_TARGET_FLAG_MAX
|
||||
};
|
||||
|
||||
virtual RID render_target_create() = 0;
|
||||
virtual void render_target_free(RID p_rid) = 0;
|
||||
|
||||
virtual void render_target_set_position(RID p_render_target, int p_x, int p_y) = 0;
|
||||
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) = 0;
|
||||
virtual RID render_target_get_texture(RID p_render_target) = 0;
|
||||
virtual void render_target_set_external_texture(RID p_render_target, unsigned int p_texture_id) = 0;
|
||||
virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0;
|
||||
virtual bool render_target_was_used(RID p_render_target) = 0;
|
||||
virtual void render_target_set_as_unused(RID p_render_target) = 0;
|
||||
|
||||
virtual void render_target_request_clear(RID p_render_target, const Color &p_clear_color) = 0;
|
||||
virtual bool render_target_is_clear_requested(RID p_render_target) = 0;
|
||||
virtual Color render_target_get_clear_request_color(RID p_render_target) = 0;
|
||||
virtual void render_target_disable_clear_request(RID p_render_target) = 0;
|
||||
virtual void render_target_do_clear_request(RID p_render_target) = 0;
|
||||
|
||||
virtual void render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) = 0;
|
||||
virtual Rect2i render_target_get_sdf_rect(RID p_render_target) const = 0;
|
||||
virtual void render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) = 0;
|
||||
};
|
||||
|
||||
#endif // !TEXTURE_STORAGE_H
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "xr_interface_extension.h"
|
||||
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/renderer_storage.h"
|
||||
#include "servers/rendering/rendering_server_globals.h"
|
||||
|
||||
|
@ -339,10 +340,10 @@ void XRInterfaceExtension::notification(int p_what) {
|
|||
RID XRInterfaceExtension::get_render_target_texture(RID p_render_target) {
|
||||
// In due time this will need to be enhance to return the correct INTERNAL RID for the chosen rendering engine.
|
||||
// So once a GLES driver is implemented we'll return that and the implemented plugin needs to handle this correctly too.
|
||||
RendererStorageRD *rd_storage = RendererStorageRD::base_singleton;
|
||||
ERR_FAIL_NULL_V_MSG(rd_storage, RID(), "Renderer storage not setup");
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
ERR_FAIL_NULL_V_MSG(texture_storage, RID(), "Texture storage not setup");
|
||||
|
||||
return rd_storage->render_target_get_rd_texture(p_render_target);
|
||||
return texture_storage->render_target_get_rd_texture(p_render_target);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue