Path: blob/master/drivers/gles3/storage/texture_storage.cpp
20943 views
/**************************************************************************/1/* texture_storage.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#ifdef GLES3_ENABLED3132#include "texture_storage.h"3334#include "../effects/copy_effects.h"35#include "../rasterizer_gles3.h"36#include "config.h"37#include "utilities.h"3839using namespace GLES3;4041TextureStorage *TextureStorage::singleton = nullptr;4243TextureStorage *TextureStorage::get_singleton() {44return singleton;45}4647static const GLenum _cube_side_enum[6] = {48GL_TEXTURE_CUBE_MAP_POSITIVE_X,49GL_TEXTURE_CUBE_MAP_NEGATIVE_X,50GL_TEXTURE_CUBE_MAP_POSITIVE_Y,51GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,52GL_TEXTURE_CUBE_MAP_POSITIVE_Z,53GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,54};5556TextureStorage::TextureStorage() {57singleton = this;5859{ //create default textures60{ // White Textures6162Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);63image->fill(Color(1, 1, 1, 1));64image->generate_mipmaps();6566default_gl_textures[DEFAULT_GL_TEXTURE_WHITE] = texture_allocate();67texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE], image);6869Vector<Ref<Image>> images;70images.push_back(image);7172default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE] = texture_allocate();73texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE], images, RS::TEXTURE_LAYERED_2D_ARRAY);7475for (int i = 0; i < 5; i++) {76images.push_back(image);77}7879default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_WHITE] = texture_allocate();80texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_WHITE], images, RS::TEXTURE_LAYERED_CUBEMAP);81}8283{84Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);85image->fill(Color(1, 1, 1, 1));8687Vector<Ref<Image>> images;88for (int i = 0; i < 4; i++) {89images.push_back(image);90}91default_gl_textures[DEFAULT_GL_TEXTURE_3D_WHITE] = texture_allocate();92texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_WHITE], image->get_format(), 4, 4, 4, false, images);93}9495{ // black96Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);97image->fill(Color(0, 0, 0, 1));98image->generate_mipmaps();99100default_gl_textures[DEFAULT_GL_TEXTURE_BLACK] = texture_allocate();101texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK], image);102103Vector<Ref<Image>> images;104images.push_back(image);105106default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_BLACK] = texture_allocate();107texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_BLACK], images, RS::TEXTURE_LAYERED_2D_ARRAY);108109for (int i = 0; i < 5; i++) {110images.push_back(image);111}112default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK] = texture_allocate();113texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK], images, RS::TEXTURE_LAYERED_CUBEMAP);114}115116{117Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);118image->fill(Color());119120Vector<Ref<Image>> images;121for (int i = 0; i < 4; i++) {122images.push_back(image);123}124default_gl_textures[DEFAULT_GL_TEXTURE_3D_BLACK] = texture_allocate();125texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_BLACK], image->get_format(), 4, 4, 4, false, images);126}127128{ // transparent black129Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);130image->fill(Color(0, 0, 0, 0));131image->generate_mipmaps();132133default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT] = texture_allocate();134texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT], image);135136Vector<Ref<Image>> images;137images.push_back(image);138139default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_TRANSPARENT] = texture_allocate();140texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_TRANSPARENT], images, RS::TEXTURE_LAYERED_2D_ARRAY);141142for (int i = 0; i < 5; i++) {143images.push_back(image);144}145146default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_TRANSPARENT] = texture_allocate();147texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_TRANSPARENT], images, RS::TEXTURE_LAYERED_CUBEMAP);148}149150{151Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);152image->fill(Color(0, 0, 0, 0));153154Vector<Ref<Image>> images;155for (int i = 0; i < 4; i++) {156images.push_back(image);157}158default_gl_textures[DEFAULT_GL_TEXTURE_3D_TRANSPARENT] = texture_allocate();159texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_TRANSPARENT], image->get_format(), 4, 4, 4, false, images);160}161162{163Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);164image->fill(Color(0.5, 0.5, 1, 1));165image->generate_mipmaps();166167default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL] = texture_allocate();168texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL], image);169}170171{172Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);173image->fill(Color(1.0, 0.5, 1, 1));174image->generate_mipmaps();175176default_gl_textures[DEFAULT_GL_TEXTURE_ANISO] = texture_allocate();177texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_ANISO], image);178}179180{181default_gl_textures[DEFAULT_GL_TEXTURE_EXT] = texture_allocate();182texture_external_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_EXT], 1, 1, 0);183}184185{186unsigned char pixel_data[4 * 4 * 4];187for (int i = 0; i < 16; i++) {188pixel_data[i * 4 + 0] = 0;189pixel_data[i * 4 + 1] = 0;190pixel_data[i * 4 + 2] = 0;191pixel_data[i * 4 + 3] = 0;192}193194default_gl_textures[DEFAULT_GL_TEXTURE_2D_UINT] = texture_allocate();195Texture texture;196texture.width = 4;197texture.height = 4;198texture.format = Image::FORMAT_RGBA8;199texture.type = Texture::TYPE_2D;200texture.target = GL_TEXTURE_2D;201texture.active = true;202glGenTextures(1, &texture.tex_id);203texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_2D_UINT], texture);204205glBindTexture(GL_TEXTURE_2D, texture.tex_id);206glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 4, 4, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixel_data);207GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 4, "Default uint texture");208texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);209}210{211uint16_t pixel_data[4 * 4];212for (int i = 0; i < 16; i++) {213pixel_data[i] = Math::make_half_float(1.0f);214}215216default_gl_textures[DEFAULT_GL_TEXTURE_DEPTH] = texture_allocate();217Texture texture;218texture.width = 4;219texture.height = 4;220texture.format = Image::FORMAT_RGBA8;221texture.type = Texture::TYPE_2D;222texture.target = GL_TEXTURE_2D;223texture.active = true;224glGenTextures(1, &texture.tex_id);225texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_DEPTH], texture);226227glBindTexture(GL_TEXTURE_2D, texture.tex_id);228glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 4, 4, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixel_data);229GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 2, "Default depth texture");230texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);231}232}233234glBindTexture(GL_TEXTURE_2D, 0);235236{ // Atlas Texture initialize.237uint8_t pixel_data[4 * 4 * 4];238for (int i = 0; i < 16; i++) {239pixel_data[i * 4 + 0] = 0;240pixel_data[i * 4 + 1] = 0;241pixel_data[i * 4 + 2] = 0;242pixel_data[i * 4 + 3] = 255;243}244245glGenTextures(1, &texture_atlas.texture);246glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);247glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data);248GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, 4 * 4 * 4, "Texture atlas (Default)");249}250251glBindTexture(GL_TEXTURE_2D, 0);252253{254sdf_shader.shader.initialize();255sdf_shader.shader_version = sdf_shader.shader.version_create();256}257258// Initialize texture placeholder data for the `texture_*_placeholder_initialize()` methods.259260constexpr int placeholder_size = 4;261texture_2d_placeholder = Image::create_empty(placeholder_size, placeholder_size, false, Image::FORMAT_RGBA8);262// Draw a magenta/black checkerboard pattern.263for (int i = 0; i < placeholder_size * placeholder_size; i++) {264const int x = i % placeholder_size;265const int y = i / placeholder_size;266texture_2d_placeholder->set_pixel(x, y, (x + y) % 2 == 0 ? Color(1, 0, 1) : Color(0, 0, 0));267}268269texture_2d_array_placeholder.push_back(texture_2d_placeholder);270271for (int i = 0; i < 6; i++) {272cubemap_placeholder.push_back(texture_2d_placeholder);273}274275Ref<Image> texture_2d_placeholder_rotated;276texture_2d_placeholder_rotated.instantiate();277texture_2d_placeholder_rotated->copy_from(texture_2d_placeholder);278texture_2d_placeholder_rotated->rotate_90(CLOCKWISE);279for (int i = 0; i < 4; i++) {280// Alternate checkerboard pattern on odd layers (by using a copy that is rotated 90 degrees).281texture_3d_placeholder.push_back(i % 2 == 0 ? texture_2d_placeholder : texture_2d_placeholder_rotated);282}283284#ifdef GL_API_ENABLED285if (RasterizerGLES3::is_gles_over_gl()) {286glEnable(GL_PROGRAM_POINT_SIZE);287}288#endif // GL_API_ENABLED289}290291TextureStorage::~TextureStorage() {292singleton = nullptr;293for (int i = 0; i < DEFAULT_GL_TEXTURE_MAX; i++) {294texture_free(default_gl_textures[i]);295}296if (texture_atlas.texture != 0) {297GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);298}299texture_atlas.texture = 0;300glDeleteFramebuffers(1, &texture_atlas.framebuffer);301texture_atlas.framebuffer = 0;302sdf_shader.shader.version_free(sdf_shader.shader_version);303}304305// Has to be a separate call from TextureStorage initialization due to interacting with MaterialStorage306void TextureStorage::_tex_blit_shader_initialize() {307GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();308309{310String global_defines;311global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now312material_storage->shaders.tex_blit_shader.initialize(global_defines, 1);313}314315{316// default material and shader for Texture Blit shader317tex_blit_shader.default_shader = material_storage->shader_allocate();318material_storage->shader_initialize(tex_blit_shader.default_shader);319material_storage->shader_set_code(tex_blit_shader.default_shader, R"(320// Default Texture Blit shader.321322shader_type texture_blit;323render_mode blend_mix;324325uniform sampler2D source_texture0 : hint_blit_source0;326uniform sampler2D source_texture1 : hint_blit_source1;327uniform sampler2D source_texture2 : hint_blit_source2;328uniform sampler2D source_texture3 : hint_blit_source3;329330void blit() {331// Copies from each whole source texture to a rect on each output texture.332COLOR0 = texture(source_texture0, UV) * MODULATE;333COLOR1 = texture(source_texture1, UV) * MODULATE;334COLOR2 = texture(source_texture2, UV) * MODULATE;335COLOR3 = texture(source_texture3, UV) * MODULATE;336}337)");338tex_blit_shader.default_material = material_storage->material_allocate();339material_storage->material_initialize(tex_blit_shader.default_material);340material_storage->material_set_shader(tex_blit_shader.default_material, tex_blit_shader.default_shader);341}342343{344// Set up Frame & Vertex Buffers for TextureBlit Shaders345// Just a 1x1 Quad to draw346glGenFramebuffers(1, &tex_blit_fbo);347348glGenBuffers(1, &tex_blit_quad);349glBindBuffer(GL_ARRAY_BUFFER, tex_blit_quad);350351const float qv[12] = {352-1.0f,353-1.0f,3541.0f,355-1.0f,3561.0f,3571.0f,358-1.0f,359-1.0f,3601.0f,3611.0f,362-1.0f,3631.0f,364};365366glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 12, qv, GL_STATIC_DRAW);367glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind368369glGenVertexArrays(1, &tex_blit_quad_array);370glBindVertexArray(tex_blit_quad_array);371glBindBuffer(GL_ARRAY_BUFFER, tex_blit_quad);372glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);373glEnableVertexAttribArray(RS::ARRAY_VERTEX);374glBindVertexArray(0);375glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind376}377378tex_blit_shader.initialized = true;379}380381// Has to be a separate call from TextureStorage destruction due to interacting with Material Storage382void TextureStorage::_tex_blit_shader_free() {383if (tex_blit_shader.initialized) {384GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();385glDeleteFramebuffers(1, &tex_blit_fbo);386glDeleteBuffers(1, &tex_blit_quad);387glDeleteVertexArrays(1, &tex_blit_quad_array);388material_storage->material_free(tex_blit_shader.default_material);389material_storage->shader_free(tex_blit_shader.default_shader);390}391}392393/* Canvas Texture API */394395RID TextureStorage::canvas_texture_allocate() {396return canvas_texture_owner.allocate_rid();397}398399void TextureStorage::canvas_texture_initialize(RID p_rid) {400canvas_texture_owner.initialize_rid(p_rid);401}402403void TextureStorage::canvas_texture_free(RID p_rid) {404canvas_texture_owner.free(p_rid);405}406407void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {408CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);409ERR_FAIL_NULL(ct);410411switch (p_channel) {412case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {413ct->diffuse = p_texture;414} break;415case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {416ct->normal_map = p_texture;417} break;418case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {419ct->specular = p_texture;420} break;421}422}423424void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {425CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);426ERR_FAIL_NULL(ct);427428ct->specular_color.r = p_specular_color.r;429ct->specular_color.g = p_specular_color.g;430ct->specular_color.b = p_specular_color.b;431ct->specular_color.a = p_shininess;432}433434void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {435CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);436ERR_FAIL_NULL(ct);437438ct->texture_filter = p_filter;439}440441void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {442CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);443ERR_FAIL_NULL(ct);444445ct->texture_repeat = p_repeat;446}447448/* Texture API */449450static inline Error _get_gl_uncompressed_format(const Ref<Image> &p_image, Image::Format p_format, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type) {451Config *config = Config::get_singleton();452453switch (p_format) {454case Image::FORMAT_L8: {455if (RasterizerGLES3::is_gles_over_gl()) {456r_gl_internal_format = GL_R8;457r_gl_format = GL_RED;458r_gl_type = GL_UNSIGNED_BYTE;459} else {460r_gl_internal_format = GL_LUMINANCE;461r_gl_format = GL_LUMINANCE;462r_gl_type = GL_UNSIGNED_BYTE;463}464} break;465case Image::FORMAT_LA8: {466if (RasterizerGLES3::is_gles_over_gl()) {467r_gl_internal_format = GL_RG8;468r_gl_format = GL_RG;469r_gl_type = GL_UNSIGNED_BYTE;470} else {471r_gl_internal_format = GL_LUMINANCE_ALPHA;472r_gl_format = GL_LUMINANCE_ALPHA;473r_gl_type = GL_UNSIGNED_BYTE;474}475} break;476case Image::FORMAT_R8: {477r_gl_internal_format = GL_R8;478r_gl_format = GL_RED;479r_gl_type = GL_UNSIGNED_BYTE;480} break;481case Image::FORMAT_RG8: {482r_gl_internal_format = GL_RG8;483r_gl_format = GL_RG;484r_gl_type = GL_UNSIGNED_BYTE;485} break;486case Image::FORMAT_RGB8: {487r_gl_internal_format = GL_RGB8;488r_gl_format = GL_RGB;489r_gl_type = GL_UNSIGNED_BYTE;490} break;491case Image::FORMAT_RGBA8: {492r_gl_internal_format = GL_RGBA8;493r_gl_format = GL_RGBA;494r_gl_type = GL_UNSIGNED_BYTE;495} break;496case Image::FORMAT_RGBA4444: {497r_gl_internal_format = GL_RGBA4;498r_gl_format = GL_RGBA;499r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4;500} break;501case Image::FORMAT_RGB565: {502r_gl_internal_format = GL_RGB565;503r_gl_format = GL_RGB;504r_gl_type = GL_UNSIGNED_SHORT_5_6_5;505} break;506case Image::FORMAT_RF: {507if (config->float_texture_linear_supported) {508r_gl_internal_format = GL_R32F;509r_gl_format = GL_RED;510r_gl_type = GL_FLOAT;511} else {512if (p_image.is_valid()) {513p_image->convert(Image::FORMAT_RH);514}515r_real_format = Image::FORMAT_RH;516r_gl_internal_format = GL_R16F;517r_gl_format = GL_RED;518r_gl_type = GL_HALF_FLOAT;519}520} break;521case Image::FORMAT_RGF: {522if (config->float_texture_linear_supported) {523r_gl_internal_format = GL_RG32F;524r_gl_format = GL_RG;525r_gl_type = GL_FLOAT;526} else {527if (p_image.is_valid()) {528p_image->convert(Image::FORMAT_RGH);529}530r_real_format = Image::FORMAT_RGH;531r_gl_internal_format = GL_RG16F;532r_gl_format = GL_RG;533r_gl_type = GL_HALF_FLOAT;534}535} break;536case Image::FORMAT_RGBF: {537if (config->float_texture_linear_supported) {538r_gl_internal_format = GL_RGB32F;539r_gl_format = GL_RGB;540r_gl_type = GL_FLOAT;541} else {542if (p_image.is_valid()) {543p_image->convert(Image::FORMAT_RGBH);544}545r_real_format = Image::FORMAT_RGBH;546r_gl_internal_format = GL_RGB16F;547r_gl_format = GL_RGB;548r_gl_type = GL_HALF_FLOAT;549}550} break;551case Image::FORMAT_RGBAF: {552if (config->float_texture_linear_supported) {553r_gl_internal_format = GL_RGBA32F;554r_gl_format = GL_RGBA;555r_gl_type = GL_FLOAT;556} else {557if (p_image.is_valid()) {558p_image->convert(Image::FORMAT_RGBAH);559}560r_real_format = Image::FORMAT_RGBAH;561r_gl_internal_format = GL_RGBA16F;562r_gl_format = GL_RGBA;563r_gl_type = GL_HALF_FLOAT;564}565} break;566case Image::FORMAT_RH: {567r_gl_internal_format = GL_R16F;568r_gl_format = GL_RED;569r_gl_type = GL_HALF_FLOAT;570} break;571case Image::FORMAT_RGH: {572r_gl_internal_format = GL_RG16F;573r_gl_format = GL_RG;574r_gl_type = GL_HALF_FLOAT;575} break;576case Image::FORMAT_RGBH: {577r_gl_internal_format = GL_RGB16F;578r_gl_format = GL_RGB;579r_gl_type = GL_HALF_FLOAT;580} break;581case Image::FORMAT_RGBAH: {582r_gl_internal_format = GL_RGBA16F;583r_gl_format = GL_RGBA;584r_gl_type = GL_HALF_FLOAT;585} break;586case Image::FORMAT_RGBE9995: {587r_gl_internal_format = GL_RGB9_E5;588r_gl_format = GL_RGB;589r_gl_type = GL_UNSIGNED_INT_5_9_9_9_REV;590} break;591case Image::FORMAT_R16: {592if (config->unorm16_texture_supported) {593r_gl_internal_format = _EXT_R16;594r_gl_format = GL_RED;595r_gl_type = GL_UNSIGNED_SHORT;596} else {597if (config->float_texture_linear_supported) {598if (p_image.is_valid()) {599p_image->convert(Image::FORMAT_RF);600}601r_real_format = Image::FORMAT_RF;602r_gl_internal_format = GL_R32F;603r_gl_format = GL_RED;604r_gl_type = GL_FLOAT;605} else {606if (p_image.is_valid()) {607p_image->convert(Image::FORMAT_RH);608}609r_real_format = Image::FORMAT_RH;610r_gl_internal_format = GL_R16F;611r_gl_format = GL_RED;612r_gl_type = GL_HALF_FLOAT;613}614}615} break;616case Image::FORMAT_RG16: {617if (config->unorm16_texture_supported) {618r_gl_internal_format = _EXT_RG16;619r_gl_format = GL_RG;620r_gl_type = GL_UNSIGNED_SHORT;621} else {622if (config->float_texture_linear_supported) {623if (p_image.is_valid()) {624p_image->convert(Image::FORMAT_RGF);625}626r_real_format = Image::FORMAT_RGF;627r_gl_internal_format = GL_RG32F;628r_gl_format = GL_RG;629r_gl_type = GL_FLOAT;630} else {631if (p_image.is_valid()) {632p_image->convert(Image::FORMAT_RGH);633}634r_real_format = Image::FORMAT_RGH;635r_gl_internal_format = GL_RG16F;636r_gl_format = GL_RG;637r_gl_type = GL_HALF_FLOAT;638}639}640} break;641case Image::FORMAT_RGB16: {642if (config->unorm16_texture_supported) {643r_gl_internal_format = _EXT_RGB16;644r_gl_format = GL_RGB;645r_gl_type = GL_UNSIGNED_SHORT;646} else {647if (config->float_texture_linear_supported) {648if (p_image.is_valid()) {649p_image->convert(Image::FORMAT_RGBF);650}651r_real_format = Image::FORMAT_RGBF;652r_gl_internal_format = GL_RGB32F;653r_gl_format = GL_RGB;654r_gl_type = GL_FLOAT;655} else {656if (p_image.is_valid()) {657p_image->convert(Image::FORMAT_RGBH);658}659r_real_format = Image::FORMAT_RGBH;660r_gl_internal_format = GL_RGB16F;661r_gl_format = GL_RGB;662r_gl_type = GL_HALF_FLOAT;663}664}665} break;666case Image::FORMAT_RGBA16: {667if (config->unorm16_texture_supported) {668r_gl_internal_format = _EXT_RGBA16;669r_gl_format = GL_RGBA;670r_gl_type = GL_UNSIGNED_SHORT;671} else {672if (config->float_texture_linear_supported) {673if (p_image.is_valid()) {674p_image->convert(Image::FORMAT_RGBAF);675}676r_real_format = Image::FORMAT_RGBAF;677r_gl_internal_format = GL_RGBA32F;678r_gl_format = GL_RGBA;679r_gl_type = GL_FLOAT;680} else {681if (p_image.is_valid()) {682p_image->convert(Image::FORMAT_RGH);683}684r_real_format = Image::FORMAT_RGH;685r_gl_internal_format = GL_RGBA16F;686r_gl_format = GL_RGBA;687r_gl_type = GL_HALF_FLOAT;688}689}690} break;691case Image::FORMAT_R16I: {692r_gl_internal_format = GL_R16UI;693r_gl_format = GL_RED_INTEGER;694r_gl_type = GL_UNSIGNED_SHORT;695} break;696case Image::FORMAT_RG16I: {697r_gl_internal_format = GL_RG16UI;698r_gl_format = GL_RG_INTEGER;699r_gl_type = GL_UNSIGNED_SHORT;700} break;701case Image::FORMAT_RGB16I: {702r_gl_internal_format = GL_RGB16UI;703r_gl_format = GL_RGB_INTEGER;704r_gl_type = GL_UNSIGNED_SHORT;705} break;706case Image::FORMAT_RGBA16I: {707r_gl_internal_format = GL_RGBA16UI;708r_gl_format = GL_RGBA_INTEGER;709r_gl_type = GL_UNSIGNED_SHORT;710} break;711default: {712return ERR_UNAVAILABLE;713}714}715716return OK;717}718719Ref<Image> TextureStorage::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, 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 {720Config *config = Config::get_singleton();721r_gl_format = 0;722Ref<Image> image = p_image;723r_compressed = false;724r_real_format = p_format;725726if (!Image::is_format_compressed(p_format)) {727Error err = _get_gl_uncompressed_format(p_image, p_format, r_real_format, r_gl_format, r_gl_internal_format, r_gl_type);728ERR_FAIL_COND_V_MSG(err != OK, Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", p_format));729730if (p_format != r_real_format) {731WARN_PRINT(vformat("Image format %s not supported by hardware, converting to %s.", Image::get_format_name(p_format), Image::get_format_name(r_real_format)));732}733734return p_image;735}736737// For compressed images, some formats may not be supported by the current device and will require decompression.738bool need_decompress = false;739bool decompress_ra_to_rg = false;740741switch (p_format) {742case Image::FORMAT_DXT1: {743if (config->s3tc_supported) {744r_gl_internal_format = _EXT_COMPRESSED_RGB_S3TC_DXT1_EXT;745r_gl_format = GL_RGB;746r_gl_type = GL_UNSIGNED_BYTE;747r_compressed = true;748} else {749need_decompress = true;750}751} break;752case Image::FORMAT_DXT3: {753if (config->s3tc_supported) {754r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;755r_gl_format = GL_RGBA;756r_gl_type = GL_UNSIGNED_BYTE;757r_compressed = true;758} else {759need_decompress = true;760}761} break;762case Image::FORMAT_DXT5: {763if (config->s3tc_supported) {764r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;765r_gl_format = GL_RGBA;766r_gl_type = GL_UNSIGNED_BYTE;767r_compressed = true;768} else {769need_decompress = true;770}771} break;772case Image::FORMAT_RGTC_R: {773if (config->rgtc_supported) {774r_gl_internal_format = _EXT_COMPRESSED_RED_RGTC1_EXT;775r_gl_format = GL_RGBA;776r_gl_type = GL_UNSIGNED_BYTE;777r_compressed = true;778} else {779need_decompress = true;780}781} break;782case Image::FORMAT_RGTC_RG: {783if (config->rgtc_supported) {784r_gl_internal_format = _EXT_COMPRESSED_RED_GREEN_RGTC2_EXT;785r_gl_format = GL_RGBA;786r_gl_type = GL_UNSIGNED_BYTE;787r_compressed = true;788} else {789need_decompress = true;790}791} break;792case Image::FORMAT_BPTC_RGBA: {793if (config->bptc_supported) {794r_gl_internal_format = _EXT_COMPRESSED_RGBA_BPTC_UNORM;795r_gl_format = GL_RGBA;796r_gl_type = GL_UNSIGNED_BYTE;797r_compressed = true;798} else {799need_decompress = true;800}801} break;802case Image::FORMAT_BPTC_RGBF: {803if (config->bptc_supported) {804r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;805r_gl_format = GL_RGB;806r_gl_type = GL_FLOAT;807r_compressed = true;808} else {809need_decompress = true;810}811} break;812case Image::FORMAT_BPTC_RGBFU: {813if (config->bptc_supported) {814r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;815r_gl_format = GL_RGB;816r_gl_type = GL_FLOAT;817r_compressed = true;818} else {819need_decompress = true;820}821} break;822case Image::FORMAT_ETC2_R11: {823if (config->etc2_supported) {824r_gl_internal_format = _EXT_COMPRESSED_R11_EAC;825r_gl_format = GL_RED;826r_gl_type = GL_UNSIGNED_BYTE;827r_compressed = true;828} else {829need_decompress = true;830}831} break;832case Image::FORMAT_ETC2_R11S: {833if (config->etc2_supported) {834r_gl_internal_format = _EXT_COMPRESSED_SIGNED_R11_EAC;835r_gl_format = GL_RED;836r_gl_type = GL_UNSIGNED_BYTE;837r_compressed = true;838} else {839need_decompress = true;840}841} break;842case Image::FORMAT_ETC2_RG11: {843if (config->etc2_supported) {844r_gl_internal_format = _EXT_COMPRESSED_RG11_EAC;845r_gl_format = GL_RG;846r_gl_type = GL_UNSIGNED_BYTE;847r_compressed = true;848} else {849need_decompress = true;850}851} break;852case Image::FORMAT_ETC2_RG11S: {853if (config->etc2_supported) {854r_gl_internal_format = _EXT_COMPRESSED_SIGNED_RG11_EAC;855r_gl_format = GL_RG;856r_gl_type = GL_UNSIGNED_BYTE;857r_compressed = true;858} else {859need_decompress = true;860}861} break;862case Image::FORMAT_ETC:863case Image::FORMAT_ETC2_RGB8: {864if (config->etc2_supported) {865r_gl_internal_format = _EXT_COMPRESSED_RGB8_ETC2;866r_gl_format = GL_RGB;867r_gl_type = GL_UNSIGNED_BYTE;868r_compressed = true;869} else {870need_decompress = true;871}872} break;873case Image::FORMAT_ETC2_RGBA8: {874if (config->etc2_supported) {875r_gl_internal_format = _EXT_COMPRESSED_RGBA8_ETC2_EAC;876r_gl_format = GL_RGBA;877r_gl_type = GL_UNSIGNED_BYTE;878r_compressed = true;879} else {880need_decompress = true;881}882} break;883case Image::FORMAT_ETC2_RGB8A1: {884if (config->etc2_supported) {885r_gl_internal_format = _EXT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;886r_gl_format = GL_RGBA;887r_gl_type = GL_UNSIGNED_BYTE;888r_compressed = true;889} else {890need_decompress = true;891}892} break;893case Image::FORMAT_ETC2_RA_AS_RG: {894#ifndef WEB_ENABLED895if (config->etc2_supported) {896r_gl_internal_format = _EXT_COMPRESSED_RGBA8_ETC2_EAC;897r_gl_format = GL_RGBA;898r_gl_type = GL_UNSIGNED_BYTE;899r_compressed = true;900} else901#endif902{903need_decompress = true;904}905decompress_ra_to_rg = true;906} break;907case Image::FORMAT_DXT5_RA_AS_RG: {908#ifndef WEB_ENABLED909if (config->s3tc_supported) {910r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;911r_gl_format = GL_RGBA;912r_gl_type = GL_UNSIGNED_BYTE;913r_compressed = true;914} else915#endif916{917need_decompress = true;918}919decompress_ra_to_rg = true;920} break;921case Image::FORMAT_ASTC_4x4: {922if (config->astc_supported) {923r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;924r_gl_format = GL_RGBA;925r_gl_type = GL_UNSIGNED_BYTE;926r_compressed = true;927} else {928need_decompress = true;929}930} break;931case Image::FORMAT_ASTC_4x4_HDR: {932if (config->astc_hdr_supported) {933r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;934r_gl_format = GL_RGBA;935r_gl_type = GL_UNSIGNED_BYTE;936r_compressed = true;937} else {938need_decompress = true;939}940} break;941case Image::FORMAT_ASTC_8x8: {942if (config->astc_supported) {943r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;944r_gl_format = GL_RGBA;945r_gl_type = GL_UNSIGNED_BYTE;946r_compressed = true;947} else {948need_decompress = true;949}950} break;951case Image::FORMAT_ASTC_8x8_HDR: {952if (config->astc_hdr_supported) {953r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;954r_gl_format = GL_RGBA;955r_gl_type = GL_UNSIGNED_BYTE;956r_compressed = true;957} else {958need_decompress = true;959}960} break;961default: {962ERR_FAIL_V_MSG(Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", p_format));963}964}965966if (need_decompress || p_force_decompress) {967if (image.is_valid()) {968image = image->duplicate();969image->decompress();970ERR_FAIL_COND_V(image->is_compressed(), image);971972if (decompress_ra_to_rg) {973image->convert_ra_rgba8_to_rg();974image->convert(Image::FORMAT_RG8);975}976977Error err = _get_gl_uncompressed_format(image, image->get_format(), r_real_format, r_gl_format, r_gl_internal_format, r_gl_type);978ERR_FAIL_COND_V_MSG(err != OK, Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", image->get_format()));979980r_real_format = image->get_format();981r_compressed = false;982983if (p_format != image->get_format()) {984WARN_PRINT(vformat("Image format %s not supported by hardware, converting to %s.", Image::get_format_name(p_format), Image::get_format_name(image->get_format())));985}986}987988return image;989}990991return p_image;992}993994RID TextureStorage::texture_allocate() {995return texture_owner.allocate_rid();996}997998void TextureStorage::texture_free(RID p_texture) {999Texture *t = texture_owner.get_or_null(p_texture);1000ERR_FAIL_NULL(t);1001ERR_FAIL_COND(t->is_render_target);10021003if (t->canvas_texture) {1004memdelete(t->canvas_texture);1005}10061007bool must_free_data = false;1008if (t->is_proxy) {1009if (t->proxy_to.is_valid()) {1010Texture *proxy_to = texture_owner.get_or_null(t->proxy_to);1011if (proxy_to) {1012proxy_to->proxies.erase(p_texture);1013}1014}1015} else {1016must_free_data = t->tex_id != 0 && !t->is_from_native_handle;1017}1018if (must_free_data) {1019GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);1020t->tex_id = 0;1021}10221023texture_atlas_remove_texture(p_texture);10241025for (uint32_t i = 0; i < t->proxies.size(); i++) {1026Texture *p = texture_owner.get_or_null(t->proxies[i]);1027ERR_CONTINUE(!p);1028p->proxy_to = RID();1029p->tex_id = 0;1030}10311032texture_owner.free(p_texture);1033}10341035void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) {1036ERR_FAIL_COND(p_image.is_null());10371038Texture texture;1039texture.width = p_image->get_width();1040texture.height = p_image->get_height();1041texture.alloc_width = texture.width;1042texture.alloc_height = texture.height;1043texture.mipmaps = p_image->get_mipmap_count() + 1;1044texture.format = p_image->get_format();1045texture.type = Texture::TYPE_2D;1046texture.target = GL_TEXTURE_2D;1047_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);1048texture.total_data_size = p_image->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps);1049texture.active = true;1050glGenTextures(1, &texture.tex_id);1051GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 2D");1052texture_owner.initialize_rid(p_texture, texture);1053texture_set_data(p_texture, p_image);1054}10551056void TextureStorage::texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {1057Texture texture;1058texture.active = true;1059texture.alloc_width = texture.width = p_width;1060texture.alloc_height = texture.height = p_height;1061texture.real_format = texture.format = Image::FORMAT_RGB8;1062texture.type = Texture::TYPE_2D;10631064if (GLES3::Config::get_singleton()->external_texture_supported) {1065texture.target = _GL_TEXTURE_EXTERNAL_OES;1066} else {1067texture.target = GL_TEXTURE_2D;1068}10691070glGenTextures(1, &texture.tex_id);1071glBindTexture(texture.target, texture.tex_id);10721073#ifdef ANDROID_ENABLED1074if (texture.target == _GL_TEXTURE_EXTERNAL_OES) {1075if (p_external_buffer) {1076GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));1077}1078texture.total_data_size = 0;1079} else1080#endif1081{1082// If external textures aren't supported, allocate an empty 1x1 texture.1083glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);1084texture.total_data_size = 3;1085}10861087glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1088glTexParameteri(texture.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1089glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1090glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);10911092GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture External");1093texture_owner.initialize_rid(p_texture, texture);10941095glBindTexture(texture.target, 0);1096}10971098void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {1099ERR_FAIL_COND(p_layers.is_empty());11001101ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6);1102ERR_FAIL_COND_MSG(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY, "Cubemap Arrays are not supported in the Compatibility renderer.");11031104const Ref<Image> &image = p_layers[0];1105{1106int valid_width = 0;1107int valid_height = 0;1108bool valid_mipmaps = false;1109Image::Format valid_format = Image::FORMAT_MAX;11101111for (int i = 0; i < p_layers.size(); i++) {1112ERR_FAIL_COND(p_layers[i]->is_empty());11131114if (i == 0) {1115valid_width = p_layers[i]->get_width();1116valid_height = p_layers[i]->get_height();1117valid_format = p_layers[i]->get_format();1118valid_mipmaps = p_layers[i]->has_mipmaps();1119} else {1120ERR_FAIL_COND(p_layers[i]->get_width() != valid_width);1121ERR_FAIL_COND(p_layers[i]->get_height() != valid_height);1122ERR_FAIL_COND(p_layers[i]->get_format() != valid_format);1123ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps);1124}1125}1126}11271128Texture texture;1129texture.width = image->get_width();1130texture.height = image->get_height();1131texture.alloc_width = texture.width;1132texture.alloc_height = texture.height;1133texture.mipmaps = image->get_mipmap_count() + 1;1134texture.format = image->get_format();1135texture.type = Texture::TYPE_LAYERED;1136texture.layered_type = p_layered_type;1137texture.target = p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D_ARRAY;1138texture.layers = p_layers.size();1139_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);1140texture.total_data_size = p_layers[0]->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps) * texture.layers;1141texture.active = true;1142glGenTextures(1, &texture.tex_id);1143GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture Layered");1144texture_owner.initialize_rid(p_texture, texture);1145for (int i = 0; i < p_layers.size(); i++) {1146_texture_set_data(p_texture, p_layers[i], i, i == 0);1147}1148}11491150void TextureStorage::texture_3d_initialize(RID p_texture, Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) {1151ERR_FAIL_COND(p_data.is_empty());11521153Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);1154ERR_FAIL_COND_MSG(verr != Image::VALIDATE_3D_OK, Image::get_3d_image_validation_error_text(verr));11551156Ref<Image> image = p_data[0];1157int mipmap_count = 0;1158{1159Size2i prev_size;1160for (int i = 0; i < p_data.size(); i++) {1161Size2i img_size(p_data[i]->get_width(), p_data[i]->get_height());1162if (img_size != prev_size) {1163mipmap_count++;1164}1165prev_size = img_size;1166}1167}11681169Texture texture;1170texture.width = p_width;1171texture.height = p_height;1172texture.depth = p_depth;1173texture.alloc_width = texture.width;1174texture.alloc_height = texture.height;1175texture.mipmaps = mipmap_count;1176texture.format = image->get_format();1177texture.type = Texture::TYPE_3D;1178texture.target = GL_TEXTURE_3D;1179_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);1180texture.total_data_size = p_data[0]->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps) * texture.depth;1181texture.active = true;1182glGenTextures(1, &texture.tex_id);1183GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 3D");1184texture_owner.initialize_rid(p_texture, texture);1185_texture_set_3d_data(p_texture, p_data, true);1186}11871188// Called internally when texture_proxy_create(p_base) is called.1189// Note: p_base is the root and p_texture is the proxy.1190void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {1191Texture *texture = texture_owner.get_or_null(p_base);1192ERR_FAIL_NULL(texture);1193Texture proxy_tex;1194proxy_tex.copy_from(*texture);1195proxy_tex.proxy_to = p_base;1196proxy_tex.is_render_target = false;1197proxy_tex.is_proxy = true;1198proxy_tex.proxies.clear();1199texture->proxies.push_back(p_texture);1200texture_owner.initialize_rid(p_texture, proxy_tex);1201}12021203void TextureStorage::texture_drawable_initialize(RID p_texture, int p_width, int p_height, RS::TextureDrawableFormat p_format, const Color &p_color, bool p_with_mipmaps) {1204// Behaves identically to Texture_2D_Initialize by generating a white image based on parameters.12051206// GUARDRAIL: Bad Widths/Heights1207ERR_FAIL_COND_MSG(p_width <= 0 || p_height <= 0, "Drawable Texture Width or Height cannot be less than 1.");1208ERR_FAIL_COND_MSG(p_width >= 16384 || p_height >= 16384, "Drawable Texture Width or Height cannot be greater than 16383.");12091210Image::Format format;1211switch (p_format) {1212case RS::TEXTURE_DRAWABLE_FORMAT_RGBA8:1213format = Image::FORMAT_RGBA8;1214break;1215case RS::TEXTURE_DRAWABLE_FORMAT_RGBA8_SRGB:1216format = Image::FORMAT_RGBA8;1217break;1218case RS::TEXTURE_DRAWABLE_FORMAT_RGBAH:1219format = Image::FORMAT_RGBAH;1220break;1221case RS::TEXTURE_DRAWABLE_FORMAT_RGBAF:1222format = Image::FORMAT_RGBAF;1223break;1224default:1225format = Image::FORMAT_RGBA8;1226}12271228Ref<Image> image = Image::create_empty(p_width, p_height, p_with_mipmaps, format);1229image->fill(p_color);1230Texture texture;1231texture.width = image->get_width();1232texture.height = image->get_height();1233texture.alloc_width = texture.width;1234texture.alloc_height = texture.height;1235texture.mipmaps = image->get_mipmap_count() + 1;1236texture.format = image->get_format();1237texture.type = Texture::TYPE_2D;1238texture.target = GL_TEXTURE_2D;1239_get_gl_image_and_format(Ref<Image>(), texture.format, texture.real_format, texture.gl_format_cache, texture.gl_internal_format_cache, texture.gl_type_cache, texture.compressed, false);1240texture.total_data_size = image->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps);1241texture.active = true;1242glGenTextures(1, &texture.tex_id);1243GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 2D");1244texture_owner.initialize_rid(p_texture, texture);1245texture_set_data(p_texture, image);1246}12471248RID TextureStorage::texture_create_from_native_handle(RS::TextureType p_type, Image::Format p_format, uint64_t p_native_handle, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) {1249Texture texture;1250texture.active = true;1251texture.is_from_native_handle = true;12521253switch (p_type) {1254case RS::TEXTURE_TYPE_2D: {1255texture.type = Texture::TYPE_2D;1256texture.target = GL_TEXTURE_2D;1257} break;1258case RS::TEXTURE_TYPE_3D: {1259texture.type = Texture::TYPE_3D;1260texture.target = GL_TEXTURE_3D;1261} break;1262case RS::TEXTURE_TYPE_LAYERED: {1263texture.type = Texture::TYPE_LAYERED;1264texture.target = GL_TEXTURE_2D_ARRAY;1265} break;1266}12671268texture.real_format = texture.format = p_format;1269texture.tex_id = p_native_handle;1270texture.alloc_width = texture.width = p_width;1271texture.alloc_height = texture.height = p_height;1272texture.depth = p_depth;1273texture.layers = p_layers;1274texture.layered_type = p_layered_type;12751276return texture_owner.make_rid(texture);1277}12781279void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {1280texture_set_data(p_texture, p_image, p_layer);12811282Texture *tex = texture_owner.get_or_null(p_texture);1283ERR_FAIL_NULL(tex);1284GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);12851286#ifdef TOOLS_ENABLED1287tex->image_cache_2d.unref();1288#endif1289}12901291void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) {1292Texture *tex = texture_owner.get_or_null(p_texture);1293ERR_FAIL_NULL(tex);1294ERR_FAIL_COND(tex->type != Texture::TYPE_3D);12951296Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data);1297ERR_FAIL_COND_MSG(verr != Image::VALIDATE_3D_OK, Image::get_3d_image_validation_error_text(verr));12981299_texture_set_3d_data(p_texture, p_data, false);13001301GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);1302}13031304void TextureStorage::texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {1305Texture *tex = texture_owner.get_or_null(p_texture);1306ERR_FAIL_NULL(tex);13071308tex->alloc_width = tex->width = p_width;1309tex->alloc_height = tex->height = p_height;13101311#ifdef ANDROID_ENABLED1312if (tex->target == _GL_TEXTURE_EXTERNAL_OES && p_external_buffer) {1313glBindTexture(_GL_TEXTURE_EXTERNAL_OES, tex->tex_id);1314GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));1315glBindTexture(_GL_TEXTURE_EXTERNAL_OES, 0);1316}1317#endif1318}13191320void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) {1321Texture *tex = texture_owner.get_or_null(p_texture);1322ERR_FAIL_NULL(tex);1323ERR_FAIL_COND(!tex->is_proxy);1324Texture *proxy_to = texture_owner.get_or_null(p_proxy_to);1325ERR_FAIL_NULL(proxy_to);1326ERR_FAIL_COND(proxy_to->is_proxy);13271328if (tex->proxy_to.is_valid()) {1329Texture *prev_tex = texture_owner.get_or_null(tex->proxy_to);1330ERR_FAIL_NULL(prev_tex);1331prev_tex->proxies.erase(p_texture);1332}13331334*tex = *proxy_to;13351336tex->proxy_to = p_proxy_to;1337tex->is_render_target = false;1338tex->is_proxy = true;1339tex->proxies.clear();1340tex->canvas_texture = nullptr;1341tex->tex_id = 0;1342proxy_to->proxies.push_back(p_texture);1343}13441345void TextureStorage::texture_remap_proxies(RID p_from_texture, RID p_to_texture) {1346Texture *from_tex = texture_owner.get_or_null(p_from_texture);1347ERR_FAIL_NULL(from_tex);1348ERR_FAIL_COND(from_tex->is_proxy);1349Texture *to_tex = texture_owner.get_or_null(p_to_texture);1350ERR_FAIL_NULL(to_tex);1351ERR_FAIL_COND(to_tex->is_proxy);13521353if (from_tex == to_tex) {1354return;1355}13561357// Make a local copy, we're about to change the content of the original.1358thread_local LocalVector<RID> proxies(from_tex->proxies);13591360// Now change them to our new texture.1361for (RID &proxy : proxies) {1362texture_proxy_update(proxy, p_to_texture);1363}1364}13651366// Output textures in p_textures must ALL BE THE SAME SIZE1367void TextureStorage::texture_drawable_blit_rect(const TypedArray<RID> &p_textures, const Rect2i &p_rect, RID p_material, const Color &p_modulate, const TypedArray<RID> &p_source_textures, int p_to_mipmap) {1368ERR_FAIL_COND_MSG(!tex_blit_shader.initialized, "Texture Blit shader & materials not yet initialized.");1369ERR_FAIL_COND_MSG(p_textures.size() == 0 || p_source_textures.size() == 0, "Blit Rect texture output and source arrays must contain at least 1 texture.");1370GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();13711372TexBlitMaterialData *m = static_cast<TexBlitMaterialData *>(material_storage->material_get_data(p_material, RS::SHADER_TEXTURE_BLIT));1373if (!m) {1374m = static_cast<TexBlitMaterialData *>(material_storage->material_get_data(tex_blit_shader.default_material, RS::SHADER_TEXTURE_BLIT));1375}1376// GUARDRAIL: p_material MUST BE ShaderType TextureBlit1377ERR_FAIL_NULL(m);13781379TexBlitShaderGLES3::ShaderVariant variant = TexBlitShaderGLES3::MODE_DEFAULT;1380RID version = tex_blit_shader.default_shader_version;1381if (m->shader_data->version.is_valid() && m->shader_data->valid) {1382// Must be called to force user ShaderMaterials to actually populate uniform buffer before binding1383// NOTE: Not an ideal work around, maybe in the future this can only update this MaterialData and remove it from the queue, instead of processing all queued updates1384material_storage->_update_queued_materials();1385// Bind material uniform buffer and textures.1386m->bind_uniforms();1387version = m->shader_data->version;1388}13891390glBindFramebuffer(GL_FRAMEBUFFER, tex_blit_fbo);1391TightLocalVector<GLenum> draw_buffers;13921393Texture *tar_textures[4];1394int convert_to_srgb_mask = 0;1395Texture *src_textures[4];13961397int i = 0;1398uint32_t specialization = 0;1399const int outputFlagArray[4] = { 0, TexBlitShaderGLES3::USE_OUTPUT1, TexBlitShaderGLES3::USE_OUTPUT2, TexBlitShaderGLES3::USE_OUTPUT3 };1400const int srgbMaskArray[4] = { 1, 2, 4, 8 };1401while (i < 4) {1402// Attach Targets to Framebuffer1403if (i < p_textures.size()) {1404tar_textures[i] = get_texture(p_textures[i]);1405ERR_FAIL_NULL_MSG(tar_textures[i], "Drawable Texture target cannot be null.");1406if (i > 0) {1407ERR_FAIL_COND_MSG(texture_get_size(p_textures[i - 1]) != texture_get_size(p_textures[i]), "All Blit_Rect output textures must be same size.");1408}1409specialization |= outputFlagArray[i];1410draw_buffers.push_back(GL_COLOR_ATTACHMENT0 + i);1411ERR_FAIL_COND_MSG(p_to_mipmap >= tar_textures[i]->mipmaps, vformat("Drawable Texture Target does not have mipmap level %d.", p_to_mipmap));1412glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, tar_textures[i]->tex_id, p_to_mipmap);1413convert_to_srgb_mask += tar_textures[i]->drawable_type == RS::TEXTURE_DRAWABLE_FORMAT_RGBA8_SRGB ? srgbMaskArray[i] : 0;1414}14151416// Bind Sources to buffer. Use placeholder Black Texture if source is bad.1417if (i < p_source_textures.size()) {1418src_textures[i] = get_texture(p_source_textures[i]);1419if (!src_textures[i]) {1420src_textures[i] = get_texture(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE]);1421}1422} else {1423src_textures[i] = get_texture(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE]);1424}1425int shift = i == 0 ? 0 : GLES3::Config::get_singleton()->max_texture_image_units - i;1426glActiveTexture(GL_TEXTURE0 + shift);1427glBindTexture(GL_TEXTURE_2D, src_textures[i]->tex_id);14281429i += 1;1430}14311432bool success = material_storage->shaders.tex_blit_shader.version_bind_shader(version, variant, specialization);1433if (!success) {1434return;1435}14361437// Calculates the Rects Offset & Size in UV space for Shader to scale Vertex Quad correctly1438Vector3 size = texture_get_size(p_textures[0]);1439Vector2 offset = Vector2(p_rect.position.x / size.x, p_rect.position.y / size.y);1440Vector2 rect_size = Vector2(p_rect.size.x / size.x, p_rect.size.y / size.y);1441Vector2i vp_size = Vector2i(tar_textures[0]->alloc_width, tar_textures[0]->alloc_height);1442if (p_to_mipmap != 0) {1443vp_size.x >>= p_to_mipmap;1444vp_size.y >>= p_to_mipmap;1445}14461447glViewport(0, 0, vp_size.x, vp_size.y);14481449material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::CONVERT_TO_SRGB, convert_to_srgb_mask, version, variant, specialization);1450material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::SIZE, rect_size, version, variant, specialization);1451material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::OFFSET, offset, version, variant, specialization);1452material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::MODULATE, p_modulate, version, variant, specialization);1453material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::TIME, RasterizerGLES3::get_singleton()->get_total_time(), version, variant, specialization);14541455// Set Blend_Mode correctly1456GLES3::TexBlitShaderData::BlendMode blend_mode = m->shader_data->blend_mode;1457glEnable(GL_BLEND);1458switch (blend_mode) {1459case GLES3::TexBlitShaderData::BLEND_MODE_ADD:1460glBlendEquation(GL_FUNC_ADD);1461glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);1462break;14631464case GLES3::TexBlitShaderData::BLEND_MODE_SUB:1465glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);1466glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);1467break;14681469case GLES3::TexBlitShaderData::BLEND_MODE_MIX:1470glBlendEquation(GL_FUNC_ADD);1471glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);1472break;14731474case GLES3::TexBlitShaderData::BLEND_MODE_MUL:1475glBlendEquation(GL_FUNC_ADD);1476glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_DST_ALPHA, GL_ZERO);1477break;14781479case GLES3::TexBlitShaderData::BLEND_MODE_DISABLED:1480glDisable(GL_BLEND);1481break;1482}14831484glDrawBuffers(draw_buffers.size(), draw_buffers.ptr());14851486// DRAW!!1487glBindVertexArray(tex_blit_quad_array);1488glDrawArrays(GL_TRIANGLES, 0, 6);1489glBindVertexArray(0);14901491// Reset to system FBO1492glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1493}14941495void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) {1496texture_2d_initialize(p_texture, texture_2d_placeholder);1497}14981499void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) {1500if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) {1501texture_2d_layered_initialize(p_texture, texture_2d_array_placeholder, p_layered_type);1502} else {1503texture_2d_layered_initialize(p_texture, cubemap_placeholder, p_layered_type);1504}1505}15061507void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) {1508texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, texture_3d_placeholder);1509}15101511Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {1512Texture *texture = texture_owner.get_or_null(p_texture);1513ERR_FAIL_NULL_V(texture, Ref<Image>());15141515#ifdef TOOLS_ENABLED1516if (texture->image_cache_2d.is_valid() && !texture->is_render_target) {1517return texture->image_cache_2d;1518}1519#endif15201521Ref<Image> image;1522#ifdef GL_API_ENABLED1523if (RasterizerGLES3::is_gles_over_gl()) {1524// OpenGL 3.3 supports glGetTexImage which is faster and simpler than glReadPixels.1525// It also allows for reading compressed textures, mipmaps, and more formats.1526Vector<uint8_t> data;15271528int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->real_format, texture->mipmaps > 1);15291530data.resize(data_size * 2); // Add some memory at the end, just in case for buggy drivers.1531uint8_t *w = data.ptrw();15321533glActiveTexture(GL_TEXTURE0);15341535glBindTexture(texture->target, texture->tex_id);15361537glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);15381539for (int i = 0; i < texture->mipmaps; i++) {1540int64_t ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, texture->real_format, i);15411542if (texture->compressed) {1543glPixelStorei(GL_PACK_ALIGNMENT, 4);1544glGetCompressedTexImage(texture->target, i, &w[ofs]);1545} else {1546glPixelStorei(GL_PACK_ALIGNMENT, 1);1547glGetTexImage(texture->target, i, texture->gl_format_cache, texture->gl_type_cache, &w[ofs]);1548}1549}15501551data.resize(data_size);15521553ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());1554image = Image::create_from_data(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1, texture->real_format, data);1555if (image->is_empty()) {1556const String &path_str = texture->path.is_empty() ? "with no path" : vformat("with path '%s'", texture->path);1557ERR_FAIL_V_MSG(Ref<Image>(), vformat("Texture %s has no data.", path_str));1558}15591560if (texture->format != texture->real_format && !Image::is_format_compressed(texture->real_format)) {1561image->convert(texture->format);1562}1563}1564#endif // GL_API_ENABLED1565#ifdef GLES_API_ENABLED1566if (!RasterizerGLES3::is_gles_over_gl()) {1567Vector<uint8_t> data;15681569// On web and mobile we always read an RGBA8 image with no mipmaps.1570int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);15711572data.resize(data_size * 2); // Add some memory at the end, just in case for buggy drivers.1573uint8_t *w = data.ptrw();15741575GLuint temp_framebuffer;1576glGenFramebuffers(1, &temp_framebuffer);15771578GLuint temp_color_texture;1579glGenTextures(1, &temp_color_texture);15801581glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);15821583glBindTexture(GL_TEXTURE_2D, temp_color_texture);1584glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);15851586glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1587glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1588glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);15891590glDepthMask(GL_FALSE);1591glDisable(GL_DEPTH_TEST);1592glDisable(GL_CULL_FACE);1593glDisable(GL_BLEND);1594glDepthFunc(GL_GEQUAL);1595glColorMask(1, 1, 1, 1);1596glActiveTexture(GL_TEXTURE0);1597glBindTexture(GL_TEXTURE_2D, texture->tex_id);15981599glViewport(0, 0, texture->alloc_width, texture->alloc_height);1600glClearColor(0.0, 0.0, 0.0, 0.0);1601glClear(GL_COLOR_BUFFER_BIT);16021603CopyEffects::get_singleton()->copy_to_rect(Rect2i(0, 0, 1.0, 1.0));16041605glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);16061607glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1608glDeleteTextures(1, &temp_color_texture);1609glDeleteFramebuffers(1, &temp_framebuffer);16101611data.resize(data_size);16121613ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());1614image = Image::create_from_data(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data);1615if (image->is_empty()) {1616const String &path_str = texture->path.is_empty() ? "with no path" : vformat("with path '%s'", texture->path);1617ERR_FAIL_V_MSG(Ref<Image>(), vformat("Texture %s has no data.", path_str));1618}16191620if (texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(texture->format)) {1621image->convert(texture->format);1622}16231624if (texture->mipmaps > 1) {1625image->generate_mipmaps();1626}1627}1628#endif // GLES_API_ENABLED16291630#ifdef TOOLS_ENABLED1631if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {1632texture->image_cache_2d = image;1633}1634#endif16351636return image;1637}16381639Ref<Image> TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) const {1640Texture *texture = texture_owner.get_or_null(p_texture);1641ERR_FAIL_NULL_V(texture, Ref<Image>());16421643Vector<uint8_t> data;16441645int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);16461647data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers1648uint8_t *w = data.ptrw();16491650GLuint temp_framebuffer;1651glGenFramebuffers(1, &temp_framebuffer);16521653GLuint temp_color_texture;1654glGenTextures(1, &temp_color_texture);16551656glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);16571658glBindTexture(GL_TEXTURE_2D, temp_color_texture);1659glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);16601661glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1662glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1663glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);16641665glDepthMask(GL_FALSE);1666glDisable(GL_DEPTH_TEST);1667glDisable(GL_CULL_FACE);1668glDisable(GL_BLEND);1669glDepthFunc(GL_LEQUAL);1670glColorMask(1, 1, 1, 1);1671glActiveTexture(GL_TEXTURE0);1672glBindTexture(GL_TEXTURE_2D_ARRAY, texture->tex_id);16731674glViewport(0, 0, texture->alloc_width, texture->alloc_height);1675glClearColor(0.0, 0.0, 0.0, 0.0);1676glClear(GL_COLOR_BUFFER_BIT);16771678CopyEffects::get_singleton()->copy_to_rect_3d(Rect2i(0, 0, 1, 1), p_layer, Texture::TYPE_LAYERED);16791680glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);16811682glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1683glDeleteTextures(1, &temp_color_texture);1684glDeleteFramebuffers(1, &temp_framebuffer);16851686data.resize(data_size);16871688ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());1689Ref<Image> image = Image::create_from_data(texture->width, texture->height, false, Image::FORMAT_RGBA8, data);1690if (image->is_empty()) {1691const String &path_str = texture->path.is_empty() ? "with no path" : vformat("with path '%s'", texture->path);1692ERR_FAIL_V_MSG(Ref<Image>(), vformat("Texture %s has no data.", path_str));1693}16941695if (texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(texture->format)) {1696image->convert(texture->format);1697}16981699if (texture->mipmaps > 1) {1700image->generate_mipmaps();1701}17021703return image;1704}17051706Vector<Ref<Image>> TextureStorage::_texture_3d_read_framebuffer(GLES3::Texture *p_texture) const {1707ERR_FAIL_NULL_V(p_texture, Vector<Ref<Image>>());17081709Vector<Ref<Image>> ret;1710Vector<uint8_t> data;17111712int width = p_texture->width;1713int height = p_texture->height;1714int depth = p_texture->depth;17151716for (int mipmap_level = 0; mipmap_level < p_texture->mipmaps; mipmap_level++) {1717int64_t data_size = Image::get_image_data_size(width, height, Image::FORMAT_RGBA8, false);1718glViewport(0, 0, width, height);1719glClearColor(0.0, 0.0, 0.0, 0.0);1720glClear(GL_COLOR_BUFFER_BIT);17211722for (int layer = 0; layer < depth; layer++) {1723data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers1724uint8_t *w = data.ptrw();17251726float layer_f = layer / float(depth);1727CopyEffects::get_singleton()->copy_to_rect_3d(Rect2i(0, 0, 1, 1), layer_f, Texture::TYPE_3D, mipmap_level);1728glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);17291730data.resize(data_size);1731ERR_FAIL_COND_V(data.is_empty(), Vector<Ref<Image>>());17321733Ref<Image> img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, data);1734ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>());17351736if (p_texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(p_texture->format)) {1737img->convert(p_texture->format);1738}17391740ret.push_back(img);1741}17421743width = MAX(1, width >> 1);1744height = MAX(1, height >> 1);1745depth = MAX(1, depth >> 1);1746}17471748return ret;1749}17501751Vector<Ref<Image>> TextureStorage::texture_3d_get(RID p_texture) const {1752Texture *texture = texture_owner.get_or_null(p_texture);1753ERR_FAIL_NULL_V(texture, Vector<Ref<Image>>());1754ERR_FAIL_COND_V(texture->type != Texture::TYPE_3D, Vector<Ref<Image>>());17551756#ifdef TOOLS_ENABLED1757if (!texture->image_cache_3d.is_empty() && !texture->is_render_target) {1758return texture->image_cache_3d;1759}1760#endif17611762GLuint temp_framebuffer;1763glGenFramebuffers(1, &temp_framebuffer);17641765GLuint temp_color_texture;1766glGenTextures(1, &temp_color_texture);17671768glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);17691770glBindTexture(GL_TEXTURE_2D, temp_color_texture);1771glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);17721773glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);1774glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);1775glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);17761777glDepthMask(GL_FALSE);1778glDisable(GL_DEPTH_TEST);1779glDisable(GL_CULL_FACE);1780glDisable(GL_BLEND);1781glDepthFunc(GL_LEQUAL);1782glColorMask(1, 1, 1, 1);1783glActiveTexture(GL_TEXTURE0);1784glBindTexture(GL_TEXTURE_3D, texture->tex_id);17851786Vector<Ref<Image>> ret = _texture_3d_read_framebuffer(texture);17871788glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);1789glDeleteTextures(1, &temp_color_texture);1790glDeleteFramebuffers(1, &temp_framebuffer);17911792#ifdef TOOLS_ENABLED1793if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {1794texture->image_cache_3d = ret;1795}1796#endif17971798return ret;1799}18001801void TextureStorage::texture_drawable_generate_mipmaps(RID p_texture) {1802Texture *texture = get_texture(p_texture);1803Vector3i size = texture_get_size(p_texture);1804CopyEffects::get_singleton()->bilinear_blur(texture->tex_id, texture->mipmaps, Rect2i(0, 0, size.x, size.y));1805}18061807RID TextureStorage::texture_drawable_get_default_material() const {1808// This should never be called before DrawableTexture stuff is initialized.1809return tex_blit_shader.default_material;1810}18111812void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {1813Texture *tex_to = texture_owner.get_or_null(p_texture);1814ERR_FAIL_NULL(tex_to);1815ERR_FAIL_COND(tex_to->is_proxy); //can't replace proxy1816Texture *tex_from = texture_owner.get_or_null(p_by_texture);1817ERR_FAIL_NULL(tex_from);1818ERR_FAIL_COND(tex_from->is_proxy); //can't replace proxy18191820if (tex_to == tex_from) {1821return;1822}18231824if (tex_to->canvas_texture) {1825memdelete(tex_to->canvas_texture);1826tex_to->canvas_texture = nullptr;1827}18281829if (tex_to->tex_id) {1830GLES3::Utilities::get_singleton()->texture_free_data(tex_to->tex_id);1831tex_to->tex_id = 0;1832}18331834Vector<RID> proxies_to_update = Vector<RID>(tex_to->proxies);1835Vector<RID> proxies_to_redirect = Vector<RID>(tex_from->proxies);18361837*tex_to = *tex_from;18381839tex_to->proxies = proxies_to_update; //restore proxies, so they can be updated18401841if (tex_to->canvas_texture) {1842tex_to->canvas_texture->diffuse = p_texture; //update1843}18441845for (int i = 0; i < proxies_to_update.size(); i++) {1846texture_proxy_update(proxies_to_update[i], p_texture);1847}1848for (int i = 0; i < proxies_to_redirect.size(); i++) {1849texture_proxy_update(proxies_to_redirect[i], p_texture);1850}1851//delete last, so proxies can be updated1852texture_owner.free(p_by_texture);18531854texture_atlas_mark_dirty_on_texture(p_texture);1855}18561857void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) {1858Texture *texture = texture_owner.get_or_null(p_texture);18591860ERR_FAIL_NULL(texture);1861ERR_FAIL_COND(texture->is_render_target);18621863ERR_FAIL_COND(p_width <= 0 || p_width > 16384);1864ERR_FAIL_COND(p_height <= 0 || p_height > 16384);1865//real texture size is in alloc width and height1866texture->width = p_width;1867texture->height = p_height;1868}18691870void TextureStorage::texture_set_path(RID p_texture, const String &p_path) {1871Texture *texture = texture_owner.get_or_null(p_texture);1872ERR_FAIL_NULL(texture);18731874texture->path = p_path;1875}18761877String TextureStorage::texture_get_path(RID p_texture) const {1878Texture *texture = texture_owner.get_or_null(p_texture);1879ERR_FAIL_NULL_V(texture, "");18801881return texture->path;1882}18831884void TextureStorage::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {1885Texture *texture = texture_owner.get_or_null(p_texture);1886ERR_FAIL_NULL(texture);18871888texture->detect_3d_callback = p_callback;1889texture->detect_3d_callback_ud = p_userdata;1890}18911892void TextureStorage::texture_set_detect_srgb_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {1893}18941895void TextureStorage::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {1896Texture *texture = texture_owner.get_or_null(p_texture);1897ERR_FAIL_NULL(texture);18981899texture->detect_normal_callback = p_callback;1900texture->detect_normal_callback_ud = p_userdata;1901}19021903void TextureStorage::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {1904Texture *texture = texture_owner.get_or_null(p_texture);1905ERR_FAIL_NULL(texture);19061907texture->detect_roughness_callback = p_callback;1908texture->detect_roughness_callback_ud = p_userdata;1909}19101911void TextureStorage::texture_debug_usage(List<RS::TextureInfo> *r_info) {1912for (const RID &rid : texture_owner.get_owned_list()) {1913Texture *t = texture_owner.get_or_null(rid);1914if (!t) {1915continue;1916}1917RS::TextureInfo tinfo;1918tinfo.path = t->path;1919tinfo.format = t->format;1920tinfo.width = t->alloc_width;1921tinfo.height = t->alloc_height;1922tinfo.bytes = t->total_data_size;1923tinfo.type = static_cast<RenderingServer::TextureType>(t->type);19241925switch (t->type) {1926case Texture::TYPE_3D:1927tinfo.depth = t->depth;1928break;19291930case Texture::TYPE_LAYERED:1931tinfo.depth = t->layers;1932break;19331934default:1935tinfo.depth = 0;1936break;1937}19381939r_info->push_back(tinfo);1940}1941}19421943void TextureStorage::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {1944Texture *texture = texture_owner.get_or_null(p_texture);1945ERR_FAIL_NULL(texture);19461947texture->redraw_if_visible = p_enable;1948}19491950Size2 TextureStorage::texture_size_with_proxy(RID p_texture) {1951const Texture *texture = texture_owner.get_or_null(p_texture);1952ERR_FAIL_NULL_V(texture, Size2());1953if (texture->is_proxy) {1954const Texture *proxy = texture_owner.get_or_null(texture->proxy_to);1955return Size2(proxy->width, proxy->height);1956} else {1957return Size2(texture->width, texture->height);1958}1959}19601961void TextureStorage::texture_rd_initialize(RID p_texture, const RID &p_rd_texture, const RS::TextureLayeredType p_layer_type) {1962}19631964RID TextureStorage::texture_get_rd_texture(RID p_texture, bool p_srgb) const {1965return RID();1966}19671968uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) const {1969const Texture *texture = texture_owner.get_or_null(p_texture);1970ERR_FAIL_NULL_V(texture, 0);19711972return texture->tex_id;1973}19741975void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) {1976_texture_set_data(p_texture, p_image, p_layer, false);1977}19781979void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_initialize) {1980Texture *texture = texture_owner.get_or_null(p_texture);19811982ERR_FAIL_NULL(texture);1983if (texture->target == GL_TEXTURE_3D) {1984// Target is set to a 3D texture or array texture, exit early to avoid spamming errors1985return;1986}1987ERR_FAIL_COND(!texture->active);1988ERR_FAIL_COND(texture->is_render_target);1989ERR_FAIL_COND(p_image.is_null());1990ERR_FAIL_COND(texture->format != p_image->get_format());19911992ERR_FAIL_COND(!p_image->get_width());1993ERR_FAIL_COND(!p_image->get_height());19941995GLenum type;1996GLenum format;1997GLenum internal_format;1998bool compressed = false;19992000bool needs_decompress = texture->resize_to_po2;20012002// Support for RGTC-compressed Texture Arrays isn't mandated by GLES3/WebGL.2003if (!RasterizerGLES3::is_gles_over_gl() && texture->target == GL_TEXTURE_2D_ARRAY) {2004if (p_image->get_format() == Image::FORMAT_RGTC_R || p_image->get_format() == Image::FORMAT_RGTC_RG) {2005needs_decompress = true;2006}2007}20082009Image::Format real_format;2010Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), real_format, format, internal_format, type, compressed, needs_decompress);2011ERR_FAIL_COND(img.is_null());2012if (texture->resize_to_po2) {2013if (p_image->is_compressed()) {2014ERR_PRINT("Texture '" + texture->path + "' is required to be a power of 2 because it uses either mipmaps or repeat, so it was decompressed. This will hurt performance and memory usage.");2015}20162017if (img == p_image) {2018img = img->duplicate();2019}2020img->resize_to_po2(false);2021}20222023GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_layer] : texture->target;20242025Vector<uint8_t> read = img->get_data();20262027glActiveTexture(GL_TEXTURE0);2028glBindTexture(texture->target, texture->tex_id);2029_texture_set_swizzle(texture, real_format);20302031int mipmaps = img->has_mipmaps() ? img->get_mipmap_count() + 1 : 1;20322033// Set filtering and repeat state to default.2034if (mipmaps > 1) {2035texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);2036} else {2037texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);2038}20392040texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);20412042int w = img->get_width();2043int h = img->get_height();20442045int tsize = 0;20462047for (int i = 0; i < mipmaps; i++) {2048int64_t size, ofs;2049img->get_mipmap_offset_and_size(i, ofs, size);2050if (compressed) {2051glPixelStorei(GL_UNPACK_ALIGNMENT, 4);2052if (texture->target == GL_TEXTURE_2D_ARRAY) {2053if (p_initialize) {2054glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0, size * texture->layers, nullptr);2055}2056glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 1, internal_format, size, &read[ofs]);2057} else {2058glCompressedTexImage2D(blit_target, i, internal_format, w, h, 0, size, &read[ofs]);2059}2060} else {2061glPixelStorei(GL_UNPACK_ALIGNMENT, 1);2062if (texture->target == GL_TEXTURE_2D_ARRAY) {2063if (p_initialize) {2064glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0, format, type, nullptr);2065}2066glTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 1, format, type, &read[ofs]);2067} else {2068glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);2069}2070}20712072tsize += size;20732074w = MAX(1, w >> 1);2075h = MAX(1, h >> 1);2076}20772078if (texture->target == GL_TEXTURE_CUBE_MAP || texture->target == GL_TEXTURE_2D_ARRAY) {2079texture->total_data_size = tsize * texture->layers;2080} else {2081texture->total_data_size = tsize;2082}20832084texture->stored_cube_sides |= (1 << p_layer);20852086texture->mipmaps = mipmaps;2087}20882089void TextureStorage::_texture_set_3d_data(RID p_texture, const Vector<Ref<Image>> &p_data, bool p_initialize) {2090Texture *texture = texture_owner.get_or_null(p_texture);20912092ERR_FAIL_NULL(texture);2093ERR_FAIL_COND(!texture->active);2094ERR_FAIL_COND(texture->is_render_target);2095ERR_FAIL_COND(texture->target != GL_TEXTURE_3D);2096ERR_FAIL_COND(p_data.is_empty());20972098GLenum type;2099GLenum format;2100GLenum internal_format;2101bool compressed = false;21022103Image::Format real_format;2104Ref<Image> img = _get_gl_image_and_format(p_data[0], p_data[0]->get_format(), real_format, format, internal_format, type, compressed, texture->resize_to_po2);2105ERR_FAIL_COND(img.is_null());21062107ERR_FAIL_COND_MSG(compressed, "Compressed 3D textures are not supported in the Compatibility renderer.");21082109glActiveTexture(GL_TEXTURE0);2110glBindTexture(texture->target, texture->tex_id);2111_texture_set_swizzle(texture, texture->real_format);21122113// Set filtering and repeat state to default.2114if (texture->mipmaps > 1) {2115texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);2116} else {2117texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);2118}21192120texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);21212122Vector<Ref<Image>> images;2123images.resize(p_data.size());2124for (int i = 0; i < p_data.size(); i++) {2125Ref<Image> image = p_data[i];2126if (image->get_format() != texture->format) {2127image = image->duplicate();2128image->convert(texture->format);2129}2130images.write[i] = image;2131}21322133glPixelStorei(GL_UNPACK_ALIGNMENT, 1);21342135int all_data_size = 0;2136int mipmap_level = 0;2137int layer = 0;2138int depth = texture->depth;2139Size2i prev_size(images[0]->get_width(), images[0]->get_height());2140for (int i = 0; i < images.size(); i++) {2141Ref<Image> image = images[i];2142Size2i img_size(image->get_width(), image->get_height());21432144if (img_size != prev_size) {2145mipmap_level++;2146depth = MAX(1, depth >> 1);2147layer = 0;2148}2149prev_size = img_size;2150all_data_size += image->get_data().size();21512152if (layer == 0 && p_initialize) {2153glTexImage3D(GL_TEXTURE_3D, mipmap_level, internal_format, img_size.width, img_size.height, depth, 0, format, type, nullptr);2154}21552156glTexSubImage3D(GL_TEXTURE_3D, mipmap_level, 0, 0, layer, img_size.width, img_size.height, 1, format, type, image->get_data().ptr());21572158layer++;2159}21602161texture->total_data_size = all_data_size;2162texture->mipmaps = mipmap_level + 1;21632164#ifdef TOOLS_ENABLED2165if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {2166texture->image_cache_3d = images;2167}2168#endif2169}21702171void TextureStorage::_texture_set_swizzle(GLES3::Texture *p_texture, Image::Format p_real_format) {2172#ifndef WEB_ENABLED2173switch (p_texture->format) {2174case Image::FORMAT_L8: {2175if (RasterizerGLES3::is_gles_over_gl()) {2176glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);2177glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_RED);2178glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_RED);2179glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ONE);2180} else {2181glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);2182glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);2183glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);2184glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);2185}2186} break;2187case Image::FORMAT_LA8: {2188if (RasterizerGLES3::is_gles_over_gl()) {2189glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);2190glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_RED);2191glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_RED);2192glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);2193} else {2194glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);2195glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);2196glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);2197glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);2198}2199} break;2200case Image::FORMAT_ETC2_RA_AS_RG:2201case Image::FORMAT_DXT5_RA_AS_RG: {2202glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);2203if (p_texture->format == p_real_format) {2204// Swizzle RA from compressed texture into RG.2205glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_ALPHA);2206} else {2207// Converted textures are already in RG, leave as-is.2208glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);2209}2210glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_ZERO);2211glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ONE);2212} break;2213default: {2214glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);2215glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);2216glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);2217glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);2218} break;2219}2220#endif // WEB_ENABLED2221}22222223Image::Format TextureStorage::texture_get_format(RID p_texture) const {2224Texture *texture = texture_owner.get_or_null(p_texture);22252226ERR_FAIL_NULL_V(texture, Image::FORMAT_L8);22272228return texture->format;2229}22302231uint32_t TextureStorage::texture_get_texid(RID p_texture) const {2232Texture *texture = texture_owner.get_or_null(p_texture);22332234ERR_FAIL_NULL_V(texture, 0);22352236return texture->tex_id;2237}22382239Vector3i TextureStorage::texture_get_size(RID p_texture) const {2240Texture *texture = texture_owner.get_or_null(p_texture);22412242ERR_FAIL_NULL_V(texture, Vector3i(0, 0, 0));22432244return Vector3i(texture->width, texture->height, texture->depth);2245}22462247uint32_t TextureStorage::texture_get_width(RID p_texture) const {2248Texture *texture = texture_owner.get_or_null(p_texture);22492250ERR_FAIL_NULL_V(texture, 0);22512252return texture->width;2253}22542255uint32_t TextureStorage::texture_get_height(RID p_texture) const {2256Texture *texture = texture_owner.get_or_null(p_texture);22572258ERR_FAIL_NULL_V(texture, 0);22592260return texture->height;2261}22622263uint32_t TextureStorage::texture_get_depth(RID p_texture) const {2264Texture *texture = texture_owner.get_or_null(p_texture);22652266ERR_FAIL_NULL_V(texture, 0);22672268return texture->depth;2269}22702271void TextureStorage::texture_bind(RID p_texture, uint32_t p_texture_no) {2272Texture *texture = texture_owner.get_or_null(p_texture);22732274ERR_FAIL_NULL(texture);22752276glActiveTexture(GL_TEXTURE0 + p_texture_no);2277glBindTexture(texture->target, texture->tex_id);2278}22792280/* TEXTURE ATLAS API */22812282void TextureStorage::texture_add_to_texture_atlas(RID p_texture) {2283if (!texture_atlas.textures.has(p_texture)) {2284TextureAtlas::Texture t;2285t.users = 1;2286texture_atlas.textures[p_texture] = t;2287texture_atlas.dirty = true;2288} else {2289TextureAtlas::Texture *t = texture_atlas.textures.getptr(p_texture);2290t->users++;2291}2292}22932294void TextureStorage::texture_remove_from_texture_atlas(RID p_texture) {2295TextureAtlas::Texture *t = texture_atlas.textures.getptr(p_texture);2296ERR_FAIL_NULL(t);2297t->users--;2298if (t->users == 0) {2299texture_atlas.textures.erase(p_texture);2300// Do not mark it dirty, there is no need to since it remains working.2301}2302}23032304void TextureStorage::texture_atlas_mark_dirty_on_texture(RID p_texture) {2305if (texture_atlas.textures.has(p_texture)) {2306texture_atlas.dirty = true; // Mark it dirty since it was most likely modified.2307}2308}23092310void TextureStorage::texture_atlas_remove_texture(RID p_texture) {2311if (texture_atlas.textures.has(p_texture)) {2312texture_atlas.textures.erase(p_texture);2313// There is not much a point of making it dirty, texture can be removed next time the atlas is updated.2314}2315}23162317GLuint TextureStorage::texture_atlas_get_texture() const {2318return texture_atlas.texture;2319}23202321void TextureStorage::update_texture_atlas() {2322CopyEffects *copy_effects = CopyEffects::get_singleton();2323ERR_FAIL_NULL(copy_effects);23242325if (!texture_atlas.dirty) {2326return; //nothing to do2327}23282329texture_atlas.dirty = false;23302331if (texture_atlas.texture != 0) {2332GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);2333texture_atlas.texture = 0;2334glDeleteFramebuffers(1, &texture_atlas.framebuffer);2335texture_atlas.framebuffer = 0;2336}23372338const int border = 2;23392340if (texture_atlas.textures.size()) {2341//generate atlas2342Vector<TextureAtlas::SortItem> itemsv;2343itemsv.resize(texture_atlas.textures.size());2344uint32_t base_size = 8;23452346int idx = 0;23472348for (const KeyValue<RID, TextureAtlas::Texture> &E : texture_atlas.textures) {2349TextureAtlas::SortItem &si = itemsv.write[idx];23502351Texture *src_tex = get_texture(E.key);23522353si.size.width = (src_tex->width / border) + 1;2354si.size.height = (src_tex->height / border) + 1;2355si.pixel_size = Size2i(src_tex->width, src_tex->height);23562357if (base_size < (uint32_t)si.size.width) {2358base_size = nearest_power_of_2_templated(si.size.width);2359}23602361si.texture = E.key;2362idx++;2363}23642365//sort items by size2366itemsv.sort();23672368//attempt to create atlas2369int item_count = itemsv.size();2370TextureAtlas::SortItem *items = itemsv.ptrw();23712372int atlas_height = 0;23732374while (true) {2375Vector<int> v_offsetsv;2376v_offsetsv.resize(base_size);23772378int *v_offsets = v_offsetsv.ptrw();2379memset(v_offsets, 0, sizeof(int) * base_size);23802381int max_height = 0;23822383for (int i = 0; i < item_count; i++) {2384//best fit2385TextureAtlas::SortItem &si = items[i];2386int best_idx = -1;2387int best_height = 0x7FFFFFFF;2388for (uint32_t j = 0; j <= base_size - si.size.width; j++) {2389int height = 0;2390for (int k = 0; k < si.size.width; k++) {2391int h = v_offsets[k + j];2392if (h > height) {2393height = h;2394if (height > best_height) {2395break; //already bad2396}2397}2398}23992400if (height < best_height) {2401best_height = height;2402best_idx = j;2403}2404}24052406//update2407for (int k = 0; k < si.size.width; k++) {2408v_offsets[k + best_idx] = best_height + si.size.height;2409}24102411si.pos.x = best_idx;2412si.pos.y = best_height;24132414if (si.pos.y + si.size.height > max_height) {2415max_height = si.pos.y + si.size.height;2416}2417}24182419if ((uint32_t)max_height <= base_size * 2) {2420atlas_height = max_height;2421break; //good ratio, break;2422}24232424base_size *= 2;2425}24262427texture_atlas.size.width = base_size * border;2428texture_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);24292430for (int i = 0; i < item_count; i++) {2431TextureAtlas::Texture *t = texture_atlas.textures.getptr(items[i].texture);2432t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);2433t->uv_rect.size = items[i].pixel_size;24342435t->uv_rect.position /= Size2(texture_atlas.size);2436t->uv_rect.size /= Size2(texture_atlas.size);2437}2438} else {2439texture_atlas.size.width = 4;2440texture_atlas.size.height = 4;2441}24422443{ // Atlas Texture initialize.2444// TODO validate texture atlas size with maximum texture size2445glGenTextures(1, &texture_atlas.texture);2446glActiveTexture(GL_TEXTURE0);2447glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);2448glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture_atlas.size.width, texture_atlas.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);2449GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, texture_atlas.size.width * texture_atlas.size.height * 4, "Texture atlas");24502451glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);2452glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);2453glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2454glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2455glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);2456glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);24572458glGenFramebuffers(1, &texture_atlas.framebuffer);2459glBindFramebuffer(GL_FRAMEBUFFER, texture_atlas.framebuffer);2460glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_atlas.texture, 0);24612462GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);24632464if (status != GL_FRAMEBUFFER_COMPLETE) {2465glDeleteFramebuffers(1, &texture_atlas.framebuffer);2466texture_atlas.framebuffer = 0;2467GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);2468texture_atlas.texture = 0;2469WARN_PRINT("Could not create texture atlas, status: " + get_framebuffer_error(status));2470return;2471}2472glViewport(0, 0, texture_atlas.size.width, texture_atlas.size.height);2473glClearColor(0.0, 0.0, 0.0, 0.0);2474glClear(GL_COLOR_BUFFER_BIT);2475glBindTexture(GL_TEXTURE_2D, 0);2476}24772478glDisable(GL_BLEND);24792480if (texture_atlas.textures.size()) {2481for (const KeyValue<RID, TextureAtlas::Texture> &E : texture_atlas.textures) {2482TextureAtlas::Texture *t = texture_atlas.textures.getptr(E.key);2483Texture *src_tex = get_texture(E.key);2484glActiveTexture(GL_TEXTURE0);2485glBindTexture(GL_TEXTURE_2D, src_tex->tex_id);2486copy_effects->copy_to_rect(t->uv_rect);2487}2488}2489glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);2490}24912492/* DECAL API */24932494RID TextureStorage::decal_allocate() {2495return RID();2496}24972498void TextureStorage::decal_initialize(RID p_rid) {2499}25002501void TextureStorage::decal_set_size(RID p_decal, const Vector3 &p_size) {2502}25032504void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {2505}25062507void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) {2508}25092510void TextureStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {2511}25122513void TextureStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {2514}25152516void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {2517}25182519void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {2520}25212522void TextureStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {2523}25242525void TextureStorage::decal_set_normal_fade(RID p_decal, float p_fade) {2526}25272528AABB TextureStorage::decal_get_aabb(RID p_decal) const {2529return AABB();2530}25312532/* RENDER TARGET API */25332534GLuint TextureStorage::system_fbo = 0;25352536void TextureStorage::_update_render_target_color(RenderTarget *rt) {2537// do not allocate a render target with no size2538if (rt->size.x <= 0 || rt->size.y <= 0) {2539return;2540}25412542// do not allocate a render target that is attached to the screen2543if (rt->direct_to_screen) {2544rt->fbo = system_fbo;2545return;2546}25472548Config *config = Config::get_singleton();25492550if (rt->hdr) {2551rt->color_internal_format = GL_RGBA16F;2552rt->color_format = GL_RGBA;2553rt->color_type = GL_FLOAT;2554rt->color_format_size = 8;2555rt->image_format = Image::FORMAT_RGBAF;2556} else if (rt->is_transparent) {2557rt->color_internal_format = GL_RGBA8;2558rt->color_format = GL_RGBA;2559rt->color_type = GL_UNSIGNED_BYTE;2560rt->color_format_size = 4;2561rt->image_format = Image::FORMAT_RGBA8;2562} else {2563rt->color_internal_format = GL_RGB10_A2;2564rt->color_format = GL_RGBA;2565rt->color_type = GL_UNSIGNED_INT_2_10_10_10_REV;2566rt->color_format_size = 4;2567rt->image_format = Image::FORMAT_RGBA8;2568}25692570glDisable(GL_SCISSOR_TEST);2571glColorMask(1, 1, 1, 1);2572glDepthMask(GL_FALSE);25732574{2575Texture *texture;2576bool use_multiview = rt->view_count > 1 && config->multiview_supported;2577GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;25782579/* Front FBO */25802581glGenFramebuffers(1, &rt->fbo);2582glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);25832584// color2585if (rt->overridden.color.is_valid()) {2586texture = get_texture(rt->overridden.color);2587ERR_FAIL_NULL(texture);25882589rt->color = texture->tex_id;2590rt->size = Size2i(texture->width, texture->height);2591} else {2592texture = get_texture(rt->texture);2593ERR_FAIL_NULL(texture);25942595glGenTextures(1, &rt->color);2596glBindTexture(texture_target, rt->color);25972598if (use_multiview) {2599glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr);2600} else {2601glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);2602}26032604texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);2605texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);26062607GLES3::Utilities::get_singleton()->texture_allocated_data(rt->color, rt->size.x * rt->size.y * rt->view_count * rt->color_format_size, "Render target color texture");2608}2609#ifndef IOS_ENABLED2610if (use_multiview) {2611glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, 0, rt->view_count);2612} else {2613#else2614{2615#endif2616glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, rt->color, 0);2617}26182619// depth2620if (rt->overridden.depth.is_valid()) {2621texture = get_texture(rt->overridden.depth);2622ERR_FAIL_NULL(texture);26232624rt->depth = texture->tex_id;2625rt->depth_has_stencil = rt->overridden.depth_has_stencil;2626} else {2627glGenTextures(1, &rt->depth);2628glBindTexture(texture_target, rt->depth);26292630if (use_multiview) {2631glTexImage3D(texture_target, 0, GL_DEPTH24_STENCIL8, rt->size.x, rt->size.y, rt->view_count, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);2632} else {2633glTexImage2D(texture_target, 0, GL_DEPTH24_STENCIL8, rt->size.x, rt->size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);2634}26352636glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);2637glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);2638glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2639glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);26402641rt->depth_has_stencil = true;26422643GLES3::Utilities::get_singleton()->texture_allocated_data(rt->depth, rt->size.x * rt->size.y * rt->view_count * 4, "Render target depth texture");2644}26452646#ifndef IOS_ENABLED2647if (use_multiview) {2648glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, rt->depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, rt->depth, 0, 0, rt->view_count);2649} else {2650#else2651{2652#endif2653glFramebufferTexture2D(GL_FRAMEBUFFER, rt->depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, texture_target, rt->depth, 0);2654}26552656GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);2657if (status != GL_FRAMEBUFFER_COMPLETE) {2658glDeleteFramebuffers(1, &rt->fbo);2659if (rt->overridden.color.is_null()) {2660GLES3::Utilities::get_singleton()->texture_free_data(rt->color);2661}2662if (rt->overridden.depth.is_null()) {2663GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);2664}2665rt->fbo = 0;2666rt->size.x = 0;2667rt->size.y = 0;2668rt->color = 0;2669rt->depth = 0;2670if (rt->overridden.color.is_null()) {2671texture->tex_id = 0;2672texture->active = false;2673}2674WARN_PRINT("Could not create render target, status: " + get_framebuffer_error(status));2675return;2676}26772678texture->is_render_target = true;2679texture->render_target = rt;2680if (rt->overridden.color.is_null()) {2681texture->format = rt->image_format;2682texture->real_format = rt->image_format;2683texture->target = texture_target;2684if (rt->view_count > 1 && config->multiview_supported) {2685texture->type = Texture::TYPE_LAYERED;2686texture->layers = rt->view_count;2687} else {2688texture->type = Texture::TYPE_2D;2689texture->layers = 1;2690}2691texture->gl_format_cache = rt->color_format;2692texture->gl_type_cache = !rt->hdr ? GL_UNSIGNED_BYTE : GL_FLOAT; // to set HDR format size to 8 and keep 4 for LDR format2693texture->gl_internal_format_cache = rt->color_internal_format;2694texture->tex_id = rt->color;2695texture->width = rt->size.x;2696texture->alloc_width = rt->size.x;2697texture->height = rt->size.y;2698texture->alloc_height = rt->size.y;2699texture->active = true;2700}2701}27022703glClearColor(0, 0, 0, 0);2704glClear(GL_COLOR_BUFFER_BIT);2705glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);2706}27072708void TextureStorage::_update_render_target_velocity(RenderTarget *rt) {2709GLuint new_velocity_fbo;2710glGenFramebuffers(1, &new_velocity_fbo);2711glBindFramebuffer(GL_FRAMEBUFFER, new_velocity_fbo);27122713uint32_t view_count = rt->view_count;2714GLuint texture_target = view_count > 1 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;27152716GLuint velocity_texture_id = texture_get_texid(rt->overridden.velocity);2717glBindTexture(texture_target, velocity_texture_id);2718glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2719glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2720glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);2721glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);27222723#ifndef IOS_ENABLED2724if (view_count > 1) {2725glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, velocity_texture_id, 0, 0, view_count);2726} else {2727#else2728{2729#endif2730glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, velocity_texture_id, 0);2731}27322733GLuint velocity_depth_texture_id = texture_get_texid(rt->overridden.velocity_depth);2734glBindTexture(texture_target, velocity_depth_texture_id);2735glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2736glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2737glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);2738glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);27392740#ifndef IOS_ENABLED2741if (view_count > 1) {2742glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, velocity_depth_texture_id, 0, 0, view_count);2743} else {2744#else2745{2746#endif2747glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, velocity_depth_texture_id, 0);2748}27492750GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);2751if (status != GL_FRAMEBUFFER_COMPLETE) {2752glDeleteFramebuffers(1, &new_velocity_fbo);2753WARN_PRINT(vformat("Could not create motion vector render target, status: %s.", GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status)));2754} else {2755rt->overridden.velocity_fbo = new_velocity_fbo;2756}27572758glBindTexture(texture_target, 0);2759glBindFramebuffer(GL_FRAMEBUFFER, 0);2760}27612762void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {2763ERR_FAIL_COND_MSG(rt->backbuffer_fbo != 0, "Cannot allocate RenderTarget backbuffer: already initialized.");2764ERR_FAIL_COND(rt->direct_to_screen);2765// Allocate mipmap chains for full screen blur2766// Limit mipmaps so smallest is 32x32 to avoid unnecessary framebuffer switches2767int count = MAX(1, Image::get_image_required_mipmaps(rt->size.x, rt->size.y, Image::FORMAT_RGBA8) - 4);2768if (rt->size.x > 40 && rt->size.y > 40) {2769GLsizei width = rt->size.x;2770GLsizei height = rt->size.y;27712772rt->mipmap_count = count;27732774glGenTextures(1, &rt->backbuffer);2775glBindTexture(GL_TEXTURE_2D, rt->backbuffer);2776uint32_t texture_size_bytes = 0;27772778for (int l = 0; l < count; l++) {2779texture_size_bytes += width * height * 4;2780glTexImage2D(GL_TEXTURE_2D, l, rt->color_internal_format, width, height, 0, rt->color_format, rt->color_type, nullptr);2781width = MAX(1, (width / 2));2782height = MAX(1, (height / 2));2783}27842785glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);2786glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1);27872788glGenFramebuffers(1, &rt->backbuffer_fbo);2789glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);27902791glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);27922793GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);2794if (status != GL_FRAMEBUFFER_COMPLETE) {2795WARN_PRINT_ONCE("Cannot allocate mipmaps for canvas screen blur. Status: " + get_framebuffer_error(status));2796glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);2797return;2798}2799GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, texture_size_bytes, "Render target backbuffer color texture");28002801// Initialize all levels to clear black.2802for (int j = 0; j < count; j++) {2803glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, j);2804glClearColor(0.0, 0.0, 0.0, 0.0);2805glClear(GL_COLOR_BUFFER_BIT);2806}28072808glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);28092810glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);2811glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);2812glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);2813glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);2814}2815}28162817void TextureStorage::_clear_render_target(RenderTarget *rt) {2818// there is nothing else to clear when DIRECT_TO_SCREEN is used2819if (rt->direct_to_screen) {2820return;2821}28222823for (KeyValue<uint32_t, GLuint> &E : rt->overridden.velocity_fbo_cache) {2824glDeleteFramebuffers(1, &E.value);2825}2826rt->overridden.velocity_fbo_cache.clear();2827rt->overridden.velocity_fbo = 0;28282829// Dispose of the cached fbo's and the allocated textures2830for (KeyValue<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry> &E : rt->overridden.fbo_cache) {2831glDeleteTextures(E.value.allocated_textures.size(), E.value.allocated_textures.ptr());2832// Don't delete the current FBO, we'll do that a couple lines down.2833if (E.value.fbo != rt->fbo) {2834glDeleteFramebuffers(1, &E.value.fbo);2835}2836}2837rt->overridden.fbo_cache.clear();28382839if (rt->fbo) {2840glDeleteFramebuffers(1, &rt->fbo);2841rt->fbo = 0;2842}28432844if (rt->overridden.color.is_null()) {2845if (rt->texture.is_valid()) {2846Texture *tex = get_texture(rt->texture);2847tex->alloc_height = 0;2848tex->alloc_width = 0;2849tex->width = 0;2850tex->height = 0;2851tex->active = false;2852tex->render_target = nullptr;2853tex->is_render_target = false;2854tex->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_MAX);2855tex->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX);2856}2857} else {2858Texture *tex = get_texture(rt->overridden.color);2859tex->render_target = nullptr;2860tex->is_render_target = false;2861}28622863if (rt->overridden.color.is_valid()) {2864rt->overridden.color = RID();2865} else if (rt->color) {2866GLES3::Utilities::get_singleton()->texture_free_data(rt->color);2867if (rt->texture.is_valid()) {2868Texture *tex = get_texture(rt->texture);2869tex->tex_id = 0;2870}2871}2872rt->color = 0;28732874if (rt->overridden.depth.is_valid()) {2875rt->overridden.depth = RID();2876} else if (rt->depth) {2877GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);2878}2879rt->depth = 0;28802881rt->overridden.is_overridden = false;28822883if (rt->backbuffer_fbo != 0) {2884glDeleteFramebuffers(1, &rt->backbuffer_fbo);2885rt->backbuffer_fbo = 0;2886}2887if (rt->backbuffer != 0) {2888GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer);2889rt->backbuffer = 0;2890}2891if (rt->backbuffer_depth != 0) {2892GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer_depth);2893rt->backbuffer_depth = 0;2894}2895_render_target_clear_sdf(rt);2896}28972898RID TextureStorage::render_target_create() {2899RenderTarget render_target;2900render_target.used_in_frame = false;2901render_target.clear_requested = false;29022903Texture t;2904t.active = true;2905t.render_target = &render_target;2906t.is_render_target = true;29072908render_target.texture = texture_owner.make_rid(t);2909_update_render_target_color(&render_target);2910return render_target_owner.make_rid(render_target);2911}29122913void TextureStorage::render_target_free(RID p_rid) {2914RenderTarget *rt = render_target_owner.get_or_null(p_rid);2915_clear_render_target(rt);29162917Texture *t = get_texture(rt->texture);2918if (t) {2919t->is_render_target = false;2920if (rt->overridden.color.is_null()) {2921texture_free(rt->texture);2922}2923//memdelete(t);2924}2925render_target_owner.free(p_rid);2926}29272928void TextureStorage::render_target_set_position(RID p_render_target, int p_x, int p_y) {2929RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2930ERR_FAIL_NULL(rt);29312932rt->position = Point2i(p_x, p_y);2933}29342935Point2i TextureStorage::render_target_get_position(RID p_render_target) const {2936RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2937ERR_FAIL_NULL_V(rt, Point2i());29382939return rt->position;2940}29412942void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {2943RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2944ERR_FAIL_NULL(rt);29452946if (p_width == rt->size.x && p_height == rt->size.y && p_view_count == rt->view_count) {2947return;2948}2949if (rt->overridden.color.is_valid()) {2950return;2951}29522953_clear_render_target(rt);29542955rt->size = Size2i(p_width, p_height);2956rt->view_count = p_view_count;29572958_update_render_target_color(rt);2959}29602961// TODO: convert to Size2i internally2962Size2i TextureStorage::render_target_get_size(RID p_render_target) const {2963RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2964ERR_FAIL_NULL_V(rt, Size2i());29652966return rt->size;2967}29682969void TextureStorage::render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture, RID p_velocity_depth_texture) {2970RenderTarget *rt = render_target_owner.get_or_null(p_render_target);2971ERR_FAIL_NULL(rt);2972ERR_FAIL_COND(rt->direct_to_screen);29732974// Remember what our current color output is.2975RID was_color_texture = render_target_get_texture(p_render_target);29762977bool create_new_color_fbo = true;2978bool create_new_velocity_fbo = true;29792980if (rt->overridden.color == p_color_texture && rt->overridden.depth == p_depth_texture && rt->overridden.velocity == p_velocity_texture && rt->overridden.velocity_depth == p_velocity_depth_texture) {2981return;2982}29832984if (p_color_texture.is_null() && p_depth_texture.is_null()) {2985// Set this back to our default textures.2986if (was_color_texture.is_valid()) {2987texture_remap_proxies(was_color_texture, rt->texture);2988}29892990_clear_render_target(rt);2991_update_render_target_color(rt);2992create_new_color_fbo = false;2993}29942995if (!rt->overridden.is_overridden) {2996_clear_render_target(rt);2997}29982999rt->overridden.color = p_color_texture;3000rt->overridden.depth = p_depth_texture;3001rt->overridden.depth_has_stencil = p_depth_texture.is_null();3002rt->overridden.velocity = p_velocity_texture;3003rt->overridden.velocity_depth = p_velocity_depth_texture;3004rt->overridden.is_overridden = true;30053006// Update to our new color output.3007RID new_color_texture = render_target_get_texture(p_render_target);3008if (was_color_texture.is_valid() && new_color_texture.is_valid()) {3009texture_remap_proxies(was_color_texture, new_color_texture);3010}30113012uint32_t hash_key = hash_murmur3_one_64(p_color_texture.get_id());3013hash_key = hash_murmur3_one_64(p_depth_texture.get_id(), hash_key);3014hash_key = hash_fmix32(hash_key);30153016RBMap<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry>::Element *cache;3017if ((cache = rt->overridden.fbo_cache.find(hash_key)) != nullptr) {3018rt->fbo = cache->get().fbo;3019rt->color = cache->get().color;3020rt->depth = cache->get().depth;3021rt->depth_has_stencil = cache->get().depth_has_stencil;3022rt->size = cache->get().size;3023rt->texture = p_color_texture;3024create_new_color_fbo = false;3025}30263027uint32_t velocity_hash_key = hash_murmur3_one_64(p_velocity_texture.get_id());3028velocity_hash_key = hash_murmur3_one_64(p_velocity_depth_texture.get_id(), velocity_hash_key);3029velocity_hash_key = hash_fmix32(velocity_hash_key);30303031RBMap<uint32_t, GLuint>::Element *fbo = rt->overridden.velocity_fbo_cache.find(velocity_hash_key);3032if (fbo != nullptr) {3033rt->overridden.velocity_fbo = fbo->get();3034create_new_velocity_fbo = false;3035}30363037if (p_velocity_texture.is_null()) {3038for (KeyValue<uint32_t, GLuint> &E : rt->overridden.velocity_fbo_cache) {3039glDeleteFramebuffers(1, &E.value);3040}30413042rt->overridden.velocity_fbo_cache.clear();3043rt->overridden.velocity_fbo = 0;3044create_new_velocity_fbo = false;3045}30463047if (create_new_color_fbo) {3048_update_render_target_color(rt);30493050RenderTarget::RTOverridden::FBOCacheEntry new_entry;3051new_entry.fbo = rt->fbo;3052new_entry.color = rt->color;3053new_entry.depth = rt->depth;3054new_entry.size = rt->size;3055// Keep track of any textures we had to allocate because they weren't overridden.3056if (p_color_texture.is_null()) {3057new_entry.allocated_textures.push_back(rt->color);3058}3059if (p_depth_texture.is_null()) {3060new_entry.allocated_textures.push_back(rt->depth);3061}3062rt->overridden.fbo_cache.insert(hash_key, new_entry);3063}30643065if (create_new_velocity_fbo) {3066_update_render_target_velocity(rt);3067rt->overridden.velocity_fbo_cache.insert(velocity_hash_key, rt->overridden.velocity_fbo);3068}3069}30703071RID TextureStorage::render_target_get_override_color(RID p_render_target) const {3072RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3073ERR_FAIL_NULL_V(rt, RID());30743075return rt->overridden.color;3076}30773078RID TextureStorage::render_target_get_override_depth(RID p_render_target) const {3079RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3080ERR_FAIL_NULL_V(rt, RID());30813082return rt->overridden.depth;3083}30843085RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const {3086RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3087ERR_FAIL_NULL_V(rt, RID());30883089return rt->overridden.velocity;3090}30913092RID TextureStorage::render_target_get_override_velocity_depth(RID p_render_target) const {3093RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3094ERR_FAIL_NULL_V(rt, RID());30953096return rt->overridden.velocity_depth;3097}30983099void TextureStorage::render_target_set_render_region(RID p_render_target, const Rect2i &p_render_region) {3100RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3101ERR_FAIL_NULL(rt);31023103rt->render_region = p_render_region;3104}31053106Rect2i TextureStorage::render_target_get_render_region(RID p_render_target) const {3107RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3108ERR_FAIL_NULL_V(rt, Rect2i());31093110return rt->render_region;3111}31123113RID TextureStorage::render_target_get_texture(RID p_render_target) {3114RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3115ERR_FAIL_NULL_V(rt, RID());31163117if (rt->overridden.color.is_valid()) {3118return rt->overridden.color;3119}31203121return rt->texture;3122}31233124void TextureStorage::render_target_set_velocity_target_size(RID p_render_target, const Size2i &p_target_size) {3125RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3126ERR_FAIL_NULL(rt);31273128rt->velocity_target_size = p_target_size;3129}31303131Size2i TextureStorage::render_target_get_velocity_target_size(RID p_render_target) const {3132RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3133ERR_FAIL_NULL_V(rt, Size2i(0, 0));31343135return rt->velocity_target_size;3136}31373138void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_transparent) {3139RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3140ERR_FAIL_NULL(rt);31413142rt->is_transparent = p_transparent;31433144if (rt->overridden.color.is_null()) {3145_clear_render_target(rt);3146_update_render_target_color(rt);3147}3148}31493150bool TextureStorage::render_target_get_transparent(RID p_render_target) const {3151RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3152ERR_FAIL_NULL_V(rt, false);31533154return rt->is_transparent;3155}31563157void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) {3158RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3159ERR_FAIL_NULL(rt);31603161if (p_direct_to_screen == rt->direct_to_screen) {3162return;3163}3164// When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as3165// those functions change how they operate depending on the value of DIRECT_TO_SCREEN3166_clear_render_target(rt);3167rt->direct_to_screen = p_direct_to_screen;3168if (rt->direct_to_screen) {3169rt->overridden.color = RID();3170rt->overridden.depth = RID();3171rt->overridden.velocity = RID();3172rt->overridden.velocity_depth = RID();3173}3174_update_render_target_color(rt);3175}31763177bool TextureStorage::render_target_get_direct_to_screen(RID p_render_target) const {3178RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3179ERR_FAIL_NULL_V(rt, false);31803181return rt->direct_to_screen;3182}31833184bool TextureStorage::render_target_was_used(RID p_render_target) const {3185RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3186ERR_FAIL_NULL_V(rt, false);31873188return rt->used_in_frame;3189}31903191void TextureStorage::render_target_clear_used(RID p_render_target) {3192RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3193ERR_FAIL_NULL(rt);31943195rt->used_in_frame = false;3196}31973198void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) {3199RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3200ERR_FAIL_NULL(rt);3201ERR_FAIL_COND(rt->direct_to_screen);3202if (p_msaa == rt->msaa) {3203return;3204}32053206WARN_PRINT("2D MSAA is not yet supported for GLES3.");32073208if (rt->overridden.color.is_null()) {3209_clear_render_target(rt);3210rt->msaa = p_msaa;3211_update_render_target_color(rt);3212}3213}32143215RS::ViewportMSAA TextureStorage::render_target_get_msaa(RID p_render_target) const {3216RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3217ERR_FAIL_NULL_V(rt, RS::VIEWPORT_MSAA_DISABLED);32183219return rt->msaa;3220}32213222void TextureStorage::render_target_set_use_hdr(RID p_render_target, bool p_use_hdr_2d) {3223RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3224ERR_FAIL_NULL(rt);3225ERR_FAIL_COND(rt->direct_to_screen);3226if (p_use_hdr_2d == rt->hdr) {3227return;3228}32293230if (rt->overridden.color.is_null()) {3231_clear_render_target(rt);3232rt->hdr = p_use_hdr_2d;3233_update_render_target_color(rt);3234}3235}32363237bool TextureStorage::render_target_is_using_hdr(RID p_render_target) const {3238RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3239ERR_FAIL_NULL_V(rt, false);32403241return rt->hdr;3242}32433244GLuint TextureStorage::render_target_get_color_internal_format(RID p_render_target) const {3245RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3246ERR_FAIL_NULL_V(rt, GL_RGBA8);32473248return rt->color_internal_format;3249}32503251GLuint TextureStorage::render_target_get_color_format(RID p_render_target) const {3252RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3253ERR_FAIL_NULL_V(rt, GL_RGBA);32543255return rt->color_format;3256}32573258GLuint TextureStorage::render_target_get_color_type(RID p_render_target) const {3259RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3260ERR_FAIL_NULL_V(rt, GL_UNSIGNED_BYTE);32613262return rt->color_type;3263}32643265uint32_t TextureStorage::render_target_get_color_format_size(RID p_render_target) const {3266RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3267ERR_FAIL_NULL_V(rt, 4);32683269return rt->color_format_size;3270}32713272void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {3273RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3274ERR_FAIL_NULL(rt);3275rt->clear_requested = true;3276rt->clear_color = p_clear_color;3277}32783279bool TextureStorage::render_target_is_clear_requested(RID p_render_target) {3280RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3281ERR_FAIL_NULL_V(rt, false);3282return rt->clear_requested;3283}3284Color TextureStorage::render_target_get_clear_request_color(RID p_render_target) {3285RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3286ERR_FAIL_NULL_V(rt, Color());3287return rt->clear_color;3288}32893290void TextureStorage::render_target_disable_clear_request(RID p_render_target) {3291RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3292ERR_FAIL_NULL(rt);3293rt->clear_requested = false;3294}32953296void TextureStorage::render_target_do_clear_request(RID p_render_target) {3297RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3298ERR_FAIL_NULL(rt);3299if (!rt->clear_requested) {3300return;3301}3302glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);33033304glClearBufferfv(GL_COLOR, 0, rt->clear_color.components);3305rt->clear_requested = false;3306glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);3307}33083309GLuint TextureStorage::render_target_get_fbo(RID p_render_target) const {3310RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3311ERR_FAIL_NULL_V(rt, 0);33123313return rt->fbo;3314}33153316GLuint TextureStorage::render_target_get_color(RID p_render_target) const {3317RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3318ERR_FAIL_NULL_V(rt, 0);33193320if (rt->overridden.color.is_valid()) {3321Texture *texture = get_texture(rt->overridden.color);3322ERR_FAIL_NULL_V(texture, 0);33233324return texture->tex_id;3325} else {3326return rt->color;3327}3328}33293330GLuint TextureStorage::render_target_get_depth(RID p_render_target) const {3331RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3332ERR_FAIL_NULL_V(rt, 0);33333334if (rt->overridden.depth.is_valid()) {3335Texture *texture = get_texture(rt->overridden.depth);3336ERR_FAIL_NULL_V(texture, 0);33373338return texture->tex_id;3339} else {3340return rt->depth;3341}3342}33433344bool TextureStorage::render_target_get_depth_has_stencil(RID p_render_target) const {3345RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3346ERR_FAIL_NULL_V(rt, 0);33473348return rt->depth_has_stencil;3349}33503351void TextureStorage::render_target_set_reattach_textures(RID p_render_target, bool p_reattach_textures) const {3352RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3353ERR_FAIL_NULL(rt);33543355rt->reattach_textures = p_reattach_textures;3356}33573358bool TextureStorage::render_target_is_reattach_textures(RID p_render_target) const {3359RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3360ERR_FAIL_NULL_V(rt, false);33613362return rt->reattach_textures;3363}33643365void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {3366RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3367ERR_FAIL_NULL(rt);3368if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) {3369return;3370}33713372rt->sdf_oversize = p_size;3373rt->sdf_scale = p_scale;33743375_render_target_clear_sdf(rt);3376}33773378Rect2i TextureStorage::_render_target_get_sdf_rect(const RenderTarget *rt) const {3379Size2i margin;3380int scale;3381switch (rt->sdf_oversize) {3382case RS::VIEWPORT_SDF_OVERSIZE_100_PERCENT: {3383scale = 100;3384} break;3385case RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT: {3386scale = 120;3387} break;3388case RS::VIEWPORT_SDF_OVERSIZE_150_PERCENT: {3389scale = 150;3390} break;3391case RS::VIEWPORT_SDF_OVERSIZE_200_PERCENT: {3392scale = 200;3393} break;3394default: {3395ERR_PRINT("Invalid viewport SDF oversize, defaulting to 100%.");3396scale = 100;3397} break;3398}33993400margin = (rt->size * scale / 100) - rt->size;34013402Rect2i r(Vector2i(), rt->size);3403r.position -= margin;3404r.size += margin * 2;34053406return r;3407}34083409Rect2i TextureStorage::render_target_get_sdf_rect(RID p_render_target) const {3410const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3411ERR_FAIL_NULL_V(rt, Rect2i());34123413return _render_target_get_sdf_rect(rt);3414}34153416void TextureStorage::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {3417RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3418ERR_FAIL_NULL(rt);34193420rt->sdf_enabled = p_enabled;3421}34223423bool TextureStorage::render_target_is_sdf_enabled(RID p_render_target) const {3424const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3425ERR_FAIL_NULL_V(rt, false);34263427return rt->sdf_enabled;3428}34293430GLuint TextureStorage::render_target_get_sdf_texture(RID p_render_target) {3431RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3432ERR_FAIL_NULL_V(rt, 0);3433if (rt->sdf_texture_read == 0) {3434Texture *texture = texture_owner.get_or_null(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK]);3435return texture->tex_id;3436}34373438return rt->sdf_texture_read;3439}34403441void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {3442ERR_FAIL_COND(rt->sdf_texture_write_fb != 0);34433444Size2i size = _render_target_get_sdf_rect(rt).size;34453446glGenTextures(1, &rt->sdf_texture_write);3447glActiveTexture(GL_TEXTURE0);3448glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);3449glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size.width, size.height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);3450GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_write, size.width * size.height, "SDF texture");3451glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);3452glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);3453glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);3454glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);3455glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);3456glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);34573458glGenFramebuffers(1, &rt->sdf_texture_write_fb);3459glBindFramebuffer(GL_FRAMEBUFFER, rt->sdf_texture_write_fb);3460glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_write, 0);34613462int scale;3463switch (rt->sdf_scale) {3464case RS::VIEWPORT_SDF_SCALE_100_PERCENT: {3465scale = 100;3466} break;3467case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {3468scale = 50;3469} break;3470case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {3471scale = 25;3472} break;3473default: {3474ERR_PRINT("Invalid viewport SDF scale, defaulting to 100%.");3475scale = 100;3476} break;3477}34783479rt->process_size = size * scale / 100;3480rt->process_size = rt->process_size.maxi(1);34813482glGenTextures(2, rt->sdf_texture_process);3483glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[0]);3484glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);3485glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);3486glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);3487glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);3488glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);3489glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);3490glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);3491GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[0], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[0]");34923493glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[1]);3494glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);3495glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);3496glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);3497glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);3498glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);3499glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);3500glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);3501GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[1], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[1]");35023503glGenTextures(1, &rt->sdf_texture_read);3504glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_read);3505glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->process_size.width, rt->process_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);3506glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);3507glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);3508glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);3509glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);3510glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);3511glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);3512GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_read, rt->process_size.width * rt->process_size.height * 4, "SDF texture (read)");3513}35143515void TextureStorage::_render_target_clear_sdf(RenderTarget *rt) {3516if (rt->sdf_texture_write_fb != 0) {3517GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_read);3518GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_write);3519GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[0]);3520GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[1]);35213522glDeleteFramebuffers(1, &rt->sdf_texture_write_fb);3523rt->sdf_texture_read = 0;3524rt->sdf_texture_write = 0;3525rt->sdf_texture_process[0] = 0;3526rt->sdf_texture_process[1] = 0;3527rt->sdf_texture_write_fb = 0;3528}3529}35303531GLuint TextureStorage::render_target_get_sdf_framebuffer(RID p_render_target) {3532RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3533ERR_FAIL_NULL_V(rt, 0);35343535if (rt->sdf_texture_write_fb == 0) {3536_render_target_allocate_sdf(rt);3537}35383539return rt->sdf_texture_write_fb;3540}3541void TextureStorage::render_target_sdf_process(RID p_render_target) {3542CopyEffects *copy_effects = CopyEffects::get_singleton();35433544RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3545ERR_FAIL_NULL(rt);3546ERR_FAIL_COND(rt->sdf_texture_write_fb == 0);35473548Rect2i r = _render_target_get_sdf_rect(rt);35493550Size2i size = r.size;3551int32_t shift = 0;35523553bool shrink = false;35543555switch (rt->sdf_scale) {3556case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {3557size[0] >>= 1;3558size[1] >>= 1;3559shift = 1;3560shrink = true;3561} break;3562case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {3563size[0] >>= 2;3564size[1] >>= 2;3565shift = 2;3566shrink = true;3567} break;3568default: {3569};3570}35713572GLuint temp_fb;3573glGenFramebuffers(1, &temp_fb);3574glBindFramebuffer(GL_FRAMEBUFFER, temp_fb);35753576// Load3577CanvasSdfShaderGLES3::ShaderVariant variant = shrink ? CanvasSdfShaderGLES3::MODE_LOAD_SHRINK : CanvasSdfShaderGLES3::MODE_LOAD;3578bool success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);3579if (!success) {3580return;3581}35823583sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);3584sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);3585sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, 0, sdf_shader.shader_version, variant);3586sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);35873588glActiveTexture(GL_TEXTURE0);3589glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);35903591glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_process[0], 0);3592glViewport(0, 0, size.width, size.height);3593glEnable(GL_SCISSOR_TEST);3594glScissor(0, 0, size.width, size.height);35953596copy_effects->draw_screen_triangle();35973598// Process35993600int stride = nearest_power_of_2_templated(MAX(size.width, size.height) / 2);36013602variant = CanvasSdfShaderGLES3::MODE_PROCESS;3603success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);3604if (!success) {3605return;3606}36073608sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);3609sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);3610sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);3611sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);36123613bool swap = false;36143615//jumpflood3616while (stride > 0) {3617glBindTexture(GL_TEXTURE_2D, 0);3618glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 0 : 1], 0);3619glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 1 : 0]);36203621sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);36223623copy_effects->draw_screen_triangle();36243625stride /= 2;3626swap = !swap;3627}36283629// Store3630variant = shrink ? CanvasSdfShaderGLES3::MODE_STORE_SHRINK : CanvasSdfShaderGLES3::MODE_STORE;3631success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);3632if (!success) {3633return;3634}36353636sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);3637sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);3638sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);3639sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);36403641glBindTexture(GL_TEXTURE_2D, 0);3642glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_read, 0);3643glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 1 : 0]);36443645copy_effects->draw_screen_triangle();36463647glBindTexture(GL_TEXTURE_2D, 0);3648glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);3649glDeleteFramebuffers(1, &temp_fb);3650glDisable(GL_SCISSOR_TEST);3651}36523653void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {3654RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3655ERR_FAIL_NULL(rt);3656ERR_FAIL_COND(rt->direct_to_screen);36573658if (rt->backbuffer_fbo == 0) {3659_create_render_target_backbuffer(rt);3660}36613662Rect2i region;3663if (p_region == Rect2i()) {3664region.size = rt->size;3665} else {3666region = Rect2i(Size2i(), rt->size).intersection(p_region);3667if (region.size == Size2i()) {3668return; //nothing to do3669}3670}36713672glDisable(GL_BLEND);3673// Single texture copy for backbuffer.3674glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3675glActiveTexture(GL_TEXTURE0);3676glBindTexture(GL_TEXTURE_2D, rt->color);3677Rect2 normalized_region = region;3678normalized_region.position = normalized_region.position / Size2(rt->size);3679normalized_region.size = normalized_region.size / Size2(rt->size);3680GLES3::CopyEffects::get_singleton()->copy_to_and_from_rect(normalized_region);36813682if (p_gen_mipmaps) {3683GLES3::CopyEffects::get_singleton()->gaussian_blur(rt->backbuffer, rt->mipmap_count, region, rt->size);3684glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3685}36863687glEnable(GL_BLEND); // 2D starts with blend enabled.3688}36893690void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {3691RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3692ERR_FAIL_NULL(rt);3693ERR_FAIL_COND(rt->direct_to_screen);36943695if (rt->backbuffer_fbo == 0) {3696_create_render_target_backbuffer(rt);3697}36983699Rect2i region;3700if (p_region == Rect2i()) {3701// Just do a full screen clear;3702glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3703glClearColor(p_color.r, p_color.g, p_color.b, p_color.a);3704glClear(GL_COLOR_BUFFER_BIT);3705} else {3706region = Rect2i(Size2i(), rt->size).intersection(p_region);3707if (region.size == Size2i()) {3708return; //nothing to do3709}3710glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3711GLES3::CopyEffects::get_singleton()->set_color(p_color, region);3712}3713}37143715void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {3716RenderTarget *rt = render_target_owner.get_or_null(p_render_target);3717ERR_FAIL_NULL(rt);37183719if (rt->backbuffer_fbo == 0) {3720_create_render_target_backbuffer(rt);3721}37223723Rect2i region;3724if (p_region == Rect2i()) {3725region.size = rt->size;3726} else {3727region = Rect2i(Size2i(), rt->size).intersection(p_region);3728if (region.size == Size2i()) {3729return; //nothing to do3730}3731}3732glDisable(GL_BLEND);3733GLES3::CopyEffects::get_singleton()->gaussian_blur(rt->backbuffer, rt->mipmap_count, region, rt->size);3734glEnable(GL_BLEND); // 2D starts with blend enabled.37353736glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);3737}37383739#endif // GLES3_ENABLED374037413742