Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/drivers/gles3/storage/texture_storage.cpp
20943 views
1
/**************************************************************************/
2
/* texture_storage.cpp */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#ifdef GLES3_ENABLED
32
33
#include "texture_storage.h"
34
35
#include "../effects/copy_effects.h"
36
#include "../rasterizer_gles3.h"
37
#include "config.h"
38
#include "utilities.h"
39
40
using namespace GLES3;
41
42
TextureStorage *TextureStorage::singleton = nullptr;
43
44
TextureStorage *TextureStorage::get_singleton() {
45
return singleton;
46
}
47
48
static const GLenum _cube_side_enum[6] = {
49
GL_TEXTURE_CUBE_MAP_POSITIVE_X,
50
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
51
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
52
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
53
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
54
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
55
};
56
57
TextureStorage::TextureStorage() {
58
singleton = this;
59
60
{ //create default textures
61
{ // White Textures
62
63
Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
64
image->fill(Color(1, 1, 1, 1));
65
image->generate_mipmaps();
66
67
default_gl_textures[DEFAULT_GL_TEXTURE_WHITE] = texture_allocate();
68
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE], image);
69
70
Vector<Ref<Image>> images;
71
images.push_back(image);
72
73
default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE] = texture_allocate();
74
texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_WHITE], images, RS::TEXTURE_LAYERED_2D_ARRAY);
75
76
for (int i = 0; i < 5; i++) {
77
images.push_back(image);
78
}
79
80
default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_WHITE] = texture_allocate();
81
texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_WHITE], images, RS::TEXTURE_LAYERED_CUBEMAP);
82
}
83
84
{
85
Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
86
image->fill(Color(1, 1, 1, 1));
87
88
Vector<Ref<Image>> images;
89
for (int i = 0; i < 4; i++) {
90
images.push_back(image);
91
}
92
default_gl_textures[DEFAULT_GL_TEXTURE_3D_WHITE] = texture_allocate();
93
texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_WHITE], image->get_format(), 4, 4, 4, false, images);
94
}
95
96
{ // black
97
Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
98
image->fill(Color(0, 0, 0, 1));
99
image->generate_mipmaps();
100
101
default_gl_textures[DEFAULT_GL_TEXTURE_BLACK] = texture_allocate();
102
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK], image);
103
104
Vector<Ref<Image>> images;
105
images.push_back(image);
106
107
default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_BLACK] = texture_allocate();
108
texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_BLACK], images, RS::TEXTURE_LAYERED_2D_ARRAY);
109
110
for (int i = 0; i < 5; i++) {
111
images.push_back(image);
112
}
113
default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK] = texture_allocate();
114
texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_BLACK], images, RS::TEXTURE_LAYERED_CUBEMAP);
115
}
116
117
{
118
Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
119
image->fill(Color());
120
121
Vector<Ref<Image>> images;
122
for (int i = 0; i < 4; i++) {
123
images.push_back(image);
124
}
125
default_gl_textures[DEFAULT_GL_TEXTURE_3D_BLACK] = texture_allocate();
126
texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_BLACK], image->get_format(), 4, 4, 4, false, images);
127
}
128
129
{ // transparent black
130
Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
131
image->fill(Color(0, 0, 0, 0));
132
image->generate_mipmaps();
133
134
default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT] = texture_allocate();
135
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_TRANSPARENT], image);
136
137
Vector<Ref<Image>> images;
138
images.push_back(image);
139
140
default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_TRANSPARENT] = texture_allocate();
141
texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_2D_ARRAY_TRANSPARENT], images, RS::TEXTURE_LAYERED_2D_ARRAY);
142
143
for (int i = 0; i < 5; i++) {
144
images.push_back(image);
145
}
146
147
default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_TRANSPARENT] = texture_allocate();
148
texture_2d_layered_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_CUBEMAP_TRANSPARENT], images, RS::TEXTURE_LAYERED_CUBEMAP);
149
}
150
151
{
152
Ref<Image> image = Image::create_empty(4, 4, false, Image::FORMAT_RGBA8);
153
image->fill(Color(0, 0, 0, 0));
154
155
Vector<Ref<Image>> images;
156
for (int i = 0; i < 4; i++) {
157
images.push_back(image);
158
}
159
default_gl_textures[DEFAULT_GL_TEXTURE_3D_TRANSPARENT] = texture_allocate();
160
texture_3d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_3D_TRANSPARENT], image->get_format(), 4, 4, 4, false, images);
161
}
162
163
{
164
Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
165
image->fill(Color(0.5, 0.5, 1, 1));
166
image->generate_mipmaps();
167
168
default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL] = texture_allocate();
169
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_NORMAL], image);
170
}
171
172
{
173
Ref<Image> image = Image::create_empty(4, 4, true, Image::FORMAT_RGBA8);
174
image->fill(Color(1.0, 0.5, 1, 1));
175
image->generate_mipmaps();
176
177
default_gl_textures[DEFAULT_GL_TEXTURE_ANISO] = texture_allocate();
178
texture_2d_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_ANISO], image);
179
}
180
181
{
182
default_gl_textures[DEFAULT_GL_TEXTURE_EXT] = texture_allocate();
183
texture_external_initialize(default_gl_textures[DEFAULT_GL_TEXTURE_EXT], 1, 1, 0);
184
}
185
186
{
187
unsigned char pixel_data[4 * 4 * 4];
188
for (int i = 0; i < 16; i++) {
189
pixel_data[i * 4 + 0] = 0;
190
pixel_data[i * 4 + 1] = 0;
191
pixel_data[i * 4 + 2] = 0;
192
pixel_data[i * 4 + 3] = 0;
193
}
194
195
default_gl_textures[DEFAULT_GL_TEXTURE_2D_UINT] = texture_allocate();
196
Texture texture;
197
texture.width = 4;
198
texture.height = 4;
199
texture.format = Image::FORMAT_RGBA8;
200
texture.type = Texture::TYPE_2D;
201
texture.target = GL_TEXTURE_2D;
202
texture.active = true;
203
glGenTextures(1, &texture.tex_id);
204
texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_2D_UINT], texture);
205
206
glBindTexture(GL_TEXTURE_2D, texture.tex_id);
207
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 4, 4, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, pixel_data);
208
GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 4, "Default uint texture");
209
texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
210
}
211
{
212
uint16_t pixel_data[4 * 4];
213
for (int i = 0; i < 16; i++) {
214
pixel_data[i] = Math::make_half_float(1.0f);
215
}
216
217
default_gl_textures[DEFAULT_GL_TEXTURE_DEPTH] = texture_allocate();
218
Texture texture;
219
texture.width = 4;
220
texture.height = 4;
221
texture.format = Image::FORMAT_RGBA8;
222
texture.type = Texture::TYPE_2D;
223
texture.target = GL_TEXTURE_2D;
224
texture.active = true;
225
glGenTextures(1, &texture.tex_id);
226
texture_owner.initialize_rid(default_gl_textures[DEFAULT_GL_TEXTURE_DEPTH], texture);
227
228
glBindTexture(GL_TEXTURE_2D, texture.tex_id);
229
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 4, 4, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, pixel_data);
230
GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, 4 * 4 * 2, "Default depth texture");
231
texture.gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
232
}
233
}
234
235
glBindTexture(GL_TEXTURE_2D, 0);
236
237
{ // Atlas Texture initialize.
238
uint8_t pixel_data[4 * 4 * 4];
239
for (int i = 0; i < 16; i++) {
240
pixel_data[i * 4 + 0] = 0;
241
pixel_data[i * 4 + 1] = 0;
242
pixel_data[i * 4 + 2] = 0;
243
pixel_data[i * 4 + 3] = 255;
244
}
245
246
glGenTextures(1, &texture_atlas.texture);
247
glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);
248
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_data);
249
GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, 4 * 4 * 4, "Texture atlas (Default)");
250
}
251
252
glBindTexture(GL_TEXTURE_2D, 0);
253
254
{
255
sdf_shader.shader.initialize();
256
sdf_shader.shader_version = sdf_shader.shader.version_create();
257
}
258
259
// Initialize texture placeholder data for the `texture_*_placeholder_initialize()` methods.
260
261
constexpr int placeholder_size = 4;
262
texture_2d_placeholder = Image::create_empty(placeholder_size, placeholder_size, false, Image::FORMAT_RGBA8);
263
// Draw a magenta/black checkerboard pattern.
264
for (int i = 0; i < placeholder_size * placeholder_size; i++) {
265
const int x = i % placeholder_size;
266
const int y = i / placeholder_size;
267
texture_2d_placeholder->set_pixel(x, y, (x + y) % 2 == 0 ? Color(1, 0, 1) : Color(0, 0, 0));
268
}
269
270
texture_2d_array_placeholder.push_back(texture_2d_placeholder);
271
272
for (int i = 0; i < 6; i++) {
273
cubemap_placeholder.push_back(texture_2d_placeholder);
274
}
275
276
Ref<Image> texture_2d_placeholder_rotated;
277
texture_2d_placeholder_rotated.instantiate();
278
texture_2d_placeholder_rotated->copy_from(texture_2d_placeholder);
279
texture_2d_placeholder_rotated->rotate_90(CLOCKWISE);
280
for (int i = 0; i < 4; i++) {
281
// Alternate checkerboard pattern on odd layers (by using a copy that is rotated 90 degrees).
282
texture_3d_placeholder.push_back(i % 2 == 0 ? texture_2d_placeholder : texture_2d_placeholder_rotated);
283
}
284
285
#ifdef GL_API_ENABLED
286
if (RasterizerGLES3::is_gles_over_gl()) {
287
glEnable(GL_PROGRAM_POINT_SIZE);
288
}
289
#endif // GL_API_ENABLED
290
}
291
292
TextureStorage::~TextureStorage() {
293
singleton = nullptr;
294
for (int i = 0; i < DEFAULT_GL_TEXTURE_MAX; i++) {
295
texture_free(default_gl_textures[i]);
296
}
297
if (texture_atlas.texture != 0) {
298
GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
299
}
300
texture_atlas.texture = 0;
301
glDeleteFramebuffers(1, &texture_atlas.framebuffer);
302
texture_atlas.framebuffer = 0;
303
sdf_shader.shader.version_free(sdf_shader.shader_version);
304
}
305
306
// Has to be a separate call from TextureStorage initialization due to interacting with MaterialStorage
307
void TextureStorage::_tex_blit_shader_initialize() {
308
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
309
310
{
311
String global_defines;
312
global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
313
material_storage->shaders.tex_blit_shader.initialize(global_defines, 1);
314
}
315
316
{
317
// default material and shader for Texture Blit shader
318
tex_blit_shader.default_shader = material_storage->shader_allocate();
319
material_storage->shader_initialize(tex_blit_shader.default_shader);
320
material_storage->shader_set_code(tex_blit_shader.default_shader, R"(
321
// Default Texture Blit shader.
322
323
shader_type texture_blit;
324
render_mode blend_mix;
325
326
uniform sampler2D source_texture0 : hint_blit_source0;
327
uniform sampler2D source_texture1 : hint_blit_source1;
328
uniform sampler2D source_texture2 : hint_blit_source2;
329
uniform sampler2D source_texture3 : hint_blit_source3;
330
331
void blit() {
332
// Copies from each whole source texture to a rect on each output texture.
333
COLOR0 = texture(source_texture0, UV) * MODULATE;
334
COLOR1 = texture(source_texture1, UV) * MODULATE;
335
COLOR2 = texture(source_texture2, UV) * MODULATE;
336
COLOR3 = texture(source_texture3, UV) * MODULATE;
337
}
338
)");
339
tex_blit_shader.default_material = material_storage->material_allocate();
340
material_storage->material_initialize(tex_blit_shader.default_material);
341
material_storage->material_set_shader(tex_blit_shader.default_material, tex_blit_shader.default_shader);
342
}
343
344
{
345
// Set up Frame & Vertex Buffers for TextureBlit Shaders
346
// Just a 1x1 Quad to draw
347
glGenFramebuffers(1, &tex_blit_fbo);
348
349
glGenBuffers(1, &tex_blit_quad);
350
glBindBuffer(GL_ARRAY_BUFFER, tex_blit_quad);
351
352
const float qv[12] = {
353
-1.0f,
354
-1.0f,
355
1.0f,
356
-1.0f,
357
1.0f,
358
1.0f,
359
-1.0f,
360
-1.0f,
361
1.0f,
362
1.0f,
363
-1.0f,
364
1.0f,
365
};
366
367
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 12, qv, GL_STATIC_DRAW);
368
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
369
370
glGenVertexArrays(1, &tex_blit_quad_array);
371
glBindVertexArray(tex_blit_quad_array);
372
glBindBuffer(GL_ARRAY_BUFFER, tex_blit_quad);
373
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);
374
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
375
glBindVertexArray(0);
376
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
377
}
378
379
tex_blit_shader.initialized = true;
380
}
381
382
// Has to be a separate call from TextureStorage destruction due to interacting with Material Storage
383
void TextureStorage::_tex_blit_shader_free() {
384
if (tex_blit_shader.initialized) {
385
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
386
glDeleteFramebuffers(1, &tex_blit_fbo);
387
glDeleteBuffers(1, &tex_blit_quad);
388
glDeleteVertexArrays(1, &tex_blit_quad_array);
389
material_storage->material_free(tex_blit_shader.default_material);
390
material_storage->shader_free(tex_blit_shader.default_shader);
391
}
392
}
393
394
/* Canvas Texture API */
395
396
RID TextureStorage::canvas_texture_allocate() {
397
return canvas_texture_owner.allocate_rid();
398
}
399
400
void TextureStorage::canvas_texture_initialize(RID p_rid) {
401
canvas_texture_owner.initialize_rid(p_rid);
402
}
403
404
void TextureStorage::canvas_texture_free(RID p_rid) {
405
canvas_texture_owner.free(p_rid);
406
}
407
408
void TextureStorage::canvas_texture_set_channel(RID p_canvas_texture, RS::CanvasTextureChannel p_channel, RID p_texture) {
409
CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
410
ERR_FAIL_NULL(ct);
411
412
switch (p_channel) {
413
case RS::CANVAS_TEXTURE_CHANNEL_DIFFUSE: {
414
ct->diffuse = p_texture;
415
} break;
416
case RS::CANVAS_TEXTURE_CHANNEL_NORMAL: {
417
ct->normal_map = p_texture;
418
} break;
419
case RS::CANVAS_TEXTURE_CHANNEL_SPECULAR: {
420
ct->specular = p_texture;
421
} break;
422
}
423
}
424
425
void TextureStorage::canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_specular_color, float p_shininess) {
426
CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
427
ERR_FAIL_NULL(ct);
428
429
ct->specular_color.r = p_specular_color.r;
430
ct->specular_color.g = p_specular_color.g;
431
ct->specular_color.b = p_specular_color.b;
432
ct->specular_color.a = p_shininess;
433
}
434
435
void TextureStorage::canvas_texture_set_texture_filter(RID p_canvas_texture, RS::CanvasItemTextureFilter p_filter) {
436
CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
437
ERR_FAIL_NULL(ct);
438
439
ct->texture_filter = p_filter;
440
}
441
442
void TextureStorage::canvas_texture_set_texture_repeat(RID p_canvas_texture, RS::CanvasItemTextureRepeat p_repeat) {
443
CanvasTexture *ct = canvas_texture_owner.get_or_null(p_canvas_texture);
444
ERR_FAIL_NULL(ct);
445
446
ct->texture_repeat = p_repeat;
447
}
448
449
/* Texture API */
450
451
static 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) {
452
Config *config = Config::get_singleton();
453
454
switch (p_format) {
455
case Image::FORMAT_L8: {
456
if (RasterizerGLES3::is_gles_over_gl()) {
457
r_gl_internal_format = GL_R8;
458
r_gl_format = GL_RED;
459
r_gl_type = GL_UNSIGNED_BYTE;
460
} else {
461
r_gl_internal_format = GL_LUMINANCE;
462
r_gl_format = GL_LUMINANCE;
463
r_gl_type = GL_UNSIGNED_BYTE;
464
}
465
} break;
466
case Image::FORMAT_LA8: {
467
if (RasterizerGLES3::is_gles_over_gl()) {
468
r_gl_internal_format = GL_RG8;
469
r_gl_format = GL_RG;
470
r_gl_type = GL_UNSIGNED_BYTE;
471
} else {
472
r_gl_internal_format = GL_LUMINANCE_ALPHA;
473
r_gl_format = GL_LUMINANCE_ALPHA;
474
r_gl_type = GL_UNSIGNED_BYTE;
475
}
476
} break;
477
case Image::FORMAT_R8: {
478
r_gl_internal_format = GL_R8;
479
r_gl_format = GL_RED;
480
r_gl_type = GL_UNSIGNED_BYTE;
481
} break;
482
case Image::FORMAT_RG8: {
483
r_gl_internal_format = GL_RG8;
484
r_gl_format = GL_RG;
485
r_gl_type = GL_UNSIGNED_BYTE;
486
} break;
487
case Image::FORMAT_RGB8: {
488
r_gl_internal_format = GL_RGB8;
489
r_gl_format = GL_RGB;
490
r_gl_type = GL_UNSIGNED_BYTE;
491
} break;
492
case Image::FORMAT_RGBA8: {
493
r_gl_internal_format = GL_RGBA8;
494
r_gl_format = GL_RGBA;
495
r_gl_type = GL_UNSIGNED_BYTE;
496
} break;
497
case Image::FORMAT_RGBA4444: {
498
r_gl_internal_format = GL_RGBA4;
499
r_gl_format = GL_RGBA;
500
r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4;
501
} break;
502
case Image::FORMAT_RGB565: {
503
r_gl_internal_format = GL_RGB565;
504
r_gl_format = GL_RGB;
505
r_gl_type = GL_UNSIGNED_SHORT_5_6_5;
506
} break;
507
case Image::FORMAT_RF: {
508
if (config->float_texture_linear_supported) {
509
r_gl_internal_format = GL_R32F;
510
r_gl_format = GL_RED;
511
r_gl_type = GL_FLOAT;
512
} else {
513
if (p_image.is_valid()) {
514
p_image->convert(Image::FORMAT_RH);
515
}
516
r_real_format = Image::FORMAT_RH;
517
r_gl_internal_format = GL_R16F;
518
r_gl_format = GL_RED;
519
r_gl_type = GL_HALF_FLOAT;
520
}
521
} break;
522
case Image::FORMAT_RGF: {
523
if (config->float_texture_linear_supported) {
524
r_gl_internal_format = GL_RG32F;
525
r_gl_format = GL_RG;
526
r_gl_type = GL_FLOAT;
527
} else {
528
if (p_image.is_valid()) {
529
p_image->convert(Image::FORMAT_RGH);
530
}
531
r_real_format = Image::FORMAT_RGH;
532
r_gl_internal_format = GL_RG16F;
533
r_gl_format = GL_RG;
534
r_gl_type = GL_HALF_FLOAT;
535
}
536
} break;
537
case Image::FORMAT_RGBF: {
538
if (config->float_texture_linear_supported) {
539
r_gl_internal_format = GL_RGB32F;
540
r_gl_format = GL_RGB;
541
r_gl_type = GL_FLOAT;
542
} else {
543
if (p_image.is_valid()) {
544
p_image->convert(Image::FORMAT_RGBH);
545
}
546
r_real_format = Image::FORMAT_RGBH;
547
r_gl_internal_format = GL_RGB16F;
548
r_gl_format = GL_RGB;
549
r_gl_type = GL_HALF_FLOAT;
550
}
551
} break;
552
case Image::FORMAT_RGBAF: {
553
if (config->float_texture_linear_supported) {
554
r_gl_internal_format = GL_RGBA32F;
555
r_gl_format = GL_RGBA;
556
r_gl_type = GL_FLOAT;
557
} else {
558
if (p_image.is_valid()) {
559
p_image->convert(Image::FORMAT_RGBAH);
560
}
561
r_real_format = Image::FORMAT_RGBAH;
562
r_gl_internal_format = GL_RGBA16F;
563
r_gl_format = GL_RGBA;
564
r_gl_type = GL_HALF_FLOAT;
565
}
566
} break;
567
case Image::FORMAT_RH: {
568
r_gl_internal_format = GL_R16F;
569
r_gl_format = GL_RED;
570
r_gl_type = GL_HALF_FLOAT;
571
} break;
572
case Image::FORMAT_RGH: {
573
r_gl_internal_format = GL_RG16F;
574
r_gl_format = GL_RG;
575
r_gl_type = GL_HALF_FLOAT;
576
} break;
577
case Image::FORMAT_RGBH: {
578
r_gl_internal_format = GL_RGB16F;
579
r_gl_format = GL_RGB;
580
r_gl_type = GL_HALF_FLOAT;
581
} break;
582
case Image::FORMAT_RGBAH: {
583
r_gl_internal_format = GL_RGBA16F;
584
r_gl_format = GL_RGBA;
585
r_gl_type = GL_HALF_FLOAT;
586
} break;
587
case Image::FORMAT_RGBE9995: {
588
r_gl_internal_format = GL_RGB9_E5;
589
r_gl_format = GL_RGB;
590
r_gl_type = GL_UNSIGNED_INT_5_9_9_9_REV;
591
} break;
592
case Image::FORMAT_R16: {
593
if (config->unorm16_texture_supported) {
594
r_gl_internal_format = _EXT_R16;
595
r_gl_format = GL_RED;
596
r_gl_type = GL_UNSIGNED_SHORT;
597
} else {
598
if (config->float_texture_linear_supported) {
599
if (p_image.is_valid()) {
600
p_image->convert(Image::FORMAT_RF);
601
}
602
r_real_format = Image::FORMAT_RF;
603
r_gl_internal_format = GL_R32F;
604
r_gl_format = GL_RED;
605
r_gl_type = GL_FLOAT;
606
} else {
607
if (p_image.is_valid()) {
608
p_image->convert(Image::FORMAT_RH);
609
}
610
r_real_format = Image::FORMAT_RH;
611
r_gl_internal_format = GL_R16F;
612
r_gl_format = GL_RED;
613
r_gl_type = GL_HALF_FLOAT;
614
}
615
}
616
} break;
617
case Image::FORMAT_RG16: {
618
if (config->unorm16_texture_supported) {
619
r_gl_internal_format = _EXT_RG16;
620
r_gl_format = GL_RG;
621
r_gl_type = GL_UNSIGNED_SHORT;
622
} else {
623
if (config->float_texture_linear_supported) {
624
if (p_image.is_valid()) {
625
p_image->convert(Image::FORMAT_RGF);
626
}
627
r_real_format = Image::FORMAT_RGF;
628
r_gl_internal_format = GL_RG32F;
629
r_gl_format = GL_RG;
630
r_gl_type = GL_FLOAT;
631
} else {
632
if (p_image.is_valid()) {
633
p_image->convert(Image::FORMAT_RGH);
634
}
635
r_real_format = Image::FORMAT_RGH;
636
r_gl_internal_format = GL_RG16F;
637
r_gl_format = GL_RG;
638
r_gl_type = GL_HALF_FLOAT;
639
}
640
}
641
} break;
642
case Image::FORMAT_RGB16: {
643
if (config->unorm16_texture_supported) {
644
r_gl_internal_format = _EXT_RGB16;
645
r_gl_format = GL_RGB;
646
r_gl_type = GL_UNSIGNED_SHORT;
647
} else {
648
if (config->float_texture_linear_supported) {
649
if (p_image.is_valid()) {
650
p_image->convert(Image::FORMAT_RGBF);
651
}
652
r_real_format = Image::FORMAT_RGBF;
653
r_gl_internal_format = GL_RGB32F;
654
r_gl_format = GL_RGB;
655
r_gl_type = GL_FLOAT;
656
} else {
657
if (p_image.is_valid()) {
658
p_image->convert(Image::FORMAT_RGBH);
659
}
660
r_real_format = Image::FORMAT_RGBH;
661
r_gl_internal_format = GL_RGB16F;
662
r_gl_format = GL_RGB;
663
r_gl_type = GL_HALF_FLOAT;
664
}
665
}
666
} break;
667
case Image::FORMAT_RGBA16: {
668
if (config->unorm16_texture_supported) {
669
r_gl_internal_format = _EXT_RGBA16;
670
r_gl_format = GL_RGBA;
671
r_gl_type = GL_UNSIGNED_SHORT;
672
} else {
673
if (config->float_texture_linear_supported) {
674
if (p_image.is_valid()) {
675
p_image->convert(Image::FORMAT_RGBAF);
676
}
677
r_real_format = Image::FORMAT_RGBAF;
678
r_gl_internal_format = GL_RGBA32F;
679
r_gl_format = GL_RGBA;
680
r_gl_type = GL_FLOAT;
681
} else {
682
if (p_image.is_valid()) {
683
p_image->convert(Image::FORMAT_RGH);
684
}
685
r_real_format = Image::FORMAT_RGH;
686
r_gl_internal_format = GL_RGBA16F;
687
r_gl_format = GL_RGBA;
688
r_gl_type = GL_HALF_FLOAT;
689
}
690
}
691
} break;
692
case Image::FORMAT_R16I: {
693
r_gl_internal_format = GL_R16UI;
694
r_gl_format = GL_RED_INTEGER;
695
r_gl_type = GL_UNSIGNED_SHORT;
696
} break;
697
case Image::FORMAT_RG16I: {
698
r_gl_internal_format = GL_RG16UI;
699
r_gl_format = GL_RG_INTEGER;
700
r_gl_type = GL_UNSIGNED_SHORT;
701
} break;
702
case Image::FORMAT_RGB16I: {
703
r_gl_internal_format = GL_RGB16UI;
704
r_gl_format = GL_RGB_INTEGER;
705
r_gl_type = GL_UNSIGNED_SHORT;
706
} break;
707
case Image::FORMAT_RGBA16I: {
708
r_gl_internal_format = GL_RGBA16UI;
709
r_gl_format = GL_RGBA_INTEGER;
710
r_gl_type = GL_UNSIGNED_SHORT;
711
} break;
712
default: {
713
return ERR_UNAVAILABLE;
714
}
715
}
716
717
return OK;
718
}
719
720
Ref<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 {
721
Config *config = Config::get_singleton();
722
r_gl_format = 0;
723
Ref<Image> image = p_image;
724
r_compressed = false;
725
r_real_format = p_format;
726
727
if (!Image::is_format_compressed(p_format)) {
728
Error err = _get_gl_uncompressed_format(p_image, p_format, r_real_format, r_gl_format, r_gl_internal_format, r_gl_type);
729
ERR_FAIL_COND_V_MSG(err != OK, Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", p_format));
730
731
if (p_format != r_real_format) {
732
WARN_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)));
733
}
734
735
return p_image;
736
}
737
738
// For compressed images, some formats may not be supported by the current device and will require decompression.
739
bool need_decompress = false;
740
bool decompress_ra_to_rg = false;
741
742
switch (p_format) {
743
case Image::FORMAT_DXT1: {
744
if (config->s3tc_supported) {
745
r_gl_internal_format = _EXT_COMPRESSED_RGB_S3TC_DXT1_EXT;
746
r_gl_format = GL_RGB;
747
r_gl_type = GL_UNSIGNED_BYTE;
748
r_compressed = true;
749
} else {
750
need_decompress = true;
751
}
752
} break;
753
case Image::FORMAT_DXT3: {
754
if (config->s3tc_supported) {
755
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
756
r_gl_format = GL_RGBA;
757
r_gl_type = GL_UNSIGNED_BYTE;
758
r_compressed = true;
759
} else {
760
need_decompress = true;
761
}
762
} break;
763
case Image::FORMAT_DXT5: {
764
if (config->s3tc_supported) {
765
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
766
r_gl_format = GL_RGBA;
767
r_gl_type = GL_UNSIGNED_BYTE;
768
r_compressed = true;
769
} else {
770
need_decompress = true;
771
}
772
} break;
773
case Image::FORMAT_RGTC_R: {
774
if (config->rgtc_supported) {
775
r_gl_internal_format = _EXT_COMPRESSED_RED_RGTC1_EXT;
776
r_gl_format = GL_RGBA;
777
r_gl_type = GL_UNSIGNED_BYTE;
778
r_compressed = true;
779
} else {
780
need_decompress = true;
781
}
782
} break;
783
case Image::FORMAT_RGTC_RG: {
784
if (config->rgtc_supported) {
785
r_gl_internal_format = _EXT_COMPRESSED_RED_GREEN_RGTC2_EXT;
786
r_gl_format = GL_RGBA;
787
r_gl_type = GL_UNSIGNED_BYTE;
788
r_compressed = true;
789
} else {
790
need_decompress = true;
791
}
792
} break;
793
case Image::FORMAT_BPTC_RGBA: {
794
if (config->bptc_supported) {
795
r_gl_internal_format = _EXT_COMPRESSED_RGBA_BPTC_UNORM;
796
r_gl_format = GL_RGBA;
797
r_gl_type = GL_UNSIGNED_BYTE;
798
r_compressed = true;
799
} else {
800
need_decompress = true;
801
}
802
} break;
803
case Image::FORMAT_BPTC_RGBF: {
804
if (config->bptc_supported) {
805
r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
806
r_gl_format = GL_RGB;
807
r_gl_type = GL_FLOAT;
808
r_compressed = true;
809
} else {
810
need_decompress = true;
811
}
812
} break;
813
case Image::FORMAT_BPTC_RGBFU: {
814
if (config->bptc_supported) {
815
r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
816
r_gl_format = GL_RGB;
817
r_gl_type = GL_FLOAT;
818
r_compressed = true;
819
} else {
820
need_decompress = true;
821
}
822
} break;
823
case Image::FORMAT_ETC2_R11: {
824
if (config->etc2_supported) {
825
r_gl_internal_format = _EXT_COMPRESSED_R11_EAC;
826
r_gl_format = GL_RED;
827
r_gl_type = GL_UNSIGNED_BYTE;
828
r_compressed = true;
829
} else {
830
need_decompress = true;
831
}
832
} break;
833
case Image::FORMAT_ETC2_R11S: {
834
if (config->etc2_supported) {
835
r_gl_internal_format = _EXT_COMPRESSED_SIGNED_R11_EAC;
836
r_gl_format = GL_RED;
837
r_gl_type = GL_UNSIGNED_BYTE;
838
r_compressed = true;
839
} else {
840
need_decompress = true;
841
}
842
} break;
843
case Image::FORMAT_ETC2_RG11: {
844
if (config->etc2_supported) {
845
r_gl_internal_format = _EXT_COMPRESSED_RG11_EAC;
846
r_gl_format = GL_RG;
847
r_gl_type = GL_UNSIGNED_BYTE;
848
r_compressed = true;
849
} else {
850
need_decompress = true;
851
}
852
} break;
853
case Image::FORMAT_ETC2_RG11S: {
854
if (config->etc2_supported) {
855
r_gl_internal_format = _EXT_COMPRESSED_SIGNED_RG11_EAC;
856
r_gl_format = GL_RG;
857
r_gl_type = GL_UNSIGNED_BYTE;
858
r_compressed = true;
859
} else {
860
need_decompress = true;
861
}
862
} break;
863
case Image::FORMAT_ETC:
864
case Image::FORMAT_ETC2_RGB8: {
865
if (config->etc2_supported) {
866
r_gl_internal_format = _EXT_COMPRESSED_RGB8_ETC2;
867
r_gl_format = GL_RGB;
868
r_gl_type = GL_UNSIGNED_BYTE;
869
r_compressed = true;
870
} else {
871
need_decompress = true;
872
}
873
} break;
874
case Image::FORMAT_ETC2_RGBA8: {
875
if (config->etc2_supported) {
876
r_gl_internal_format = _EXT_COMPRESSED_RGBA8_ETC2_EAC;
877
r_gl_format = GL_RGBA;
878
r_gl_type = GL_UNSIGNED_BYTE;
879
r_compressed = true;
880
} else {
881
need_decompress = true;
882
}
883
} break;
884
case Image::FORMAT_ETC2_RGB8A1: {
885
if (config->etc2_supported) {
886
r_gl_internal_format = _EXT_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
887
r_gl_format = GL_RGBA;
888
r_gl_type = GL_UNSIGNED_BYTE;
889
r_compressed = true;
890
} else {
891
need_decompress = true;
892
}
893
} break;
894
case Image::FORMAT_ETC2_RA_AS_RG: {
895
#ifndef WEB_ENABLED
896
if (config->etc2_supported) {
897
r_gl_internal_format = _EXT_COMPRESSED_RGBA8_ETC2_EAC;
898
r_gl_format = GL_RGBA;
899
r_gl_type = GL_UNSIGNED_BYTE;
900
r_compressed = true;
901
} else
902
#endif
903
{
904
need_decompress = true;
905
}
906
decompress_ra_to_rg = true;
907
} break;
908
case Image::FORMAT_DXT5_RA_AS_RG: {
909
#ifndef WEB_ENABLED
910
if (config->s3tc_supported) {
911
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
912
r_gl_format = GL_RGBA;
913
r_gl_type = GL_UNSIGNED_BYTE;
914
r_compressed = true;
915
} else
916
#endif
917
{
918
need_decompress = true;
919
}
920
decompress_ra_to_rg = true;
921
} break;
922
case Image::FORMAT_ASTC_4x4: {
923
if (config->astc_supported) {
924
r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;
925
r_gl_format = GL_RGBA;
926
r_gl_type = GL_UNSIGNED_BYTE;
927
r_compressed = true;
928
} else {
929
need_decompress = true;
930
}
931
} break;
932
case Image::FORMAT_ASTC_4x4_HDR: {
933
if (config->astc_hdr_supported) {
934
r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_4x4_KHR;
935
r_gl_format = GL_RGBA;
936
r_gl_type = GL_UNSIGNED_BYTE;
937
r_compressed = true;
938
} else {
939
need_decompress = true;
940
}
941
} break;
942
case Image::FORMAT_ASTC_8x8: {
943
if (config->astc_supported) {
944
r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;
945
r_gl_format = GL_RGBA;
946
r_gl_type = GL_UNSIGNED_BYTE;
947
r_compressed = true;
948
} else {
949
need_decompress = true;
950
}
951
} break;
952
case Image::FORMAT_ASTC_8x8_HDR: {
953
if (config->astc_hdr_supported) {
954
r_gl_internal_format = _EXT_COMPRESSED_RGBA_ASTC_8x8_KHR;
955
r_gl_format = GL_RGBA;
956
r_gl_type = GL_UNSIGNED_BYTE;
957
r_compressed = true;
958
} else {
959
need_decompress = true;
960
}
961
} break;
962
default: {
963
ERR_FAIL_V_MSG(Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", p_format));
964
}
965
}
966
967
if (need_decompress || p_force_decompress) {
968
if (image.is_valid()) {
969
image = image->duplicate();
970
image->decompress();
971
ERR_FAIL_COND_V(image->is_compressed(), image);
972
973
if (decompress_ra_to_rg) {
974
image->convert_ra_rgba8_to_rg();
975
image->convert(Image::FORMAT_RG8);
976
}
977
978
Error err = _get_gl_uncompressed_format(image, image->get_format(), r_real_format, r_gl_format, r_gl_internal_format, r_gl_type);
979
ERR_FAIL_COND_V_MSG(err != OK, Ref<Image>(), vformat("The image format %d is not supported by the Compatibility renderer.", image->get_format()));
980
981
r_real_format = image->get_format();
982
r_compressed = false;
983
984
if (p_format != image->get_format()) {
985
WARN_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())));
986
}
987
}
988
989
return image;
990
}
991
992
return p_image;
993
}
994
995
RID TextureStorage::texture_allocate() {
996
return texture_owner.allocate_rid();
997
}
998
999
void TextureStorage::texture_free(RID p_texture) {
1000
Texture *t = texture_owner.get_or_null(p_texture);
1001
ERR_FAIL_NULL(t);
1002
ERR_FAIL_COND(t->is_render_target);
1003
1004
if (t->canvas_texture) {
1005
memdelete(t->canvas_texture);
1006
}
1007
1008
bool must_free_data = false;
1009
if (t->is_proxy) {
1010
if (t->proxy_to.is_valid()) {
1011
Texture *proxy_to = texture_owner.get_or_null(t->proxy_to);
1012
if (proxy_to) {
1013
proxy_to->proxies.erase(p_texture);
1014
}
1015
}
1016
} else {
1017
must_free_data = t->tex_id != 0 && !t->is_from_native_handle;
1018
}
1019
if (must_free_data) {
1020
GLES3::Utilities::get_singleton()->texture_free_data(t->tex_id);
1021
t->tex_id = 0;
1022
}
1023
1024
texture_atlas_remove_texture(p_texture);
1025
1026
for (uint32_t i = 0; i < t->proxies.size(); i++) {
1027
Texture *p = texture_owner.get_or_null(t->proxies[i]);
1028
ERR_CONTINUE(!p);
1029
p->proxy_to = RID();
1030
p->tex_id = 0;
1031
}
1032
1033
texture_owner.free(p_texture);
1034
}
1035
1036
void TextureStorage::texture_2d_initialize(RID p_texture, const Ref<Image> &p_image) {
1037
ERR_FAIL_COND(p_image.is_null());
1038
1039
Texture texture;
1040
texture.width = p_image->get_width();
1041
texture.height = p_image->get_height();
1042
texture.alloc_width = texture.width;
1043
texture.alloc_height = texture.height;
1044
texture.mipmaps = p_image->get_mipmap_count() + 1;
1045
texture.format = p_image->get_format();
1046
texture.type = Texture::TYPE_2D;
1047
texture.target = GL_TEXTURE_2D;
1048
_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);
1049
texture.total_data_size = p_image->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps);
1050
texture.active = true;
1051
glGenTextures(1, &texture.tex_id);
1052
GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 2D");
1053
texture_owner.initialize_rid(p_texture, texture);
1054
texture_set_data(p_texture, p_image);
1055
}
1056
1057
void TextureStorage::texture_external_initialize(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {
1058
Texture texture;
1059
texture.active = true;
1060
texture.alloc_width = texture.width = p_width;
1061
texture.alloc_height = texture.height = p_height;
1062
texture.real_format = texture.format = Image::FORMAT_RGB8;
1063
texture.type = Texture::TYPE_2D;
1064
1065
if (GLES3::Config::get_singleton()->external_texture_supported) {
1066
texture.target = _GL_TEXTURE_EXTERNAL_OES;
1067
} else {
1068
texture.target = GL_TEXTURE_2D;
1069
}
1070
1071
glGenTextures(1, &texture.tex_id);
1072
glBindTexture(texture.target, texture.tex_id);
1073
1074
#ifdef ANDROID_ENABLED
1075
if (texture.target == _GL_TEXTURE_EXTERNAL_OES) {
1076
if (p_external_buffer) {
1077
GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));
1078
}
1079
texture.total_data_size = 0;
1080
} else
1081
#endif
1082
{
1083
// If external textures aren't supported, allocate an empty 1x1 texture.
1084
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1085
texture.total_data_size = 3;
1086
}
1087
1088
glTexParameteri(texture.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1089
glTexParameteri(texture.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1090
glTexParameteri(texture.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1091
glTexParameteri(texture.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1092
1093
GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture External");
1094
texture_owner.initialize_rid(p_texture, texture);
1095
1096
glBindTexture(texture.target, 0);
1097
}
1098
1099
void TextureStorage::texture_2d_layered_initialize(RID p_texture, const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
1100
ERR_FAIL_COND(p_layers.is_empty());
1101
1102
ERR_FAIL_COND(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6);
1103
ERR_FAIL_COND_MSG(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY, "Cubemap Arrays are not supported in the Compatibility renderer.");
1104
1105
const Ref<Image> &image = p_layers[0];
1106
{
1107
int valid_width = 0;
1108
int valid_height = 0;
1109
bool valid_mipmaps = false;
1110
Image::Format valid_format = Image::FORMAT_MAX;
1111
1112
for (int i = 0; i < p_layers.size(); i++) {
1113
ERR_FAIL_COND(p_layers[i]->is_empty());
1114
1115
if (i == 0) {
1116
valid_width = p_layers[i]->get_width();
1117
valid_height = p_layers[i]->get_height();
1118
valid_format = p_layers[i]->get_format();
1119
valid_mipmaps = p_layers[i]->has_mipmaps();
1120
} else {
1121
ERR_FAIL_COND(p_layers[i]->get_width() != valid_width);
1122
ERR_FAIL_COND(p_layers[i]->get_height() != valid_height);
1123
ERR_FAIL_COND(p_layers[i]->get_format() != valid_format);
1124
ERR_FAIL_COND(p_layers[i]->has_mipmaps() != valid_mipmaps);
1125
}
1126
}
1127
}
1128
1129
Texture texture;
1130
texture.width = image->get_width();
1131
texture.height = image->get_height();
1132
texture.alloc_width = texture.width;
1133
texture.alloc_height = texture.height;
1134
texture.mipmaps = image->get_mipmap_count() + 1;
1135
texture.format = image->get_format();
1136
texture.type = Texture::TYPE_LAYERED;
1137
texture.layered_type = p_layered_type;
1138
texture.target = p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D_ARRAY;
1139
texture.layers = p_layers.size();
1140
_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);
1141
texture.total_data_size = p_layers[0]->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps) * texture.layers;
1142
texture.active = true;
1143
glGenTextures(1, &texture.tex_id);
1144
GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture Layered");
1145
texture_owner.initialize_rid(p_texture, texture);
1146
for (int i = 0; i < p_layers.size(); i++) {
1147
_texture_set_data(p_texture, p_layers[i], i, i == 0);
1148
}
1149
}
1150
1151
void 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) {
1152
ERR_FAIL_COND(p_data.is_empty());
1153
1154
Image::Image3DValidateError verr = Image::validate_3d_image(p_format, p_width, p_height, p_depth, p_mipmaps, p_data);
1155
ERR_FAIL_COND_MSG(verr != Image::VALIDATE_3D_OK, Image::get_3d_image_validation_error_text(verr));
1156
1157
Ref<Image> image = p_data[0];
1158
int mipmap_count = 0;
1159
{
1160
Size2i prev_size;
1161
for (int i = 0; i < p_data.size(); i++) {
1162
Size2i img_size(p_data[i]->get_width(), p_data[i]->get_height());
1163
if (img_size != prev_size) {
1164
mipmap_count++;
1165
}
1166
prev_size = img_size;
1167
}
1168
}
1169
1170
Texture texture;
1171
texture.width = p_width;
1172
texture.height = p_height;
1173
texture.depth = p_depth;
1174
texture.alloc_width = texture.width;
1175
texture.alloc_height = texture.height;
1176
texture.mipmaps = mipmap_count;
1177
texture.format = image->get_format();
1178
texture.type = Texture::TYPE_3D;
1179
texture.target = GL_TEXTURE_3D;
1180
_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);
1181
texture.total_data_size = p_data[0]->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps) * texture.depth;
1182
texture.active = true;
1183
glGenTextures(1, &texture.tex_id);
1184
GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 3D");
1185
texture_owner.initialize_rid(p_texture, texture);
1186
_texture_set_3d_data(p_texture, p_data, true);
1187
}
1188
1189
// Called internally when texture_proxy_create(p_base) is called.
1190
// Note: p_base is the root and p_texture is the proxy.
1191
void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
1192
Texture *texture = texture_owner.get_or_null(p_base);
1193
ERR_FAIL_NULL(texture);
1194
Texture proxy_tex;
1195
proxy_tex.copy_from(*texture);
1196
proxy_tex.proxy_to = p_base;
1197
proxy_tex.is_render_target = false;
1198
proxy_tex.is_proxy = true;
1199
proxy_tex.proxies.clear();
1200
texture->proxies.push_back(p_texture);
1201
texture_owner.initialize_rid(p_texture, proxy_tex);
1202
}
1203
1204
void 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) {
1205
// Behaves identically to Texture_2D_Initialize by generating a white image based on parameters.
1206
1207
// GUARDRAIL: Bad Widths/Heights
1208
ERR_FAIL_COND_MSG(p_width <= 0 || p_height <= 0, "Drawable Texture Width or Height cannot be less than 1.");
1209
ERR_FAIL_COND_MSG(p_width >= 16384 || p_height >= 16384, "Drawable Texture Width or Height cannot be greater than 16383.");
1210
1211
Image::Format format;
1212
switch (p_format) {
1213
case RS::TEXTURE_DRAWABLE_FORMAT_RGBA8:
1214
format = Image::FORMAT_RGBA8;
1215
break;
1216
case RS::TEXTURE_DRAWABLE_FORMAT_RGBA8_SRGB:
1217
format = Image::FORMAT_RGBA8;
1218
break;
1219
case RS::TEXTURE_DRAWABLE_FORMAT_RGBAH:
1220
format = Image::FORMAT_RGBAH;
1221
break;
1222
case RS::TEXTURE_DRAWABLE_FORMAT_RGBAF:
1223
format = Image::FORMAT_RGBAF;
1224
break;
1225
default:
1226
format = Image::FORMAT_RGBA8;
1227
}
1228
1229
Ref<Image> image = Image::create_empty(p_width, p_height, p_with_mipmaps, format);
1230
image->fill(p_color);
1231
Texture texture;
1232
texture.width = image->get_width();
1233
texture.height = image->get_height();
1234
texture.alloc_width = texture.width;
1235
texture.alloc_height = texture.height;
1236
texture.mipmaps = image->get_mipmap_count() + 1;
1237
texture.format = image->get_format();
1238
texture.type = Texture::TYPE_2D;
1239
texture.target = GL_TEXTURE_2D;
1240
_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);
1241
texture.total_data_size = image->get_image_data_size(texture.width, texture.height, texture.format, texture.mipmaps);
1242
texture.active = true;
1243
glGenTextures(1, &texture.tex_id);
1244
GLES3::Utilities::get_singleton()->texture_allocated_data(texture.tex_id, texture.total_data_size, "Texture 2D");
1245
texture_owner.initialize_rid(p_texture, texture);
1246
texture_set_data(p_texture, image);
1247
}
1248
1249
RID 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) {
1250
Texture texture;
1251
texture.active = true;
1252
texture.is_from_native_handle = true;
1253
1254
switch (p_type) {
1255
case RS::TEXTURE_TYPE_2D: {
1256
texture.type = Texture::TYPE_2D;
1257
texture.target = GL_TEXTURE_2D;
1258
} break;
1259
case RS::TEXTURE_TYPE_3D: {
1260
texture.type = Texture::TYPE_3D;
1261
texture.target = GL_TEXTURE_3D;
1262
} break;
1263
case RS::TEXTURE_TYPE_LAYERED: {
1264
texture.type = Texture::TYPE_LAYERED;
1265
texture.target = GL_TEXTURE_2D_ARRAY;
1266
} break;
1267
}
1268
1269
texture.real_format = texture.format = p_format;
1270
texture.tex_id = p_native_handle;
1271
texture.alloc_width = texture.width = p_width;
1272
texture.alloc_height = texture.height = p_height;
1273
texture.depth = p_depth;
1274
texture.layers = p_layers;
1275
texture.layered_type = p_layered_type;
1276
1277
return texture_owner.make_rid(texture);
1278
}
1279
1280
void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
1281
texture_set_data(p_texture, p_image, p_layer);
1282
1283
Texture *tex = texture_owner.get_or_null(p_texture);
1284
ERR_FAIL_NULL(tex);
1285
GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);
1286
1287
#ifdef TOOLS_ENABLED
1288
tex->image_cache_2d.unref();
1289
#endif
1290
}
1291
1292
void TextureStorage::texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) {
1293
Texture *tex = texture_owner.get_or_null(p_texture);
1294
ERR_FAIL_NULL(tex);
1295
ERR_FAIL_COND(tex->type != Texture::TYPE_3D);
1296
1297
Image::Image3DValidateError verr = Image::validate_3d_image(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps > 1, p_data);
1298
ERR_FAIL_COND_MSG(verr != Image::VALIDATE_3D_OK, Image::get_3d_image_validation_error_text(verr));
1299
1300
_texture_set_3d_data(p_texture, p_data, false);
1301
1302
GLES3::Utilities::get_singleton()->texture_resize_data(tex->tex_id, tex->total_data_size);
1303
}
1304
1305
void TextureStorage::texture_external_update(RID p_texture, int p_width, int p_height, uint64_t p_external_buffer) {
1306
Texture *tex = texture_owner.get_or_null(p_texture);
1307
ERR_FAIL_NULL(tex);
1308
1309
tex->alloc_width = tex->width = p_width;
1310
tex->alloc_height = tex->height = p_height;
1311
1312
#ifdef ANDROID_ENABLED
1313
if (tex->target == _GL_TEXTURE_EXTERNAL_OES && p_external_buffer) {
1314
glBindTexture(_GL_TEXTURE_EXTERNAL_OES, tex->tex_id);
1315
GLES3::Config::get_singleton()->eglEGLImageTargetTexture2DOES(_GL_TEXTURE_EXTERNAL_OES, reinterpret_cast<void *>(p_external_buffer));
1316
glBindTexture(_GL_TEXTURE_EXTERNAL_OES, 0);
1317
}
1318
#endif
1319
}
1320
1321
void TextureStorage::texture_proxy_update(RID p_texture, RID p_proxy_to) {
1322
Texture *tex = texture_owner.get_or_null(p_texture);
1323
ERR_FAIL_NULL(tex);
1324
ERR_FAIL_COND(!tex->is_proxy);
1325
Texture *proxy_to = texture_owner.get_or_null(p_proxy_to);
1326
ERR_FAIL_NULL(proxy_to);
1327
ERR_FAIL_COND(proxy_to->is_proxy);
1328
1329
if (tex->proxy_to.is_valid()) {
1330
Texture *prev_tex = texture_owner.get_or_null(tex->proxy_to);
1331
ERR_FAIL_NULL(prev_tex);
1332
prev_tex->proxies.erase(p_texture);
1333
}
1334
1335
*tex = *proxy_to;
1336
1337
tex->proxy_to = p_proxy_to;
1338
tex->is_render_target = false;
1339
tex->is_proxy = true;
1340
tex->proxies.clear();
1341
tex->canvas_texture = nullptr;
1342
tex->tex_id = 0;
1343
proxy_to->proxies.push_back(p_texture);
1344
}
1345
1346
void TextureStorage::texture_remap_proxies(RID p_from_texture, RID p_to_texture) {
1347
Texture *from_tex = texture_owner.get_or_null(p_from_texture);
1348
ERR_FAIL_NULL(from_tex);
1349
ERR_FAIL_COND(from_tex->is_proxy);
1350
Texture *to_tex = texture_owner.get_or_null(p_to_texture);
1351
ERR_FAIL_NULL(to_tex);
1352
ERR_FAIL_COND(to_tex->is_proxy);
1353
1354
if (from_tex == to_tex) {
1355
return;
1356
}
1357
1358
// Make a local copy, we're about to change the content of the original.
1359
thread_local LocalVector<RID> proxies(from_tex->proxies);
1360
1361
// Now change them to our new texture.
1362
for (RID &proxy : proxies) {
1363
texture_proxy_update(proxy, p_to_texture);
1364
}
1365
}
1366
1367
// Output textures in p_textures must ALL BE THE SAME SIZE
1368
void 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) {
1369
ERR_FAIL_COND_MSG(!tex_blit_shader.initialized, "Texture Blit shader & materials not yet initialized.");
1370
ERR_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.");
1371
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
1372
1373
TexBlitMaterialData *m = static_cast<TexBlitMaterialData *>(material_storage->material_get_data(p_material, RS::SHADER_TEXTURE_BLIT));
1374
if (!m) {
1375
m = static_cast<TexBlitMaterialData *>(material_storage->material_get_data(tex_blit_shader.default_material, RS::SHADER_TEXTURE_BLIT));
1376
}
1377
// GUARDRAIL: p_material MUST BE ShaderType TextureBlit
1378
ERR_FAIL_NULL(m);
1379
1380
TexBlitShaderGLES3::ShaderVariant variant = TexBlitShaderGLES3::MODE_DEFAULT;
1381
RID version = tex_blit_shader.default_shader_version;
1382
if (m->shader_data->version.is_valid() && m->shader_data->valid) {
1383
// Must be called to force user ShaderMaterials to actually populate uniform buffer before binding
1384
// 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 updates
1385
material_storage->_update_queued_materials();
1386
// Bind material uniform buffer and textures.
1387
m->bind_uniforms();
1388
version = m->shader_data->version;
1389
}
1390
1391
glBindFramebuffer(GL_FRAMEBUFFER, tex_blit_fbo);
1392
TightLocalVector<GLenum> draw_buffers;
1393
1394
Texture *tar_textures[4];
1395
int convert_to_srgb_mask = 0;
1396
Texture *src_textures[4];
1397
1398
int i = 0;
1399
uint32_t specialization = 0;
1400
const int outputFlagArray[4] = { 0, TexBlitShaderGLES3::USE_OUTPUT1, TexBlitShaderGLES3::USE_OUTPUT2, TexBlitShaderGLES3::USE_OUTPUT3 };
1401
const int srgbMaskArray[4] = { 1, 2, 4, 8 };
1402
while (i < 4) {
1403
// Attach Targets to Framebuffer
1404
if (i < p_textures.size()) {
1405
tar_textures[i] = get_texture(p_textures[i]);
1406
ERR_FAIL_NULL_MSG(tar_textures[i], "Drawable Texture target cannot be null.");
1407
if (i > 0) {
1408
ERR_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.");
1409
}
1410
specialization |= outputFlagArray[i];
1411
draw_buffers.push_back(GL_COLOR_ATTACHMENT0 + i);
1412
ERR_FAIL_COND_MSG(p_to_mipmap >= tar_textures[i]->mipmaps, vformat("Drawable Texture Target does not have mipmap level %d.", p_to_mipmap));
1413
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, tar_textures[i]->tex_id, p_to_mipmap);
1414
convert_to_srgb_mask += tar_textures[i]->drawable_type == RS::TEXTURE_DRAWABLE_FORMAT_RGBA8_SRGB ? srgbMaskArray[i] : 0;
1415
}
1416
1417
// Bind Sources to buffer. Use placeholder Black Texture if source is bad.
1418
if (i < p_source_textures.size()) {
1419
src_textures[i] = get_texture(p_source_textures[i]);
1420
if (!src_textures[i]) {
1421
src_textures[i] = get_texture(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE]);
1422
}
1423
} else {
1424
src_textures[i] = get_texture(default_gl_textures[DEFAULT_GL_TEXTURE_WHITE]);
1425
}
1426
int shift = i == 0 ? 0 : GLES3::Config::get_singleton()->max_texture_image_units - i;
1427
glActiveTexture(GL_TEXTURE0 + shift);
1428
glBindTexture(GL_TEXTURE_2D, src_textures[i]->tex_id);
1429
1430
i += 1;
1431
}
1432
1433
bool success = material_storage->shaders.tex_blit_shader.version_bind_shader(version, variant, specialization);
1434
if (!success) {
1435
return;
1436
}
1437
1438
// Calculates the Rects Offset & Size in UV space for Shader to scale Vertex Quad correctly
1439
Vector3 size = texture_get_size(p_textures[0]);
1440
Vector2 offset = Vector2(p_rect.position.x / size.x, p_rect.position.y / size.y);
1441
Vector2 rect_size = Vector2(p_rect.size.x / size.x, p_rect.size.y / size.y);
1442
Vector2i vp_size = Vector2i(tar_textures[0]->alloc_width, tar_textures[0]->alloc_height);
1443
if (p_to_mipmap != 0) {
1444
vp_size.x >>= p_to_mipmap;
1445
vp_size.y >>= p_to_mipmap;
1446
}
1447
1448
glViewport(0, 0, vp_size.x, vp_size.y);
1449
1450
material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::CONVERT_TO_SRGB, convert_to_srgb_mask, version, variant, specialization);
1451
material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::SIZE, rect_size, version, variant, specialization);
1452
material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::OFFSET, offset, version, variant, specialization);
1453
material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::MODULATE, p_modulate, version, variant, specialization);
1454
material_storage->shaders.tex_blit_shader.version_set_uniform(TexBlitShaderGLES3::TIME, RasterizerGLES3::get_singleton()->get_total_time(), version, variant, specialization);
1455
1456
// Set Blend_Mode correctly
1457
GLES3::TexBlitShaderData::BlendMode blend_mode = m->shader_data->blend_mode;
1458
glEnable(GL_BLEND);
1459
switch (blend_mode) {
1460
case GLES3::TexBlitShaderData::BLEND_MODE_ADD:
1461
glBlendEquation(GL_FUNC_ADD);
1462
glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
1463
break;
1464
1465
case GLES3::TexBlitShaderData::BLEND_MODE_SUB:
1466
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
1467
glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
1468
break;
1469
1470
case GLES3::TexBlitShaderData::BLEND_MODE_MIX:
1471
glBlendEquation(GL_FUNC_ADD);
1472
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
1473
break;
1474
1475
case GLES3::TexBlitShaderData::BLEND_MODE_MUL:
1476
glBlendEquation(GL_FUNC_ADD);
1477
glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_DST_ALPHA, GL_ZERO);
1478
break;
1479
1480
case GLES3::TexBlitShaderData::BLEND_MODE_DISABLED:
1481
glDisable(GL_BLEND);
1482
break;
1483
}
1484
1485
glDrawBuffers(draw_buffers.size(), draw_buffers.ptr());
1486
1487
// DRAW!!
1488
glBindVertexArray(tex_blit_quad_array);
1489
glDrawArrays(GL_TRIANGLES, 0, 6);
1490
glBindVertexArray(0);
1491
1492
// Reset to system FBO
1493
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
1494
}
1495
1496
void TextureStorage::texture_2d_placeholder_initialize(RID p_texture) {
1497
texture_2d_initialize(p_texture, texture_2d_placeholder);
1498
}
1499
1500
void TextureStorage::texture_2d_layered_placeholder_initialize(RID p_texture, RS::TextureLayeredType p_layered_type) {
1501
if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) {
1502
texture_2d_layered_initialize(p_texture, texture_2d_array_placeholder, p_layered_type);
1503
} else {
1504
texture_2d_layered_initialize(p_texture, cubemap_placeholder, p_layered_type);
1505
}
1506
}
1507
1508
void TextureStorage::texture_3d_placeholder_initialize(RID p_texture) {
1509
texture_3d_initialize(p_texture, Image::FORMAT_RGBA8, 4, 4, 4, false, texture_3d_placeholder);
1510
}
1511
1512
Ref<Image> TextureStorage::texture_2d_get(RID p_texture) const {
1513
Texture *texture = texture_owner.get_or_null(p_texture);
1514
ERR_FAIL_NULL_V(texture, Ref<Image>());
1515
1516
#ifdef TOOLS_ENABLED
1517
if (texture->image_cache_2d.is_valid() && !texture->is_render_target) {
1518
return texture->image_cache_2d;
1519
}
1520
#endif
1521
1522
Ref<Image> image;
1523
#ifdef GL_API_ENABLED
1524
if (RasterizerGLES3::is_gles_over_gl()) {
1525
// OpenGL 3.3 supports glGetTexImage which is faster and simpler than glReadPixels.
1526
// It also allows for reading compressed textures, mipmaps, and more formats.
1527
Vector<uint8_t> data;
1528
1529
int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->real_format, texture->mipmaps > 1);
1530
1531
data.resize(data_size * 2); // Add some memory at the end, just in case for buggy drivers.
1532
uint8_t *w = data.ptrw();
1533
1534
glActiveTexture(GL_TEXTURE0);
1535
1536
glBindTexture(texture->target, texture->tex_id);
1537
1538
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1539
1540
for (int i = 0; i < texture->mipmaps; i++) {
1541
int64_t ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, texture->real_format, i);
1542
1543
if (texture->compressed) {
1544
glPixelStorei(GL_PACK_ALIGNMENT, 4);
1545
glGetCompressedTexImage(texture->target, i, &w[ofs]);
1546
} else {
1547
glPixelStorei(GL_PACK_ALIGNMENT, 1);
1548
glGetTexImage(texture->target, i, texture->gl_format_cache, texture->gl_type_cache, &w[ofs]);
1549
}
1550
}
1551
1552
data.resize(data_size);
1553
1554
ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());
1555
image = Image::create_from_data(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1, texture->real_format, data);
1556
if (image->is_empty()) {
1557
const String &path_str = texture->path.is_empty() ? "with no path" : vformat("with path '%s'", texture->path);
1558
ERR_FAIL_V_MSG(Ref<Image>(), vformat("Texture %s has no data.", path_str));
1559
}
1560
1561
if (texture->format != texture->real_format && !Image::is_format_compressed(texture->real_format)) {
1562
image->convert(texture->format);
1563
}
1564
}
1565
#endif // GL_API_ENABLED
1566
#ifdef GLES_API_ENABLED
1567
if (!RasterizerGLES3::is_gles_over_gl()) {
1568
Vector<uint8_t> data;
1569
1570
// On web and mobile we always read an RGBA8 image with no mipmaps.
1571
int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);
1572
1573
data.resize(data_size * 2); // Add some memory at the end, just in case for buggy drivers.
1574
uint8_t *w = data.ptrw();
1575
1576
GLuint temp_framebuffer;
1577
glGenFramebuffers(1, &temp_framebuffer);
1578
1579
GLuint temp_color_texture;
1580
glGenTextures(1, &temp_color_texture);
1581
1582
glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);
1583
1584
glBindTexture(GL_TEXTURE_2D, temp_color_texture);
1585
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1586
1587
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1588
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1589
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);
1590
1591
glDepthMask(GL_FALSE);
1592
glDisable(GL_DEPTH_TEST);
1593
glDisable(GL_CULL_FACE);
1594
glDisable(GL_BLEND);
1595
glDepthFunc(GL_GEQUAL);
1596
glColorMask(1, 1, 1, 1);
1597
glActiveTexture(GL_TEXTURE0);
1598
glBindTexture(GL_TEXTURE_2D, texture->tex_id);
1599
1600
glViewport(0, 0, texture->alloc_width, texture->alloc_height);
1601
glClearColor(0.0, 0.0, 0.0, 0.0);
1602
glClear(GL_COLOR_BUFFER_BIT);
1603
1604
CopyEffects::get_singleton()->copy_to_rect(Rect2i(0, 0, 1.0, 1.0));
1605
1606
glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);
1607
1608
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
1609
glDeleteTextures(1, &temp_color_texture);
1610
glDeleteFramebuffers(1, &temp_framebuffer);
1611
1612
data.resize(data_size);
1613
1614
ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());
1615
image = Image::create_from_data(texture->alloc_width, texture->alloc_height, false, Image::FORMAT_RGBA8, data);
1616
if (image->is_empty()) {
1617
const String &path_str = texture->path.is_empty() ? "with no path" : vformat("with path '%s'", texture->path);
1618
ERR_FAIL_V_MSG(Ref<Image>(), vformat("Texture %s has no data.", path_str));
1619
}
1620
1621
if (texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(texture->format)) {
1622
image->convert(texture->format);
1623
}
1624
1625
if (texture->mipmaps > 1) {
1626
image->generate_mipmaps();
1627
}
1628
}
1629
#endif // GLES_API_ENABLED
1630
1631
#ifdef TOOLS_ENABLED
1632
if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {
1633
texture->image_cache_2d = image;
1634
}
1635
#endif
1636
1637
return image;
1638
}
1639
1640
Ref<Image> TextureStorage::texture_2d_layer_get(RID p_texture, int p_layer) const {
1641
Texture *texture = texture_owner.get_or_null(p_texture);
1642
ERR_FAIL_NULL_V(texture, Ref<Image>());
1643
1644
Vector<uint8_t> data;
1645
1646
int64_t data_size = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, Image::FORMAT_RGBA8, false);
1647
1648
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
1649
uint8_t *w = data.ptrw();
1650
1651
GLuint temp_framebuffer;
1652
glGenFramebuffers(1, &temp_framebuffer);
1653
1654
GLuint temp_color_texture;
1655
glGenTextures(1, &temp_color_texture);
1656
1657
glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);
1658
1659
glBindTexture(GL_TEXTURE_2D, temp_color_texture);
1660
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1661
1662
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1663
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1664
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);
1665
1666
glDepthMask(GL_FALSE);
1667
glDisable(GL_DEPTH_TEST);
1668
glDisable(GL_CULL_FACE);
1669
glDisable(GL_BLEND);
1670
glDepthFunc(GL_LEQUAL);
1671
glColorMask(1, 1, 1, 1);
1672
glActiveTexture(GL_TEXTURE0);
1673
glBindTexture(GL_TEXTURE_2D_ARRAY, texture->tex_id);
1674
1675
glViewport(0, 0, texture->alloc_width, texture->alloc_height);
1676
glClearColor(0.0, 0.0, 0.0, 0.0);
1677
glClear(GL_COLOR_BUFFER_BIT);
1678
1679
CopyEffects::get_singleton()->copy_to_rect_3d(Rect2i(0, 0, 1, 1), p_layer, Texture::TYPE_LAYERED);
1680
1681
glReadPixels(0, 0, texture->alloc_width, texture->alloc_height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);
1682
1683
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
1684
glDeleteTextures(1, &temp_color_texture);
1685
glDeleteFramebuffers(1, &temp_framebuffer);
1686
1687
data.resize(data_size);
1688
1689
ERR_FAIL_COND_V(data.is_empty(), Ref<Image>());
1690
Ref<Image> image = Image::create_from_data(texture->width, texture->height, false, Image::FORMAT_RGBA8, data);
1691
if (image->is_empty()) {
1692
const String &path_str = texture->path.is_empty() ? "with no path" : vformat("with path '%s'", texture->path);
1693
ERR_FAIL_V_MSG(Ref<Image>(), vformat("Texture %s has no data.", path_str));
1694
}
1695
1696
if (texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(texture->format)) {
1697
image->convert(texture->format);
1698
}
1699
1700
if (texture->mipmaps > 1) {
1701
image->generate_mipmaps();
1702
}
1703
1704
return image;
1705
}
1706
1707
Vector<Ref<Image>> TextureStorage::_texture_3d_read_framebuffer(GLES3::Texture *p_texture) const {
1708
ERR_FAIL_NULL_V(p_texture, Vector<Ref<Image>>());
1709
1710
Vector<Ref<Image>> ret;
1711
Vector<uint8_t> data;
1712
1713
int width = p_texture->width;
1714
int height = p_texture->height;
1715
int depth = p_texture->depth;
1716
1717
for (int mipmap_level = 0; mipmap_level < p_texture->mipmaps; mipmap_level++) {
1718
int64_t data_size = Image::get_image_data_size(width, height, Image::FORMAT_RGBA8, false);
1719
glViewport(0, 0, width, height);
1720
glClearColor(0.0, 0.0, 0.0, 0.0);
1721
glClear(GL_COLOR_BUFFER_BIT);
1722
1723
for (int layer = 0; layer < depth; layer++) {
1724
data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers
1725
uint8_t *w = data.ptrw();
1726
1727
float layer_f = layer / float(depth);
1728
CopyEffects::get_singleton()->copy_to_rect_3d(Rect2i(0, 0, 1, 1), layer_f, Texture::TYPE_3D, mipmap_level);
1729
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &w[0]);
1730
1731
data.resize(data_size);
1732
ERR_FAIL_COND_V(data.is_empty(), Vector<Ref<Image>>());
1733
1734
Ref<Image> img = Image::create_from_data(width, height, false, Image::FORMAT_RGBA8, data);
1735
ERR_FAIL_COND_V(img->is_empty(), Vector<Ref<Image>>());
1736
1737
if (p_texture->format != Image::FORMAT_RGBA8 && !Image::is_format_compressed(p_texture->format)) {
1738
img->convert(p_texture->format);
1739
}
1740
1741
ret.push_back(img);
1742
}
1743
1744
width = MAX(1, width >> 1);
1745
height = MAX(1, height >> 1);
1746
depth = MAX(1, depth >> 1);
1747
}
1748
1749
return ret;
1750
}
1751
1752
Vector<Ref<Image>> TextureStorage::texture_3d_get(RID p_texture) const {
1753
Texture *texture = texture_owner.get_or_null(p_texture);
1754
ERR_FAIL_NULL_V(texture, Vector<Ref<Image>>());
1755
ERR_FAIL_COND_V(texture->type != Texture::TYPE_3D, Vector<Ref<Image>>());
1756
1757
#ifdef TOOLS_ENABLED
1758
if (!texture->image_cache_3d.is_empty() && !texture->is_render_target) {
1759
return texture->image_cache_3d;
1760
}
1761
#endif
1762
1763
GLuint temp_framebuffer;
1764
glGenFramebuffers(1, &temp_framebuffer);
1765
1766
GLuint temp_color_texture;
1767
glGenTextures(1, &temp_color_texture);
1768
1769
glBindFramebuffer(GL_FRAMEBUFFER, temp_framebuffer);
1770
1771
glBindTexture(GL_TEXTURE_2D, temp_color_texture);
1772
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->alloc_width, texture->alloc_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1773
1774
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1775
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1776
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, temp_color_texture, 0);
1777
1778
glDepthMask(GL_FALSE);
1779
glDisable(GL_DEPTH_TEST);
1780
glDisable(GL_CULL_FACE);
1781
glDisable(GL_BLEND);
1782
glDepthFunc(GL_LEQUAL);
1783
glColorMask(1, 1, 1, 1);
1784
glActiveTexture(GL_TEXTURE0);
1785
glBindTexture(GL_TEXTURE_3D, texture->tex_id);
1786
1787
Vector<Ref<Image>> ret = _texture_3d_read_framebuffer(texture);
1788
1789
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
1790
glDeleteTextures(1, &temp_color_texture);
1791
glDeleteFramebuffers(1, &temp_framebuffer);
1792
1793
#ifdef TOOLS_ENABLED
1794
if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {
1795
texture->image_cache_3d = ret;
1796
}
1797
#endif
1798
1799
return ret;
1800
}
1801
1802
void TextureStorage::texture_drawable_generate_mipmaps(RID p_texture) {
1803
Texture *texture = get_texture(p_texture);
1804
Vector3i size = texture_get_size(p_texture);
1805
CopyEffects::get_singleton()->bilinear_blur(texture->tex_id, texture->mipmaps, Rect2i(0, 0, size.x, size.y));
1806
}
1807
1808
RID TextureStorage::texture_drawable_get_default_material() const {
1809
// This should never be called before DrawableTexture stuff is initialized.
1810
return tex_blit_shader.default_material;
1811
}
1812
1813
void TextureStorage::texture_replace(RID p_texture, RID p_by_texture) {
1814
Texture *tex_to = texture_owner.get_or_null(p_texture);
1815
ERR_FAIL_NULL(tex_to);
1816
ERR_FAIL_COND(tex_to->is_proxy); //can't replace proxy
1817
Texture *tex_from = texture_owner.get_or_null(p_by_texture);
1818
ERR_FAIL_NULL(tex_from);
1819
ERR_FAIL_COND(tex_from->is_proxy); //can't replace proxy
1820
1821
if (tex_to == tex_from) {
1822
return;
1823
}
1824
1825
if (tex_to->canvas_texture) {
1826
memdelete(tex_to->canvas_texture);
1827
tex_to->canvas_texture = nullptr;
1828
}
1829
1830
if (tex_to->tex_id) {
1831
GLES3::Utilities::get_singleton()->texture_free_data(tex_to->tex_id);
1832
tex_to->tex_id = 0;
1833
}
1834
1835
Vector<RID> proxies_to_update = Vector<RID>(tex_to->proxies);
1836
Vector<RID> proxies_to_redirect = Vector<RID>(tex_from->proxies);
1837
1838
*tex_to = *tex_from;
1839
1840
tex_to->proxies = proxies_to_update; //restore proxies, so they can be updated
1841
1842
if (tex_to->canvas_texture) {
1843
tex_to->canvas_texture->diffuse = p_texture; //update
1844
}
1845
1846
for (int i = 0; i < proxies_to_update.size(); i++) {
1847
texture_proxy_update(proxies_to_update[i], p_texture);
1848
}
1849
for (int i = 0; i < proxies_to_redirect.size(); i++) {
1850
texture_proxy_update(proxies_to_redirect[i], p_texture);
1851
}
1852
//delete last, so proxies can be updated
1853
texture_owner.free(p_by_texture);
1854
1855
texture_atlas_mark_dirty_on_texture(p_texture);
1856
}
1857
1858
void TextureStorage::texture_set_size_override(RID p_texture, int p_width, int p_height) {
1859
Texture *texture = texture_owner.get_or_null(p_texture);
1860
1861
ERR_FAIL_NULL(texture);
1862
ERR_FAIL_COND(texture->is_render_target);
1863
1864
ERR_FAIL_COND(p_width <= 0 || p_width > 16384);
1865
ERR_FAIL_COND(p_height <= 0 || p_height > 16384);
1866
//real texture size is in alloc width and height
1867
texture->width = p_width;
1868
texture->height = p_height;
1869
}
1870
1871
void TextureStorage::texture_set_path(RID p_texture, const String &p_path) {
1872
Texture *texture = texture_owner.get_or_null(p_texture);
1873
ERR_FAIL_NULL(texture);
1874
1875
texture->path = p_path;
1876
}
1877
1878
String TextureStorage::texture_get_path(RID p_texture) const {
1879
Texture *texture = texture_owner.get_or_null(p_texture);
1880
ERR_FAIL_NULL_V(texture, "");
1881
1882
return texture->path;
1883
}
1884
1885
void TextureStorage::texture_set_detect_3d_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
1886
Texture *texture = texture_owner.get_or_null(p_texture);
1887
ERR_FAIL_NULL(texture);
1888
1889
texture->detect_3d_callback = p_callback;
1890
texture->detect_3d_callback_ud = p_userdata;
1891
}
1892
1893
void TextureStorage::texture_set_detect_srgb_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
1894
}
1895
1896
void TextureStorage::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
1897
Texture *texture = texture_owner.get_or_null(p_texture);
1898
ERR_FAIL_NULL(texture);
1899
1900
texture->detect_normal_callback = p_callback;
1901
texture->detect_normal_callback_ud = p_userdata;
1902
}
1903
1904
void TextureStorage::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {
1905
Texture *texture = texture_owner.get_or_null(p_texture);
1906
ERR_FAIL_NULL(texture);
1907
1908
texture->detect_roughness_callback = p_callback;
1909
texture->detect_roughness_callback_ud = p_userdata;
1910
}
1911
1912
void TextureStorage::texture_debug_usage(List<RS::TextureInfo> *r_info) {
1913
for (const RID &rid : texture_owner.get_owned_list()) {
1914
Texture *t = texture_owner.get_or_null(rid);
1915
if (!t) {
1916
continue;
1917
}
1918
RS::TextureInfo tinfo;
1919
tinfo.path = t->path;
1920
tinfo.format = t->format;
1921
tinfo.width = t->alloc_width;
1922
tinfo.height = t->alloc_height;
1923
tinfo.bytes = t->total_data_size;
1924
tinfo.type = static_cast<RenderingServer::TextureType>(t->type);
1925
1926
switch (t->type) {
1927
case Texture::TYPE_3D:
1928
tinfo.depth = t->depth;
1929
break;
1930
1931
case Texture::TYPE_LAYERED:
1932
tinfo.depth = t->layers;
1933
break;
1934
1935
default:
1936
tinfo.depth = 0;
1937
break;
1938
}
1939
1940
r_info->push_back(tinfo);
1941
}
1942
}
1943
1944
void TextureStorage::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {
1945
Texture *texture = texture_owner.get_or_null(p_texture);
1946
ERR_FAIL_NULL(texture);
1947
1948
texture->redraw_if_visible = p_enable;
1949
}
1950
1951
Size2 TextureStorage::texture_size_with_proxy(RID p_texture) {
1952
const Texture *texture = texture_owner.get_or_null(p_texture);
1953
ERR_FAIL_NULL_V(texture, Size2());
1954
if (texture->is_proxy) {
1955
const Texture *proxy = texture_owner.get_or_null(texture->proxy_to);
1956
return Size2(proxy->width, proxy->height);
1957
} else {
1958
return Size2(texture->width, texture->height);
1959
}
1960
}
1961
1962
void TextureStorage::texture_rd_initialize(RID p_texture, const RID &p_rd_texture, const RS::TextureLayeredType p_layer_type) {
1963
}
1964
1965
RID TextureStorage::texture_get_rd_texture(RID p_texture, bool p_srgb) const {
1966
return RID();
1967
}
1968
1969
uint64_t TextureStorage::texture_get_native_handle(RID p_texture, bool p_srgb) const {
1970
const Texture *texture = texture_owner.get_or_null(p_texture);
1971
ERR_FAIL_NULL_V(texture, 0);
1972
1973
return texture->tex_id;
1974
}
1975
1976
void TextureStorage::texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer) {
1977
_texture_set_data(p_texture, p_image, p_layer, false);
1978
}
1979
1980
void TextureStorage::_texture_set_data(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_initialize) {
1981
Texture *texture = texture_owner.get_or_null(p_texture);
1982
1983
ERR_FAIL_NULL(texture);
1984
if (texture->target == GL_TEXTURE_3D) {
1985
// Target is set to a 3D texture or array texture, exit early to avoid spamming errors
1986
return;
1987
}
1988
ERR_FAIL_COND(!texture->active);
1989
ERR_FAIL_COND(texture->is_render_target);
1990
ERR_FAIL_COND(p_image.is_null());
1991
ERR_FAIL_COND(texture->format != p_image->get_format());
1992
1993
ERR_FAIL_COND(!p_image->get_width());
1994
ERR_FAIL_COND(!p_image->get_height());
1995
1996
GLenum type;
1997
GLenum format;
1998
GLenum internal_format;
1999
bool compressed = false;
2000
2001
bool needs_decompress = texture->resize_to_po2;
2002
2003
// Support for RGTC-compressed Texture Arrays isn't mandated by GLES3/WebGL.
2004
if (!RasterizerGLES3::is_gles_over_gl() && texture->target == GL_TEXTURE_2D_ARRAY) {
2005
if (p_image->get_format() == Image::FORMAT_RGTC_R || p_image->get_format() == Image::FORMAT_RGTC_RG) {
2006
needs_decompress = true;
2007
}
2008
}
2009
2010
Image::Format real_format;
2011
Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), real_format, format, internal_format, type, compressed, needs_decompress);
2012
ERR_FAIL_COND(img.is_null());
2013
if (texture->resize_to_po2) {
2014
if (p_image->is_compressed()) {
2015
ERR_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.");
2016
}
2017
2018
if (img == p_image) {
2019
img = img->duplicate();
2020
}
2021
img->resize_to_po2(false);
2022
}
2023
2024
GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_layer] : texture->target;
2025
2026
Vector<uint8_t> read = img->get_data();
2027
2028
glActiveTexture(GL_TEXTURE0);
2029
glBindTexture(texture->target, texture->tex_id);
2030
_texture_set_swizzle(texture, real_format);
2031
2032
int mipmaps = img->has_mipmaps() ? img->get_mipmap_count() + 1 : 1;
2033
2034
// Set filtering and repeat state to default.
2035
if (mipmaps > 1) {
2036
texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
2037
} else {
2038
texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
2039
}
2040
2041
texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
2042
2043
int w = img->get_width();
2044
int h = img->get_height();
2045
2046
int tsize = 0;
2047
2048
for (int i = 0; i < mipmaps; i++) {
2049
int64_t size, ofs;
2050
img->get_mipmap_offset_and_size(i, ofs, size);
2051
if (compressed) {
2052
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
2053
if (texture->target == GL_TEXTURE_2D_ARRAY) {
2054
if (p_initialize) {
2055
glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0, size * texture->layers, nullptr);
2056
}
2057
glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 1, internal_format, size, &read[ofs]);
2058
} else {
2059
glCompressedTexImage2D(blit_target, i, internal_format, w, h, 0, size, &read[ofs]);
2060
}
2061
} else {
2062
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2063
if (texture->target == GL_TEXTURE_2D_ARRAY) {
2064
if (p_initialize) {
2065
glTexImage3D(GL_TEXTURE_2D_ARRAY, i, internal_format, w, h, texture->layers, 0, format, type, nullptr);
2066
}
2067
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, i, 0, 0, p_layer, w, h, 1, format, type, &read[ofs]);
2068
} else {
2069
glTexImage2D(blit_target, i, internal_format, w, h, 0, format, type, &read[ofs]);
2070
}
2071
}
2072
2073
tsize += size;
2074
2075
w = MAX(1, w >> 1);
2076
h = MAX(1, h >> 1);
2077
}
2078
2079
if (texture->target == GL_TEXTURE_CUBE_MAP || texture->target == GL_TEXTURE_2D_ARRAY) {
2080
texture->total_data_size = tsize * texture->layers;
2081
} else {
2082
texture->total_data_size = tsize;
2083
}
2084
2085
texture->stored_cube_sides |= (1 << p_layer);
2086
2087
texture->mipmaps = mipmaps;
2088
}
2089
2090
void TextureStorage::_texture_set_3d_data(RID p_texture, const Vector<Ref<Image>> &p_data, bool p_initialize) {
2091
Texture *texture = texture_owner.get_or_null(p_texture);
2092
2093
ERR_FAIL_NULL(texture);
2094
ERR_FAIL_COND(!texture->active);
2095
ERR_FAIL_COND(texture->is_render_target);
2096
ERR_FAIL_COND(texture->target != GL_TEXTURE_3D);
2097
ERR_FAIL_COND(p_data.is_empty());
2098
2099
GLenum type;
2100
GLenum format;
2101
GLenum internal_format;
2102
bool compressed = false;
2103
2104
Image::Format real_format;
2105
Ref<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);
2106
ERR_FAIL_COND(img.is_null());
2107
2108
ERR_FAIL_COND_MSG(compressed, "Compressed 3D textures are not supported in the Compatibility renderer.");
2109
2110
glActiveTexture(GL_TEXTURE0);
2111
glBindTexture(texture->target, texture->tex_id);
2112
_texture_set_swizzle(texture, texture->real_format);
2113
2114
// Set filtering and repeat state to default.
2115
if (texture->mipmaps > 1) {
2116
texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
2117
} else {
2118
texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
2119
}
2120
2121
texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
2122
2123
Vector<Ref<Image>> images;
2124
images.resize(p_data.size());
2125
for (int i = 0; i < p_data.size(); i++) {
2126
Ref<Image> image = p_data[i];
2127
if (image->get_format() != texture->format) {
2128
image = image->duplicate();
2129
image->convert(texture->format);
2130
}
2131
images.write[i] = image;
2132
}
2133
2134
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2135
2136
int all_data_size = 0;
2137
int mipmap_level = 0;
2138
int layer = 0;
2139
int depth = texture->depth;
2140
Size2i prev_size(images[0]->get_width(), images[0]->get_height());
2141
for (int i = 0; i < images.size(); i++) {
2142
Ref<Image> image = images[i];
2143
Size2i img_size(image->get_width(), image->get_height());
2144
2145
if (img_size != prev_size) {
2146
mipmap_level++;
2147
depth = MAX(1, depth >> 1);
2148
layer = 0;
2149
}
2150
prev_size = img_size;
2151
all_data_size += image->get_data().size();
2152
2153
if (layer == 0 && p_initialize) {
2154
glTexImage3D(GL_TEXTURE_3D, mipmap_level, internal_format, img_size.width, img_size.height, depth, 0, format, type, nullptr);
2155
}
2156
2157
glTexSubImage3D(GL_TEXTURE_3D, mipmap_level, 0, 0, layer, img_size.width, img_size.height, 1, format, type, image->get_data().ptr());
2158
2159
layer++;
2160
}
2161
2162
texture->total_data_size = all_data_size;
2163
texture->mipmaps = mipmap_level + 1;
2164
2165
#ifdef TOOLS_ENABLED
2166
if (Engine::get_singleton()->is_editor_hint() && !texture->is_render_target) {
2167
texture->image_cache_3d = images;
2168
}
2169
#endif
2170
}
2171
2172
void TextureStorage::_texture_set_swizzle(GLES3::Texture *p_texture, Image::Format p_real_format) {
2173
#ifndef WEB_ENABLED
2174
switch (p_texture->format) {
2175
case Image::FORMAT_L8: {
2176
if (RasterizerGLES3::is_gles_over_gl()) {
2177
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2178
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_RED);
2179
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_RED);
2180
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ONE);
2181
} else {
2182
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2183
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
2184
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
2185
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
2186
}
2187
} break;
2188
case Image::FORMAT_LA8: {
2189
if (RasterizerGLES3::is_gles_over_gl()) {
2190
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2191
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_RED);
2192
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_RED);
2193
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
2194
} else {
2195
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2196
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
2197
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
2198
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
2199
}
2200
} break;
2201
case Image::FORMAT_ETC2_RA_AS_RG:
2202
case Image::FORMAT_DXT5_RA_AS_RG: {
2203
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2204
if (p_texture->format == p_real_format) {
2205
// Swizzle RA from compressed texture into RG.
2206
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_ALPHA);
2207
} else {
2208
// Converted textures are already in RG, leave as-is.
2209
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
2210
}
2211
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_ZERO);
2212
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ONE);
2213
} break;
2214
default: {
2215
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_R, GL_RED);
2216
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
2217
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
2218
glTexParameteri(p_texture->target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
2219
} break;
2220
}
2221
#endif // WEB_ENABLED
2222
}
2223
2224
Image::Format TextureStorage::texture_get_format(RID p_texture) const {
2225
Texture *texture = texture_owner.get_or_null(p_texture);
2226
2227
ERR_FAIL_NULL_V(texture, Image::FORMAT_L8);
2228
2229
return texture->format;
2230
}
2231
2232
uint32_t TextureStorage::texture_get_texid(RID p_texture) const {
2233
Texture *texture = texture_owner.get_or_null(p_texture);
2234
2235
ERR_FAIL_NULL_V(texture, 0);
2236
2237
return texture->tex_id;
2238
}
2239
2240
Vector3i TextureStorage::texture_get_size(RID p_texture) const {
2241
Texture *texture = texture_owner.get_or_null(p_texture);
2242
2243
ERR_FAIL_NULL_V(texture, Vector3i(0, 0, 0));
2244
2245
return Vector3i(texture->width, texture->height, texture->depth);
2246
}
2247
2248
uint32_t TextureStorage::texture_get_width(RID p_texture) const {
2249
Texture *texture = texture_owner.get_or_null(p_texture);
2250
2251
ERR_FAIL_NULL_V(texture, 0);
2252
2253
return texture->width;
2254
}
2255
2256
uint32_t TextureStorage::texture_get_height(RID p_texture) const {
2257
Texture *texture = texture_owner.get_or_null(p_texture);
2258
2259
ERR_FAIL_NULL_V(texture, 0);
2260
2261
return texture->height;
2262
}
2263
2264
uint32_t TextureStorage::texture_get_depth(RID p_texture) const {
2265
Texture *texture = texture_owner.get_or_null(p_texture);
2266
2267
ERR_FAIL_NULL_V(texture, 0);
2268
2269
return texture->depth;
2270
}
2271
2272
void TextureStorage::texture_bind(RID p_texture, uint32_t p_texture_no) {
2273
Texture *texture = texture_owner.get_or_null(p_texture);
2274
2275
ERR_FAIL_NULL(texture);
2276
2277
glActiveTexture(GL_TEXTURE0 + p_texture_no);
2278
glBindTexture(texture->target, texture->tex_id);
2279
}
2280
2281
/* TEXTURE ATLAS API */
2282
2283
void TextureStorage::texture_add_to_texture_atlas(RID p_texture) {
2284
if (!texture_atlas.textures.has(p_texture)) {
2285
TextureAtlas::Texture t;
2286
t.users = 1;
2287
texture_atlas.textures[p_texture] = t;
2288
texture_atlas.dirty = true;
2289
} else {
2290
TextureAtlas::Texture *t = texture_atlas.textures.getptr(p_texture);
2291
t->users++;
2292
}
2293
}
2294
2295
void TextureStorage::texture_remove_from_texture_atlas(RID p_texture) {
2296
TextureAtlas::Texture *t = texture_atlas.textures.getptr(p_texture);
2297
ERR_FAIL_NULL(t);
2298
t->users--;
2299
if (t->users == 0) {
2300
texture_atlas.textures.erase(p_texture);
2301
// Do not mark it dirty, there is no need to since it remains working.
2302
}
2303
}
2304
2305
void TextureStorage::texture_atlas_mark_dirty_on_texture(RID p_texture) {
2306
if (texture_atlas.textures.has(p_texture)) {
2307
texture_atlas.dirty = true; // Mark it dirty since it was most likely modified.
2308
}
2309
}
2310
2311
void TextureStorage::texture_atlas_remove_texture(RID p_texture) {
2312
if (texture_atlas.textures.has(p_texture)) {
2313
texture_atlas.textures.erase(p_texture);
2314
// There is not much a point of making it dirty, texture can be removed next time the atlas is updated.
2315
}
2316
}
2317
2318
GLuint TextureStorage::texture_atlas_get_texture() const {
2319
return texture_atlas.texture;
2320
}
2321
2322
void TextureStorage::update_texture_atlas() {
2323
CopyEffects *copy_effects = CopyEffects::get_singleton();
2324
ERR_FAIL_NULL(copy_effects);
2325
2326
if (!texture_atlas.dirty) {
2327
return; //nothing to do
2328
}
2329
2330
texture_atlas.dirty = false;
2331
2332
if (texture_atlas.texture != 0) {
2333
GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
2334
texture_atlas.texture = 0;
2335
glDeleteFramebuffers(1, &texture_atlas.framebuffer);
2336
texture_atlas.framebuffer = 0;
2337
}
2338
2339
const int border = 2;
2340
2341
if (texture_atlas.textures.size()) {
2342
//generate atlas
2343
Vector<TextureAtlas::SortItem> itemsv;
2344
itemsv.resize(texture_atlas.textures.size());
2345
uint32_t base_size = 8;
2346
2347
int idx = 0;
2348
2349
for (const KeyValue<RID, TextureAtlas::Texture> &E : texture_atlas.textures) {
2350
TextureAtlas::SortItem &si = itemsv.write[idx];
2351
2352
Texture *src_tex = get_texture(E.key);
2353
2354
si.size.width = (src_tex->width / border) + 1;
2355
si.size.height = (src_tex->height / border) + 1;
2356
si.pixel_size = Size2i(src_tex->width, src_tex->height);
2357
2358
if (base_size < (uint32_t)si.size.width) {
2359
base_size = nearest_power_of_2_templated(si.size.width);
2360
}
2361
2362
si.texture = E.key;
2363
idx++;
2364
}
2365
2366
//sort items by size
2367
itemsv.sort();
2368
2369
//attempt to create atlas
2370
int item_count = itemsv.size();
2371
TextureAtlas::SortItem *items = itemsv.ptrw();
2372
2373
int atlas_height = 0;
2374
2375
while (true) {
2376
Vector<int> v_offsetsv;
2377
v_offsetsv.resize(base_size);
2378
2379
int *v_offsets = v_offsetsv.ptrw();
2380
memset(v_offsets, 0, sizeof(int) * base_size);
2381
2382
int max_height = 0;
2383
2384
for (int i = 0; i < item_count; i++) {
2385
//best fit
2386
TextureAtlas::SortItem &si = items[i];
2387
int best_idx = -1;
2388
int best_height = 0x7FFFFFFF;
2389
for (uint32_t j = 0; j <= base_size - si.size.width; j++) {
2390
int height = 0;
2391
for (int k = 0; k < si.size.width; k++) {
2392
int h = v_offsets[k + j];
2393
if (h > height) {
2394
height = h;
2395
if (height > best_height) {
2396
break; //already bad
2397
}
2398
}
2399
}
2400
2401
if (height < best_height) {
2402
best_height = height;
2403
best_idx = j;
2404
}
2405
}
2406
2407
//update
2408
for (int k = 0; k < si.size.width; k++) {
2409
v_offsets[k + best_idx] = best_height + si.size.height;
2410
}
2411
2412
si.pos.x = best_idx;
2413
si.pos.y = best_height;
2414
2415
if (si.pos.y + si.size.height > max_height) {
2416
max_height = si.pos.y + si.size.height;
2417
}
2418
}
2419
2420
if ((uint32_t)max_height <= base_size * 2) {
2421
atlas_height = max_height;
2422
break; //good ratio, break;
2423
}
2424
2425
base_size *= 2;
2426
}
2427
2428
texture_atlas.size.width = base_size * border;
2429
texture_atlas.size.height = nearest_power_of_2_templated(atlas_height * border);
2430
2431
for (int i = 0; i < item_count; i++) {
2432
TextureAtlas::Texture *t = texture_atlas.textures.getptr(items[i].texture);
2433
t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
2434
t->uv_rect.size = items[i].pixel_size;
2435
2436
t->uv_rect.position /= Size2(texture_atlas.size);
2437
t->uv_rect.size /= Size2(texture_atlas.size);
2438
}
2439
} else {
2440
texture_atlas.size.width = 4;
2441
texture_atlas.size.height = 4;
2442
}
2443
2444
{ // Atlas Texture initialize.
2445
// TODO validate texture atlas size with maximum texture size
2446
glGenTextures(1, &texture_atlas.texture);
2447
glActiveTexture(GL_TEXTURE0);
2448
glBindTexture(GL_TEXTURE_2D, texture_atlas.texture);
2449
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture_atlas.size.width, texture_atlas.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2450
GLES3::Utilities::get_singleton()->texture_allocated_data(texture_atlas.texture, texture_atlas.size.width * texture_atlas.size.height * 4, "Texture atlas");
2451
2452
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2453
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2454
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2455
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2456
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2457
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
2458
2459
glGenFramebuffers(1, &texture_atlas.framebuffer);
2460
glBindFramebuffer(GL_FRAMEBUFFER, texture_atlas.framebuffer);
2461
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_atlas.texture, 0);
2462
2463
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2464
2465
if (status != GL_FRAMEBUFFER_COMPLETE) {
2466
glDeleteFramebuffers(1, &texture_atlas.framebuffer);
2467
texture_atlas.framebuffer = 0;
2468
GLES3::Utilities::get_singleton()->texture_free_data(texture_atlas.texture);
2469
texture_atlas.texture = 0;
2470
WARN_PRINT("Could not create texture atlas, status: " + get_framebuffer_error(status));
2471
return;
2472
}
2473
glViewport(0, 0, texture_atlas.size.width, texture_atlas.size.height);
2474
glClearColor(0.0, 0.0, 0.0, 0.0);
2475
glClear(GL_COLOR_BUFFER_BIT);
2476
glBindTexture(GL_TEXTURE_2D, 0);
2477
}
2478
2479
glDisable(GL_BLEND);
2480
2481
if (texture_atlas.textures.size()) {
2482
for (const KeyValue<RID, TextureAtlas::Texture> &E : texture_atlas.textures) {
2483
TextureAtlas::Texture *t = texture_atlas.textures.getptr(E.key);
2484
Texture *src_tex = get_texture(E.key);
2485
glActiveTexture(GL_TEXTURE0);
2486
glBindTexture(GL_TEXTURE_2D, src_tex->tex_id);
2487
copy_effects->copy_to_rect(t->uv_rect);
2488
}
2489
}
2490
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
2491
}
2492
2493
/* DECAL API */
2494
2495
RID TextureStorage::decal_allocate() {
2496
return RID();
2497
}
2498
2499
void TextureStorage::decal_initialize(RID p_rid) {
2500
}
2501
2502
void TextureStorage::decal_set_size(RID p_decal, const Vector3 &p_size) {
2503
}
2504
2505
void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
2506
}
2507
2508
void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
2509
}
2510
2511
void TextureStorage::decal_set_albedo_mix(RID p_decal, float p_mix) {
2512
}
2513
2514
void TextureStorage::decal_set_modulate(RID p_decal, const Color &p_modulate) {
2515
}
2516
2517
void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
2518
}
2519
2520
void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
2521
}
2522
2523
void TextureStorage::decal_set_fade(RID p_decal, float p_above, float p_below) {
2524
}
2525
2526
void TextureStorage::decal_set_normal_fade(RID p_decal, float p_fade) {
2527
}
2528
2529
AABB TextureStorage::decal_get_aabb(RID p_decal) const {
2530
return AABB();
2531
}
2532
2533
/* RENDER TARGET API */
2534
2535
GLuint TextureStorage::system_fbo = 0;
2536
2537
void TextureStorage::_update_render_target_color(RenderTarget *rt) {
2538
// do not allocate a render target with no size
2539
if (rt->size.x <= 0 || rt->size.y <= 0) {
2540
return;
2541
}
2542
2543
// do not allocate a render target that is attached to the screen
2544
if (rt->direct_to_screen) {
2545
rt->fbo = system_fbo;
2546
return;
2547
}
2548
2549
Config *config = Config::get_singleton();
2550
2551
if (rt->hdr) {
2552
rt->color_internal_format = GL_RGBA16F;
2553
rt->color_format = GL_RGBA;
2554
rt->color_type = GL_FLOAT;
2555
rt->color_format_size = 8;
2556
rt->image_format = Image::FORMAT_RGBAF;
2557
} else if (rt->is_transparent) {
2558
rt->color_internal_format = GL_RGBA8;
2559
rt->color_format = GL_RGBA;
2560
rt->color_type = GL_UNSIGNED_BYTE;
2561
rt->color_format_size = 4;
2562
rt->image_format = Image::FORMAT_RGBA8;
2563
} else {
2564
rt->color_internal_format = GL_RGB10_A2;
2565
rt->color_format = GL_RGBA;
2566
rt->color_type = GL_UNSIGNED_INT_2_10_10_10_REV;
2567
rt->color_format_size = 4;
2568
rt->image_format = Image::FORMAT_RGBA8;
2569
}
2570
2571
glDisable(GL_SCISSOR_TEST);
2572
glColorMask(1, 1, 1, 1);
2573
glDepthMask(GL_FALSE);
2574
2575
{
2576
Texture *texture;
2577
bool use_multiview = rt->view_count > 1 && config->multiview_supported;
2578
GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
2579
2580
/* Front FBO */
2581
2582
glGenFramebuffers(1, &rt->fbo);
2583
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
2584
2585
// color
2586
if (rt->overridden.color.is_valid()) {
2587
texture = get_texture(rt->overridden.color);
2588
ERR_FAIL_NULL(texture);
2589
2590
rt->color = texture->tex_id;
2591
rt->size = Size2i(texture->width, texture->height);
2592
} else {
2593
texture = get_texture(rt->texture);
2594
ERR_FAIL_NULL(texture);
2595
2596
glGenTextures(1, &rt->color);
2597
glBindTexture(texture_target, rt->color);
2598
2599
if (use_multiview) {
2600
glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr);
2601
} else {
2602
glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);
2603
}
2604
2605
texture->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
2606
texture->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
2607
2608
GLES3::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");
2609
}
2610
#ifndef IOS_ENABLED
2611
if (use_multiview) {
2612
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, 0, rt->view_count);
2613
} else {
2614
#else
2615
{
2616
#endif
2617
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target, rt->color, 0);
2618
}
2619
2620
// depth
2621
if (rt->overridden.depth.is_valid()) {
2622
texture = get_texture(rt->overridden.depth);
2623
ERR_FAIL_NULL(texture);
2624
2625
rt->depth = texture->tex_id;
2626
rt->depth_has_stencil = rt->overridden.depth_has_stencil;
2627
} else {
2628
glGenTextures(1, &rt->depth);
2629
glBindTexture(texture_target, rt->depth);
2630
2631
if (use_multiview) {
2632
glTexImage3D(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);
2633
} else {
2634
glTexImage2D(texture_target, 0, GL_DEPTH24_STENCIL8, rt->size.x, rt->size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
2635
}
2636
2637
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2638
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2639
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2640
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2641
2642
rt->depth_has_stencil = true;
2643
2644
GLES3::Utilities::get_singleton()->texture_allocated_data(rt->depth, rt->size.x * rt->size.y * rt->view_count * 4, "Render target depth texture");
2645
}
2646
2647
#ifndef IOS_ENABLED
2648
if (use_multiview) {
2649
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, rt->depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, rt->depth, 0, 0, rt->view_count);
2650
} else {
2651
#else
2652
{
2653
#endif
2654
glFramebufferTexture2D(GL_FRAMEBUFFER, rt->depth_has_stencil ? GL_DEPTH_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT, texture_target, rt->depth, 0);
2655
}
2656
2657
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2658
if (status != GL_FRAMEBUFFER_COMPLETE) {
2659
glDeleteFramebuffers(1, &rt->fbo);
2660
if (rt->overridden.color.is_null()) {
2661
GLES3::Utilities::get_singleton()->texture_free_data(rt->color);
2662
}
2663
if (rt->overridden.depth.is_null()) {
2664
GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);
2665
}
2666
rt->fbo = 0;
2667
rt->size.x = 0;
2668
rt->size.y = 0;
2669
rt->color = 0;
2670
rt->depth = 0;
2671
if (rt->overridden.color.is_null()) {
2672
texture->tex_id = 0;
2673
texture->active = false;
2674
}
2675
WARN_PRINT("Could not create render target, status: " + get_framebuffer_error(status));
2676
return;
2677
}
2678
2679
texture->is_render_target = true;
2680
texture->render_target = rt;
2681
if (rt->overridden.color.is_null()) {
2682
texture->format = rt->image_format;
2683
texture->real_format = rt->image_format;
2684
texture->target = texture_target;
2685
if (rt->view_count > 1 && config->multiview_supported) {
2686
texture->type = Texture::TYPE_LAYERED;
2687
texture->layers = rt->view_count;
2688
} else {
2689
texture->type = Texture::TYPE_2D;
2690
texture->layers = 1;
2691
}
2692
texture->gl_format_cache = rt->color_format;
2693
texture->gl_type_cache = !rt->hdr ? GL_UNSIGNED_BYTE : GL_FLOAT; // to set HDR format size to 8 and keep 4 for LDR format
2694
texture->gl_internal_format_cache = rt->color_internal_format;
2695
texture->tex_id = rt->color;
2696
texture->width = rt->size.x;
2697
texture->alloc_width = rt->size.x;
2698
texture->height = rt->size.y;
2699
texture->alloc_height = rt->size.y;
2700
texture->active = true;
2701
}
2702
}
2703
2704
glClearColor(0, 0, 0, 0);
2705
glClear(GL_COLOR_BUFFER_BIT);
2706
glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
2707
}
2708
2709
void TextureStorage::_update_render_target_velocity(RenderTarget *rt) {
2710
GLuint new_velocity_fbo;
2711
glGenFramebuffers(1, &new_velocity_fbo);
2712
glBindFramebuffer(GL_FRAMEBUFFER, new_velocity_fbo);
2713
2714
uint32_t view_count = rt->view_count;
2715
GLuint texture_target = view_count > 1 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
2716
2717
GLuint velocity_texture_id = texture_get_texid(rt->overridden.velocity);
2718
glBindTexture(texture_target, velocity_texture_id);
2719
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2720
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2721
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2722
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2723
2724
#ifndef IOS_ENABLED
2725
if (view_count > 1) {
2726
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, velocity_texture_id, 0, 0, view_count);
2727
} else {
2728
#else
2729
{
2730
#endif
2731
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, velocity_texture_id, 0);
2732
}
2733
2734
GLuint velocity_depth_texture_id = texture_get_texid(rt->overridden.velocity_depth);
2735
glBindTexture(texture_target, velocity_depth_texture_id);
2736
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2737
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2738
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2739
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2740
2741
#ifndef IOS_ENABLED
2742
if (view_count > 1) {
2743
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, velocity_depth_texture_id, 0, 0, view_count);
2744
} else {
2745
#else
2746
{
2747
#endif
2748
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, velocity_depth_texture_id, 0);
2749
}
2750
2751
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2752
if (status != GL_FRAMEBUFFER_COMPLETE) {
2753
glDeleteFramebuffers(1, &new_velocity_fbo);
2754
WARN_PRINT(vformat("Could not create motion vector render target, status: %s.", GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status)));
2755
} else {
2756
rt->overridden.velocity_fbo = new_velocity_fbo;
2757
}
2758
2759
glBindTexture(texture_target, 0);
2760
glBindFramebuffer(GL_FRAMEBUFFER, 0);
2761
}
2762
2763
void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {
2764
ERR_FAIL_COND_MSG(rt->backbuffer_fbo != 0, "Cannot allocate RenderTarget backbuffer: already initialized.");
2765
ERR_FAIL_COND(rt->direct_to_screen);
2766
// Allocate mipmap chains for full screen blur
2767
// Limit mipmaps so smallest is 32x32 to avoid unnecessary framebuffer switches
2768
int count = MAX(1, Image::get_image_required_mipmaps(rt->size.x, rt->size.y, Image::FORMAT_RGBA8) - 4);
2769
if (rt->size.x > 40 && rt->size.y > 40) {
2770
GLsizei width = rt->size.x;
2771
GLsizei height = rt->size.y;
2772
2773
rt->mipmap_count = count;
2774
2775
glGenTextures(1, &rt->backbuffer);
2776
glBindTexture(GL_TEXTURE_2D, rt->backbuffer);
2777
uint32_t texture_size_bytes = 0;
2778
2779
for (int l = 0; l < count; l++) {
2780
texture_size_bytes += width * height * 4;
2781
glTexImage2D(GL_TEXTURE_2D, l, rt->color_internal_format, width, height, 0, rt->color_format, rt->color_type, nullptr);
2782
width = MAX(1, (width / 2));
2783
height = MAX(1, (height / 2));
2784
}
2785
2786
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2787
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1);
2788
2789
glGenFramebuffers(1, &rt->backbuffer_fbo);
2790
glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
2791
2792
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);
2793
2794
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
2795
if (status != GL_FRAMEBUFFER_COMPLETE) {
2796
WARN_PRINT_ONCE("Cannot allocate mipmaps for canvas screen blur. Status: " + get_framebuffer_error(status));
2797
glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
2798
return;
2799
}
2800
GLES3::Utilities::get_singleton()->texture_allocated_data(rt->backbuffer, texture_size_bytes, "Render target backbuffer color texture");
2801
2802
// Initialize all levels to clear black.
2803
for (int j = 0; j < count; j++) {
2804
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, j);
2805
glClearColor(0.0, 0.0, 0.0, 0.0);
2806
glClear(GL_COLOR_BUFFER_BIT);
2807
}
2808
2809
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);
2810
2811
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2812
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
2813
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2814
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2815
}
2816
}
2817
2818
void TextureStorage::_clear_render_target(RenderTarget *rt) {
2819
// there is nothing else to clear when DIRECT_TO_SCREEN is used
2820
if (rt->direct_to_screen) {
2821
return;
2822
}
2823
2824
for (KeyValue<uint32_t, GLuint> &E : rt->overridden.velocity_fbo_cache) {
2825
glDeleteFramebuffers(1, &E.value);
2826
}
2827
rt->overridden.velocity_fbo_cache.clear();
2828
rt->overridden.velocity_fbo = 0;
2829
2830
// Dispose of the cached fbo's and the allocated textures
2831
for (KeyValue<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry> &E : rt->overridden.fbo_cache) {
2832
glDeleteTextures(E.value.allocated_textures.size(), E.value.allocated_textures.ptr());
2833
// Don't delete the current FBO, we'll do that a couple lines down.
2834
if (E.value.fbo != rt->fbo) {
2835
glDeleteFramebuffers(1, &E.value.fbo);
2836
}
2837
}
2838
rt->overridden.fbo_cache.clear();
2839
2840
if (rt->fbo) {
2841
glDeleteFramebuffers(1, &rt->fbo);
2842
rt->fbo = 0;
2843
}
2844
2845
if (rt->overridden.color.is_null()) {
2846
if (rt->texture.is_valid()) {
2847
Texture *tex = get_texture(rt->texture);
2848
tex->alloc_height = 0;
2849
tex->alloc_width = 0;
2850
tex->width = 0;
2851
tex->height = 0;
2852
tex->active = false;
2853
tex->render_target = nullptr;
2854
tex->is_render_target = false;
2855
tex->gl_set_filter(RS::CANVAS_ITEM_TEXTURE_FILTER_MAX);
2856
tex->gl_set_repeat(RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX);
2857
}
2858
} else {
2859
Texture *tex = get_texture(rt->overridden.color);
2860
tex->render_target = nullptr;
2861
tex->is_render_target = false;
2862
}
2863
2864
if (rt->overridden.color.is_valid()) {
2865
rt->overridden.color = RID();
2866
} else if (rt->color) {
2867
GLES3::Utilities::get_singleton()->texture_free_data(rt->color);
2868
if (rt->texture.is_valid()) {
2869
Texture *tex = get_texture(rt->texture);
2870
tex->tex_id = 0;
2871
}
2872
}
2873
rt->color = 0;
2874
2875
if (rt->overridden.depth.is_valid()) {
2876
rt->overridden.depth = RID();
2877
} else if (rt->depth) {
2878
GLES3::Utilities::get_singleton()->texture_free_data(rt->depth);
2879
}
2880
rt->depth = 0;
2881
2882
rt->overridden.is_overridden = false;
2883
2884
if (rt->backbuffer_fbo != 0) {
2885
glDeleteFramebuffers(1, &rt->backbuffer_fbo);
2886
rt->backbuffer_fbo = 0;
2887
}
2888
if (rt->backbuffer != 0) {
2889
GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer);
2890
rt->backbuffer = 0;
2891
}
2892
if (rt->backbuffer_depth != 0) {
2893
GLES3::Utilities::get_singleton()->texture_free_data(rt->backbuffer_depth);
2894
rt->backbuffer_depth = 0;
2895
}
2896
_render_target_clear_sdf(rt);
2897
}
2898
2899
RID TextureStorage::render_target_create() {
2900
RenderTarget render_target;
2901
render_target.used_in_frame = false;
2902
render_target.clear_requested = false;
2903
2904
Texture t;
2905
t.active = true;
2906
t.render_target = &render_target;
2907
t.is_render_target = true;
2908
2909
render_target.texture = texture_owner.make_rid(t);
2910
_update_render_target_color(&render_target);
2911
return render_target_owner.make_rid(render_target);
2912
}
2913
2914
void TextureStorage::render_target_free(RID p_rid) {
2915
RenderTarget *rt = render_target_owner.get_or_null(p_rid);
2916
_clear_render_target(rt);
2917
2918
Texture *t = get_texture(rt->texture);
2919
if (t) {
2920
t->is_render_target = false;
2921
if (rt->overridden.color.is_null()) {
2922
texture_free(rt->texture);
2923
}
2924
//memdelete(t);
2925
}
2926
render_target_owner.free(p_rid);
2927
}
2928
2929
void TextureStorage::render_target_set_position(RID p_render_target, int p_x, int p_y) {
2930
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2931
ERR_FAIL_NULL(rt);
2932
2933
rt->position = Point2i(p_x, p_y);
2934
}
2935
2936
Point2i TextureStorage::render_target_get_position(RID p_render_target) const {
2937
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2938
ERR_FAIL_NULL_V(rt, Point2i());
2939
2940
return rt->position;
2941
}
2942
2943
void TextureStorage::render_target_set_size(RID p_render_target, int p_width, int p_height, uint32_t p_view_count) {
2944
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2945
ERR_FAIL_NULL(rt);
2946
2947
if (p_width == rt->size.x && p_height == rt->size.y && p_view_count == rt->view_count) {
2948
return;
2949
}
2950
if (rt->overridden.color.is_valid()) {
2951
return;
2952
}
2953
2954
_clear_render_target(rt);
2955
2956
rt->size = Size2i(p_width, p_height);
2957
rt->view_count = p_view_count;
2958
2959
_update_render_target_color(rt);
2960
}
2961
2962
// TODO: convert to Size2i internally
2963
Size2i TextureStorage::render_target_get_size(RID p_render_target) const {
2964
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2965
ERR_FAIL_NULL_V(rt, Size2i());
2966
2967
return rt->size;
2968
}
2969
2970
void 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) {
2971
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
2972
ERR_FAIL_NULL(rt);
2973
ERR_FAIL_COND(rt->direct_to_screen);
2974
2975
// Remember what our current color output is.
2976
RID was_color_texture = render_target_get_texture(p_render_target);
2977
2978
bool create_new_color_fbo = true;
2979
bool create_new_velocity_fbo = true;
2980
2981
if (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) {
2982
return;
2983
}
2984
2985
if (p_color_texture.is_null() && p_depth_texture.is_null()) {
2986
// Set this back to our default textures.
2987
if (was_color_texture.is_valid()) {
2988
texture_remap_proxies(was_color_texture, rt->texture);
2989
}
2990
2991
_clear_render_target(rt);
2992
_update_render_target_color(rt);
2993
create_new_color_fbo = false;
2994
}
2995
2996
if (!rt->overridden.is_overridden) {
2997
_clear_render_target(rt);
2998
}
2999
3000
rt->overridden.color = p_color_texture;
3001
rt->overridden.depth = p_depth_texture;
3002
rt->overridden.depth_has_stencil = p_depth_texture.is_null();
3003
rt->overridden.velocity = p_velocity_texture;
3004
rt->overridden.velocity_depth = p_velocity_depth_texture;
3005
rt->overridden.is_overridden = true;
3006
3007
// Update to our new color output.
3008
RID new_color_texture = render_target_get_texture(p_render_target);
3009
if (was_color_texture.is_valid() && new_color_texture.is_valid()) {
3010
texture_remap_proxies(was_color_texture, new_color_texture);
3011
}
3012
3013
uint32_t hash_key = hash_murmur3_one_64(p_color_texture.get_id());
3014
hash_key = hash_murmur3_one_64(p_depth_texture.get_id(), hash_key);
3015
hash_key = hash_fmix32(hash_key);
3016
3017
RBMap<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry>::Element *cache;
3018
if ((cache = rt->overridden.fbo_cache.find(hash_key)) != nullptr) {
3019
rt->fbo = cache->get().fbo;
3020
rt->color = cache->get().color;
3021
rt->depth = cache->get().depth;
3022
rt->depth_has_stencil = cache->get().depth_has_stencil;
3023
rt->size = cache->get().size;
3024
rt->texture = p_color_texture;
3025
create_new_color_fbo = false;
3026
}
3027
3028
uint32_t velocity_hash_key = hash_murmur3_one_64(p_velocity_texture.get_id());
3029
velocity_hash_key = hash_murmur3_one_64(p_velocity_depth_texture.get_id(), velocity_hash_key);
3030
velocity_hash_key = hash_fmix32(velocity_hash_key);
3031
3032
RBMap<uint32_t, GLuint>::Element *fbo = rt->overridden.velocity_fbo_cache.find(velocity_hash_key);
3033
if (fbo != nullptr) {
3034
rt->overridden.velocity_fbo = fbo->get();
3035
create_new_velocity_fbo = false;
3036
}
3037
3038
if (p_velocity_texture.is_null()) {
3039
for (KeyValue<uint32_t, GLuint> &E : rt->overridden.velocity_fbo_cache) {
3040
glDeleteFramebuffers(1, &E.value);
3041
}
3042
3043
rt->overridden.velocity_fbo_cache.clear();
3044
rt->overridden.velocity_fbo = 0;
3045
create_new_velocity_fbo = false;
3046
}
3047
3048
if (create_new_color_fbo) {
3049
_update_render_target_color(rt);
3050
3051
RenderTarget::RTOverridden::FBOCacheEntry new_entry;
3052
new_entry.fbo = rt->fbo;
3053
new_entry.color = rt->color;
3054
new_entry.depth = rt->depth;
3055
new_entry.size = rt->size;
3056
// Keep track of any textures we had to allocate because they weren't overridden.
3057
if (p_color_texture.is_null()) {
3058
new_entry.allocated_textures.push_back(rt->color);
3059
}
3060
if (p_depth_texture.is_null()) {
3061
new_entry.allocated_textures.push_back(rt->depth);
3062
}
3063
rt->overridden.fbo_cache.insert(hash_key, new_entry);
3064
}
3065
3066
if (create_new_velocity_fbo) {
3067
_update_render_target_velocity(rt);
3068
rt->overridden.velocity_fbo_cache.insert(velocity_hash_key, rt->overridden.velocity_fbo);
3069
}
3070
}
3071
3072
RID TextureStorage::render_target_get_override_color(RID p_render_target) const {
3073
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3074
ERR_FAIL_NULL_V(rt, RID());
3075
3076
return rt->overridden.color;
3077
}
3078
3079
RID TextureStorage::render_target_get_override_depth(RID p_render_target) const {
3080
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3081
ERR_FAIL_NULL_V(rt, RID());
3082
3083
return rt->overridden.depth;
3084
}
3085
3086
RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const {
3087
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3088
ERR_FAIL_NULL_V(rt, RID());
3089
3090
return rt->overridden.velocity;
3091
}
3092
3093
RID TextureStorage::render_target_get_override_velocity_depth(RID p_render_target) const {
3094
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3095
ERR_FAIL_NULL_V(rt, RID());
3096
3097
return rt->overridden.velocity_depth;
3098
}
3099
3100
void TextureStorage::render_target_set_render_region(RID p_render_target, const Rect2i &p_render_region) {
3101
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3102
ERR_FAIL_NULL(rt);
3103
3104
rt->render_region = p_render_region;
3105
}
3106
3107
Rect2i TextureStorage::render_target_get_render_region(RID p_render_target) const {
3108
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3109
ERR_FAIL_NULL_V(rt, Rect2i());
3110
3111
return rt->render_region;
3112
}
3113
3114
RID TextureStorage::render_target_get_texture(RID p_render_target) {
3115
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3116
ERR_FAIL_NULL_V(rt, RID());
3117
3118
if (rt->overridden.color.is_valid()) {
3119
return rt->overridden.color;
3120
}
3121
3122
return rt->texture;
3123
}
3124
3125
void TextureStorage::render_target_set_velocity_target_size(RID p_render_target, const Size2i &p_target_size) {
3126
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3127
ERR_FAIL_NULL(rt);
3128
3129
rt->velocity_target_size = p_target_size;
3130
}
3131
3132
Size2i TextureStorage::render_target_get_velocity_target_size(RID p_render_target) const {
3133
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3134
ERR_FAIL_NULL_V(rt, Size2i(0, 0));
3135
3136
return rt->velocity_target_size;
3137
}
3138
3139
void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_transparent) {
3140
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3141
ERR_FAIL_NULL(rt);
3142
3143
rt->is_transparent = p_transparent;
3144
3145
if (rt->overridden.color.is_null()) {
3146
_clear_render_target(rt);
3147
_update_render_target_color(rt);
3148
}
3149
}
3150
3151
bool TextureStorage::render_target_get_transparent(RID p_render_target) const {
3152
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3153
ERR_FAIL_NULL_V(rt, false);
3154
3155
return rt->is_transparent;
3156
}
3157
3158
void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, bool p_direct_to_screen) {
3159
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3160
ERR_FAIL_NULL(rt);
3161
3162
if (p_direct_to_screen == rt->direct_to_screen) {
3163
return;
3164
}
3165
// When setting DIRECT_TO_SCREEN, you need to clear before the value is set, but allocate after as
3166
// those functions change how they operate depending on the value of DIRECT_TO_SCREEN
3167
_clear_render_target(rt);
3168
rt->direct_to_screen = p_direct_to_screen;
3169
if (rt->direct_to_screen) {
3170
rt->overridden.color = RID();
3171
rt->overridden.depth = RID();
3172
rt->overridden.velocity = RID();
3173
rt->overridden.velocity_depth = RID();
3174
}
3175
_update_render_target_color(rt);
3176
}
3177
3178
bool TextureStorage::render_target_get_direct_to_screen(RID p_render_target) const {
3179
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3180
ERR_FAIL_NULL_V(rt, false);
3181
3182
return rt->direct_to_screen;
3183
}
3184
3185
bool TextureStorage::render_target_was_used(RID p_render_target) const {
3186
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3187
ERR_FAIL_NULL_V(rt, false);
3188
3189
return rt->used_in_frame;
3190
}
3191
3192
void TextureStorage::render_target_clear_used(RID p_render_target) {
3193
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3194
ERR_FAIL_NULL(rt);
3195
3196
rt->used_in_frame = false;
3197
}
3198
3199
void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSAA p_msaa) {
3200
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3201
ERR_FAIL_NULL(rt);
3202
ERR_FAIL_COND(rt->direct_to_screen);
3203
if (p_msaa == rt->msaa) {
3204
return;
3205
}
3206
3207
WARN_PRINT("2D MSAA is not yet supported for GLES3.");
3208
3209
if (rt->overridden.color.is_null()) {
3210
_clear_render_target(rt);
3211
rt->msaa = p_msaa;
3212
_update_render_target_color(rt);
3213
}
3214
}
3215
3216
RS::ViewportMSAA TextureStorage::render_target_get_msaa(RID p_render_target) const {
3217
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3218
ERR_FAIL_NULL_V(rt, RS::VIEWPORT_MSAA_DISABLED);
3219
3220
return rt->msaa;
3221
}
3222
3223
void TextureStorage::render_target_set_use_hdr(RID p_render_target, bool p_use_hdr_2d) {
3224
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3225
ERR_FAIL_NULL(rt);
3226
ERR_FAIL_COND(rt->direct_to_screen);
3227
if (p_use_hdr_2d == rt->hdr) {
3228
return;
3229
}
3230
3231
if (rt->overridden.color.is_null()) {
3232
_clear_render_target(rt);
3233
rt->hdr = p_use_hdr_2d;
3234
_update_render_target_color(rt);
3235
}
3236
}
3237
3238
bool TextureStorage::render_target_is_using_hdr(RID p_render_target) const {
3239
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3240
ERR_FAIL_NULL_V(rt, false);
3241
3242
return rt->hdr;
3243
}
3244
3245
GLuint TextureStorage::render_target_get_color_internal_format(RID p_render_target) const {
3246
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3247
ERR_FAIL_NULL_V(rt, GL_RGBA8);
3248
3249
return rt->color_internal_format;
3250
}
3251
3252
GLuint TextureStorage::render_target_get_color_format(RID p_render_target) const {
3253
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3254
ERR_FAIL_NULL_V(rt, GL_RGBA);
3255
3256
return rt->color_format;
3257
}
3258
3259
GLuint TextureStorage::render_target_get_color_type(RID p_render_target) const {
3260
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3261
ERR_FAIL_NULL_V(rt, GL_UNSIGNED_BYTE);
3262
3263
return rt->color_type;
3264
}
3265
3266
uint32_t TextureStorage::render_target_get_color_format_size(RID p_render_target) const {
3267
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3268
ERR_FAIL_NULL_V(rt, 4);
3269
3270
return rt->color_format_size;
3271
}
3272
3273
void TextureStorage::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
3274
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3275
ERR_FAIL_NULL(rt);
3276
rt->clear_requested = true;
3277
rt->clear_color = p_clear_color;
3278
}
3279
3280
bool TextureStorage::render_target_is_clear_requested(RID p_render_target) {
3281
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3282
ERR_FAIL_NULL_V(rt, false);
3283
return rt->clear_requested;
3284
}
3285
Color TextureStorage::render_target_get_clear_request_color(RID p_render_target) {
3286
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3287
ERR_FAIL_NULL_V(rt, Color());
3288
return rt->clear_color;
3289
}
3290
3291
void TextureStorage::render_target_disable_clear_request(RID p_render_target) {
3292
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3293
ERR_FAIL_NULL(rt);
3294
rt->clear_requested = false;
3295
}
3296
3297
void TextureStorage::render_target_do_clear_request(RID p_render_target) {
3298
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3299
ERR_FAIL_NULL(rt);
3300
if (!rt->clear_requested) {
3301
return;
3302
}
3303
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
3304
3305
glClearBufferfv(GL_COLOR, 0, rt->clear_color.components);
3306
rt->clear_requested = false;
3307
glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
3308
}
3309
3310
GLuint TextureStorage::render_target_get_fbo(RID p_render_target) const {
3311
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3312
ERR_FAIL_NULL_V(rt, 0);
3313
3314
return rt->fbo;
3315
}
3316
3317
GLuint TextureStorage::render_target_get_color(RID p_render_target) const {
3318
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3319
ERR_FAIL_NULL_V(rt, 0);
3320
3321
if (rt->overridden.color.is_valid()) {
3322
Texture *texture = get_texture(rt->overridden.color);
3323
ERR_FAIL_NULL_V(texture, 0);
3324
3325
return texture->tex_id;
3326
} else {
3327
return rt->color;
3328
}
3329
}
3330
3331
GLuint TextureStorage::render_target_get_depth(RID p_render_target) const {
3332
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3333
ERR_FAIL_NULL_V(rt, 0);
3334
3335
if (rt->overridden.depth.is_valid()) {
3336
Texture *texture = get_texture(rt->overridden.depth);
3337
ERR_FAIL_NULL_V(texture, 0);
3338
3339
return texture->tex_id;
3340
} else {
3341
return rt->depth;
3342
}
3343
}
3344
3345
bool TextureStorage::render_target_get_depth_has_stencil(RID p_render_target) const {
3346
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3347
ERR_FAIL_NULL_V(rt, 0);
3348
3349
return rt->depth_has_stencil;
3350
}
3351
3352
void TextureStorage::render_target_set_reattach_textures(RID p_render_target, bool p_reattach_textures) const {
3353
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3354
ERR_FAIL_NULL(rt);
3355
3356
rt->reattach_textures = p_reattach_textures;
3357
}
3358
3359
bool TextureStorage::render_target_is_reattach_textures(RID p_render_target) const {
3360
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3361
ERR_FAIL_NULL_V(rt, false);
3362
3363
return rt->reattach_textures;
3364
}
3365
3366
void TextureStorage::render_target_set_sdf_size_and_scale(RID p_render_target, RS::ViewportSDFOversize p_size, RS::ViewportSDFScale p_scale) {
3367
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3368
ERR_FAIL_NULL(rt);
3369
if (rt->sdf_oversize == p_size && rt->sdf_scale == p_scale) {
3370
return;
3371
}
3372
3373
rt->sdf_oversize = p_size;
3374
rt->sdf_scale = p_scale;
3375
3376
_render_target_clear_sdf(rt);
3377
}
3378
3379
Rect2i TextureStorage::_render_target_get_sdf_rect(const RenderTarget *rt) const {
3380
Size2i margin;
3381
int scale;
3382
switch (rt->sdf_oversize) {
3383
case RS::VIEWPORT_SDF_OVERSIZE_100_PERCENT: {
3384
scale = 100;
3385
} break;
3386
case RS::VIEWPORT_SDF_OVERSIZE_120_PERCENT: {
3387
scale = 120;
3388
} break;
3389
case RS::VIEWPORT_SDF_OVERSIZE_150_PERCENT: {
3390
scale = 150;
3391
} break;
3392
case RS::VIEWPORT_SDF_OVERSIZE_200_PERCENT: {
3393
scale = 200;
3394
} break;
3395
default: {
3396
ERR_PRINT("Invalid viewport SDF oversize, defaulting to 100%.");
3397
scale = 100;
3398
} break;
3399
}
3400
3401
margin = (rt->size * scale / 100) - rt->size;
3402
3403
Rect2i r(Vector2i(), rt->size);
3404
r.position -= margin;
3405
r.size += margin * 2;
3406
3407
return r;
3408
}
3409
3410
Rect2i TextureStorage::render_target_get_sdf_rect(RID p_render_target) const {
3411
const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3412
ERR_FAIL_NULL_V(rt, Rect2i());
3413
3414
return _render_target_get_sdf_rect(rt);
3415
}
3416
3417
void TextureStorage::render_target_mark_sdf_enabled(RID p_render_target, bool p_enabled) {
3418
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3419
ERR_FAIL_NULL(rt);
3420
3421
rt->sdf_enabled = p_enabled;
3422
}
3423
3424
bool TextureStorage::render_target_is_sdf_enabled(RID p_render_target) const {
3425
const RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3426
ERR_FAIL_NULL_V(rt, false);
3427
3428
return rt->sdf_enabled;
3429
}
3430
3431
GLuint TextureStorage::render_target_get_sdf_texture(RID p_render_target) {
3432
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3433
ERR_FAIL_NULL_V(rt, 0);
3434
if (rt->sdf_texture_read == 0) {
3435
Texture *texture = texture_owner.get_or_null(default_gl_textures[DEFAULT_GL_TEXTURE_BLACK]);
3436
return texture->tex_id;
3437
}
3438
3439
return rt->sdf_texture_read;
3440
}
3441
3442
void TextureStorage::_render_target_allocate_sdf(RenderTarget *rt) {
3443
ERR_FAIL_COND(rt->sdf_texture_write_fb != 0);
3444
3445
Size2i size = _render_target_get_sdf_rect(rt).size;
3446
3447
glGenTextures(1, &rt->sdf_texture_write);
3448
glActiveTexture(GL_TEXTURE0);
3449
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);
3450
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, size.width, size.height, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
3451
GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_write, size.width * size.height, "SDF texture");
3452
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3453
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3454
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3455
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
3456
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3457
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3458
3459
glGenFramebuffers(1, &rt->sdf_texture_write_fb);
3460
glBindFramebuffer(GL_FRAMEBUFFER, rt->sdf_texture_write_fb);
3461
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_write, 0);
3462
3463
int scale;
3464
switch (rt->sdf_scale) {
3465
case RS::VIEWPORT_SDF_SCALE_100_PERCENT: {
3466
scale = 100;
3467
} break;
3468
case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
3469
scale = 50;
3470
} break;
3471
case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
3472
scale = 25;
3473
} break;
3474
default: {
3475
ERR_PRINT("Invalid viewport SDF scale, defaulting to 100%.");
3476
scale = 100;
3477
} break;
3478
}
3479
3480
rt->process_size = size * scale / 100;
3481
rt->process_size = rt->process_size.maxi(1);
3482
3483
glGenTextures(2, rt->sdf_texture_process);
3484
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[0]);
3485
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);
3486
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3487
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3488
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3489
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
3490
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3491
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3492
GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[0], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[0]");
3493
3494
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[1]);
3495
glTexImage2D(GL_TEXTURE_2D, 0, GL_RG16I, rt->process_size.width, rt->process_size.height, 0, GL_RG_INTEGER, GL_SHORT, nullptr);
3496
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3497
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3498
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3499
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
3500
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3501
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3502
GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_process[1], rt->process_size.width * rt->process_size.height * 4, "SDF process texture[1]");
3503
3504
glGenTextures(1, &rt->sdf_texture_read);
3505
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_read);
3506
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->process_size.width, rt->process_size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3507
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3508
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3509
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
3510
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
3511
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3512
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3513
GLES3::Utilities::get_singleton()->texture_allocated_data(rt->sdf_texture_read, rt->process_size.width * rt->process_size.height * 4, "SDF texture (read)");
3514
}
3515
3516
void TextureStorage::_render_target_clear_sdf(RenderTarget *rt) {
3517
if (rt->sdf_texture_write_fb != 0) {
3518
GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_read);
3519
GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_write);
3520
GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[0]);
3521
GLES3::Utilities::get_singleton()->texture_free_data(rt->sdf_texture_process[1]);
3522
3523
glDeleteFramebuffers(1, &rt->sdf_texture_write_fb);
3524
rt->sdf_texture_read = 0;
3525
rt->sdf_texture_write = 0;
3526
rt->sdf_texture_process[0] = 0;
3527
rt->sdf_texture_process[1] = 0;
3528
rt->sdf_texture_write_fb = 0;
3529
}
3530
}
3531
3532
GLuint TextureStorage::render_target_get_sdf_framebuffer(RID p_render_target) {
3533
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3534
ERR_FAIL_NULL_V(rt, 0);
3535
3536
if (rt->sdf_texture_write_fb == 0) {
3537
_render_target_allocate_sdf(rt);
3538
}
3539
3540
return rt->sdf_texture_write_fb;
3541
}
3542
void TextureStorage::render_target_sdf_process(RID p_render_target) {
3543
CopyEffects *copy_effects = CopyEffects::get_singleton();
3544
3545
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3546
ERR_FAIL_NULL(rt);
3547
ERR_FAIL_COND(rt->sdf_texture_write_fb == 0);
3548
3549
Rect2i r = _render_target_get_sdf_rect(rt);
3550
3551
Size2i size = r.size;
3552
int32_t shift = 0;
3553
3554
bool shrink = false;
3555
3556
switch (rt->sdf_scale) {
3557
case RS::VIEWPORT_SDF_SCALE_50_PERCENT: {
3558
size[0] >>= 1;
3559
size[1] >>= 1;
3560
shift = 1;
3561
shrink = true;
3562
} break;
3563
case RS::VIEWPORT_SDF_SCALE_25_PERCENT: {
3564
size[0] >>= 2;
3565
size[1] >>= 2;
3566
shift = 2;
3567
shrink = true;
3568
} break;
3569
default: {
3570
};
3571
}
3572
3573
GLuint temp_fb;
3574
glGenFramebuffers(1, &temp_fb);
3575
glBindFramebuffer(GL_FRAMEBUFFER, temp_fb);
3576
3577
// Load
3578
CanvasSdfShaderGLES3::ShaderVariant variant = shrink ? CanvasSdfShaderGLES3::MODE_LOAD_SHRINK : CanvasSdfShaderGLES3::MODE_LOAD;
3579
bool success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);
3580
if (!success) {
3581
return;
3582
}
3583
3584
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);
3585
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);
3586
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, 0, sdf_shader.shader_version, variant);
3587
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);
3588
3589
glActiveTexture(GL_TEXTURE0);
3590
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_write);
3591
3592
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_process[0], 0);
3593
glViewport(0, 0, size.width, size.height);
3594
glEnable(GL_SCISSOR_TEST);
3595
glScissor(0, 0, size.width, size.height);
3596
3597
copy_effects->draw_screen_triangle();
3598
3599
// Process
3600
3601
int stride = nearest_power_of_2_templated(MAX(size.width, size.height) / 2);
3602
3603
variant = CanvasSdfShaderGLES3::MODE_PROCESS;
3604
success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);
3605
if (!success) {
3606
return;
3607
}
3608
3609
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);
3610
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);
3611
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);
3612
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);
3613
3614
bool swap = false;
3615
3616
//jumpflood
3617
while (stride > 0) {
3618
glBindTexture(GL_TEXTURE_2D, 0);
3619
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 0 : 1], 0);
3620
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 1 : 0]);
3621
3622
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);
3623
3624
copy_effects->draw_screen_triangle();
3625
3626
stride /= 2;
3627
swap = !swap;
3628
}
3629
3630
// Store
3631
variant = shrink ? CanvasSdfShaderGLES3::MODE_STORE_SHRINK : CanvasSdfShaderGLES3::MODE_STORE;
3632
success = sdf_shader.shader.version_bind_shader(sdf_shader.shader_version, variant);
3633
if (!success) {
3634
return;
3635
}
3636
3637
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::BASE_SIZE, r.size, sdf_shader.shader_version, variant);
3638
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SIZE, size, sdf_shader.shader_version, variant);
3639
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::STRIDE, stride, sdf_shader.shader_version, variant);
3640
sdf_shader.shader.version_set_uniform(CanvasSdfShaderGLES3::SHIFT, shift, sdf_shader.shader_version, variant);
3641
3642
glBindTexture(GL_TEXTURE_2D, 0);
3643
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->sdf_texture_read, 0);
3644
glBindTexture(GL_TEXTURE_2D, rt->sdf_texture_process[swap ? 1 : 0]);
3645
3646
copy_effects->draw_screen_triangle();
3647
3648
glBindTexture(GL_TEXTURE_2D, 0);
3649
glBindFramebuffer(GL_FRAMEBUFFER, system_fbo);
3650
glDeleteFramebuffers(1, &temp_fb);
3651
glDisable(GL_SCISSOR_TEST);
3652
}
3653
3654
void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) {
3655
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3656
ERR_FAIL_NULL(rt);
3657
ERR_FAIL_COND(rt->direct_to_screen);
3658
3659
if (rt->backbuffer_fbo == 0) {
3660
_create_render_target_backbuffer(rt);
3661
}
3662
3663
Rect2i region;
3664
if (p_region == Rect2i()) {
3665
region.size = rt->size;
3666
} else {
3667
region = Rect2i(Size2i(), rt->size).intersection(p_region);
3668
if (region.size == Size2i()) {
3669
return; //nothing to do
3670
}
3671
}
3672
3673
glDisable(GL_BLEND);
3674
// Single texture copy for backbuffer.
3675
glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
3676
glActiveTexture(GL_TEXTURE0);
3677
glBindTexture(GL_TEXTURE_2D, rt->color);
3678
Rect2 normalized_region = region;
3679
normalized_region.position = normalized_region.position / Size2(rt->size);
3680
normalized_region.size = normalized_region.size / Size2(rt->size);
3681
GLES3::CopyEffects::get_singleton()->copy_to_and_from_rect(normalized_region);
3682
3683
if (p_gen_mipmaps) {
3684
GLES3::CopyEffects::get_singleton()->gaussian_blur(rt->backbuffer, rt->mipmap_count, region, rt->size);
3685
glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
3686
}
3687
3688
glEnable(GL_BLEND); // 2D starts with blend enabled.
3689
}
3690
3691
void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const Rect2i &p_region, const Color &p_color) {
3692
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3693
ERR_FAIL_NULL(rt);
3694
ERR_FAIL_COND(rt->direct_to_screen);
3695
3696
if (rt->backbuffer_fbo == 0) {
3697
_create_render_target_backbuffer(rt);
3698
}
3699
3700
Rect2i region;
3701
if (p_region == Rect2i()) {
3702
// Just do a full screen clear;
3703
glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
3704
glClearColor(p_color.r, p_color.g, p_color.b, p_color.a);
3705
glClear(GL_COLOR_BUFFER_BIT);
3706
} else {
3707
region = Rect2i(Size2i(), rt->size).intersection(p_region);
3708
if (region.size == Size2i()) {
3709
return; //nothing to do
3710
}
3711
glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
3712
GLES3::CopyEffects::get_singleton()->set_color(p_color, region);
3713
}
3714
}
3715
3716
void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) {
3717
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
3718
ERR_FAIL_NULL(rt);
3719
3720
if (rt->backbuffer_fbo == 0) {
3721
_create_render_target_backbuffer(rt);
3722
}
3723
3724
Rect2i region;
3725
if (p_region == Rect2i()) {
3726
region.size = rt->size;
3727
} else {
3728
region = Rect2i(Size2i(), rt->size).intersection(p_region);
3729
if (region.size == Size2i()) {
3730
return; //nothing to do
3731
}
3732
}
3733
glDisable(GL_BLEND);
3734
GLES3::CopyEffects::get_singleton()->gaussian_blur(rt->backbuffer, rt->mipmap_count, region, rt->size);
3735
glEnable(GL_BLEND); // 2D starts with blend enabled.
3736
3737
glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
3738
}
3739
3740
#endif // GLES3_ENABLED
3741
3742