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