Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/drivers/gles3/rasterizer_canvas_gles3.cpp
9973 views
1
/**************************************************************************/
2
/* rasterizer_canvas_gles3.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
#include "rasterizer_canvas_gles3.h"
32
33
#ifdef GLES3_ENABLED
34
35
#include "rasterizer_gles3.h"
36
#include "rasterizer_scene_gles3.h"
37
38
#include "core/config/project_settings.h"
39
#include "core/math/geometry_2d.h"
40
#include "core/math/transform_interpolator.h"
41
#include "servers/rendering/rendering_server_default.h"
42
#include "storage/config.h"
43
#include "storage/material_storage.h"
44
#include "storage/mesh_storage.h"
45
#include "storage/particles_storage.h"
46
#include "storage/texture_storage.h"
47
48
void RasterizerCanvasGLES3::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
49
p_mat4[0] = p_transform.columns[0][0];
50
p_mat4[1] = p_transform.columns[0][1];
51
p_mat4[2] = 0;
52
p_mat4[3] = 0;
53
p_mat4[4] = p_transform.columns[1][0];
54
p_mat4[5] = p_transform.columns[1][1];
55
p_mat4[6] = 0;
56
p_mat4[7] = 0;
57
p_mat4[8] = 0;
58
p_mat4[9] = 0;
59
p_mat4[10] = 1;
60
p_mat4[11] = 0;
61
p_mat4[12] = p_transform.columns[2][0];
62
p_mat4[13] = p_transform.columns[2][1];
63
p_mat4[14] = 0;
64
p_mat4[15] = 1;
65
}
66
67
void RasterizerCanvasGLES3::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) {
68
p_mat2x4[0] = p_transform.columns[0][0];
69
p_mat2x4[1] = p_transform.columns[1][0];
70
p_mat2x4[2] = 0;
71
p_mat2x4[3] = p_transform.columns[2][0];
72
73
p_mat2x4[4] = p_transform.columns[0][1];
74
p_mat2x4[5] = p_transform.columns[1][1];
75
p_mat2x4[6] = 0;
76
p_mat2x4[7] = p_transform.columns[2][1];
77
}
78
79
void RasterizerCanvasGLES3::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) {
80
p_mat2x3[0] = p_transform.columns[0][0];
81
p_mat2x3[1] = p_transform.columns[0][1];
82
p_mat2x3[2] = p_transform.columns[1][0];
83
p_mat2x3[3] = p_transform.columns[1][1];
84
p_mat2x3[4] = p_transform.columns[2][0];
85
p_mat2x3[5] = p_transform.columns[2][1];
86
}
87
88
void RasterizerCanvasGLES3::_update_transform_to_mat4(const Transform3D &p_transform, float *p_mat4) {
89
p_mat4[0] = p_transform.basis.rows[0][0];
90
p_mat4[1] = p_transform.basis.rows[1][0];
91
p_mat4[2] = p_transform.basis.rows[2][0];
92
p_mat4[3] = 0;
93
p_mat4[4] = p_transform.basis.rows[0][1];
94
p_mat4[5] = p_transform.basis.rows[1][1];
95
p_mat4[6] = p_transform.basis.rows[2][1];
96
p_mat4[7] = 0;
97
p_mat4[8] = p_transform.basis.rows[0][2];
98
p_mat4[9] = p_transform.basis.rows[1][2];
99
p_mat4[10] = p_transform.basis.rows[2][2];
100
p_mat4[11] = 0;
101
p_mat4[12] = p_transform.origin.x;
102
p_mat4[13] = p_transform.origin.y;
103
p_mat4[14] = p_transform.origin.z;
104
p_mat4[15] = 1;
105
}
106
107
void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, Light *p_directional_light_list, const Transform2D &p_canvas_transform, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, bool &r_sdf_used, RenderingMethod::RenderInfo *r_render_info) {
108
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
109
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
110
GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();
111
112
Transform2D canvas_transform_inverse = p_canvas_transform.affine_inverse();
113
114
// Clear out any state that may have been left from the 3D pass.
115
reset_canvas();
116
117
if (state.canvas_instance_data_buffers[state.current_data_buffer_index].fence != GLsync()) {
118
GLint syncStatus;
119
glGetSynciv(state.canvas_instance_data_buffers[state.current_data_buffer_index].fence, GL_SYNC_STATUS, 1, nullptr, &syncStatus);
120
if (syncStatus == GL_UNSIGNALED) {
121
// If older than 2 frames, wait for sync OpenGL can have up to 3 frames in flight, any more and we need to sync anyway.
122
if (state.canvas_instance_data_buffers[state.current_data_buffer_index].last_frame_used < RSG::rasterizer->get_frame_number() - 2) {
123
#ifndef WEB_ENABLED
124
// On web, we do nothing as the glSubBufferData will force a sync anyway and WebGL does not like waiting.
125
glClientWaitSync(state.canvas_instance_data_buffers[state.current_data_buffer_index].fence, 0, 100000000); // wait for up to 100ms
126
#endif
127
state.canvas_instance_data_buffers[state.current_data_buffer_index].last_frame_used = RSG::rasterizer->get_frame_number();
128
glDeleteSync(state.canvas_instance_data_buffers[state.current_data_buffer_index].fence);
129
state.canvas_instance_data_buffers[state.current_data_buffer_index].fence = GLsync();
130
} else {
131
// Used in last frame or frame before that. OpenGL can get up to two frames behind, so these buffers may still be in use
132
// Allocate a new buffer and use that.
133
_allocate_instance_data_buffer();
134
}
135
} else {
136
// Already finished all rendering commands, we can use it.
137
state.canvas_instance_data_buffers[state.current_data_buffer_index].last_frame_used = RSG::rasterizer->get_frame_number();
138
glDeleteSync(state.canvas_instance_data_buffers[state.current_data_buffer_index].fence);
139
state.canvas_instance_data_buffers[state.current_data_buffer_index].fence = GLsync();
140
}
141
}
142
143
//setup directional lights if exist
144
145
uint32_t light_count = 0;
146
uint32_t directional_light_count = 0;
147
{
148
Light *l = p_directional_light_list;
149
uint32_t index = 0;
150
151
while (l) {
152
if (index == data.max_lights_per_render) {
153
l->render_index_cache = -1;
154
l = l->next_ptr;
155
continue;
156
}
157
158
CanvasLight *clight = canvas_light_owner.get_or_null(l->light_internal);
159
if (!clight) { //unused or invalid texture
160
l->render_index_cache = -1;
161
l = l->next_ptr;
162
ERR_CONTINUE(!clight);
163
}
164
165
Vector2 canvas_light_dir = l->xform_cache.columns[1].normalized();
166
167
state.light_uniforms[index].position[0] = -canvas_light_dir.x;
168
state.light_uniforms[index].position[1] = -canvas_light_dir.y;
169
170
_update_transform_2d_to_mat2x4(clight->shadow.directional_xform, state.light_uniforms[index].shadow_matrix);
171
172
state.light_uniforms[index].height = l->height; //0..1 here
173
174
for (int i = 0; i < 4; i++) {
175
state.light_uniforms[index].shadow_color[i] = uint8_t(CLAMP(int32_t(l->shadow_color[i] * 255.0), 0, 255));
176
state.light_uniforms[index].color[i] = l->color[i];
177
}
178
179
state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate
180
181
if (state.shadow_fb != 0) {
182
state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth);
183
state.light_uniforms[index].shadow_z_far_inv = 1.0 / clight->shadow.z_far;
184
state.light_uniforms[index].shadow_y_ofs = clight->shadow.y_offset;
185
} else {
186
state.light_uniforms[index].shadow_pixel_size = 1.0;
187
state.light_uniforms[index].shadow_z_far_inv = 1.0;
188
state.light_uniforms[index].shadow_y_ofs = 0;
189
}
190
191
state.light_uniforms[index].flags = l->blend_mode << LIGHT_FLAGS_BLEND_SHIFT;
192
state.light_uniforms[index].flags |= l->shadow_filter << LIGHT_FLAGS_FILTER_SHIFT;
193
194
if (clight->shadow.enabled) {
195
state.light_uniforms[index].flags |= LIGHT_FLAGS_HAS_SHADOW;
196
}
197
198
l->render_index_cache = index;
199
200
index++;
201
l = l->next_ptr;
202
}
203
204
light_count = index;
205
directional_light_count = light_count;
206
state.using_directional_lights = directional_light_count > 0;
207
}
208
209
//setup lights if exist
210
211
{
212
Light *l = p_light_list;
213
uint32_t index = light_count;
214
215
while (l) {
216
if (index == data.max_lights_per_render) {
217
l->render_index_cache = -1;
218
l = l->next_ptr;
219
continue;
220
}
221
222
CanvasLight *clight = canvas_light_owner.get_or_null(l->light_internal);
223
if (!clight) { //unused or invalid texture
224
l->render_index_cache = -1;
225
l = l->next_ptr;
226
ERR_CONTINUE(!clight);
227
}
228
229
Transform2D final_xform;
230
if (!RSG::canvas->_interpolation_data.interpolation_enabled || !l->interpolated) {
231
final_xform = l->xform_curr;
232
} else {
233
real_t f = Engine::get_singleton()->get_physics_interpolation_fraction();
234
TransformInterpolator::interpolate_transform_2d(l->xform_prev, l->xform_curr, final_xform, f);
235
}
236
// Convert light position to canvas coordinates, as all computation is done in canvas coordinates to avoid precision loss.
237
Vector2 canvas_light_pos = p_canvas_transform.xform(final_xform.get_origin());
238
state.light_uniforms[index].position[0] = canvas_light_pos.x;
239
state.light_uniforms[index].position[1] = canvas_light_pos.y;
240
241
_update_transform_2d_to_mat2x4(l->light_shader_xform.affine_inverse(), state.light_uniforms[index].matrix);
242
_update_transform_2d_to_mat2x4(l->xform_cache.affine_inverse(), state.light_uniforms[index].shadow_matrix);
243
244
state.light_uniforms[index].height = l->height * (p_canvas_transform.columns[0].length() + p_canvas_transform.columns[1].length()) * 0.5; //approximate height conversion to the canvas size, since all calculations are done in canvas coords to avoid precision loss
245
for (int i = 0; i < 4; i++) {
246
state.light_uniforms[index].shadow_color[i] = uint8_t(CLAMP(int32_t(l->shadow_color[i] * 255.0), 0, 255));
247
state.light_uniforms[index].color[i] = l->color[i];
248
}
249
250
state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate
251
252
if (state.shadow_fb != 0) {
253
state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth);
254
state.light_uniforms[index].shadow_z_far_inv = 1.0 / clight->shadow.z_far;
255
state.light_uniforms[index].shadow_y_ofs = clight->shadow.y_offset;
256
} else {
257
state.light_uniforms[index].shadow_pixel_size = 1.0;
258
state.light_uniforms[index].shadow_z_far_inv = 1.0;
259
state.light_uniforms[index].shadow_y_ofs = 0;
260
}
261
262
state.light_uniforms[index].flags = l->blend_mode << LIGHT_FLAGS_BLEND_SHIFT;
263
state.light_uniforms[index].flags |= l->shadow_filter << LIGHT_FLAGS_FILTER_SHIFT;
264
265
if (clight->shadow.enabled) {
266
state.light_uniforms[index].flags |= LIGHT_FLAGS_HAS_SHADOW;
267
}
268
269
if (clight->texture.is_valid()) {
270
Rect2 atlas_rect = GLES3::TextureStorage::get_singleton()->texture_atlas_get_texture_rect(clight->texture);
271
state.light_uniforms[index].atlas_rect[0] = atlas_rect.position.x;
272
state.light_uniforms[index].atlas_rect[1] = atlas_rect.position.y;
273
state.light_uniforms[index].atlas_rect[2] = atlas_rect.size.width;
274
state.light_uniforms[index].atlas_rect[3] = atlas_rect.size.height;
275
276
} else {
277
state.light_uniforms[index].atlas_rect[0] = 0;
278
state.light_uniforms[index].atlas_rect[1] = 0;
279
state.light_uniforms[index].atlas_rect[2] = 0;
280
state.light_uniforms[index].atlas_rect[3] = 0;
281
}
282
283
l->render_index_cache = index;
284
285
index++;
286
l = l->next_ptr;
287
}
288
289
light_count = index;
290
}
291
292
if (light_count > 0) {
293
glBindBufferBase(GL_UNIFORM_BUFFER, LIGHT_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_data_buffer_index].light_ubo);
294
295
#ifdef WEB_ENABLED
296
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightUniform) * light_count, state.light_uniforms);
297
#else
298
// On Desktop and mobile we map the memory without synchronizing for maximum speed.
299
void *ubo = glMapBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(LightUniform) * light_count, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
300
memcpy(ubo, state.light_uniforms, sizeof(LightUniform) * light_count);
301
glUnmapBuffer(GL_UNIFORM_BUFFER);
302
#endif
303
304
GLuint texture_atlas = texture_storage->texture_atlas_get_texture();
305
if (texture_atlas == 0) {
306
GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE));
307
texture_atlas = tex->tex_id;
308
}
309
glActiveTexture(GL_TEXTURE0 + GLES3::Config::get_singleton()->max_texture_image_units - 2);
310
glBindTexture(GL_TEXTURE_2D, texture_atlas);
311
GLuint shadow_tex = state.shadow_texture;
312
if (shadow_tex == 0) {
313
GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE));
314
shadow_tex = tex->tex_id;
315
}
316
glActiveTexture(GL_TEXTURE0 + GLES3::Config::get_singleton()->max_texture_image_units - 3);
317
glBindTexture(GL_TEXTURE_2D, shadow_tex);
318
}
319
320
{
321
//update canvas state uniform buffer
322
StateBuffer state_buffer;
323
324
Size2i ssize = texture_storage->render_target_get_size(p_to_render_target);
325
326
// If we've overridden the render target's color texture, then we need
327
// to invert the Y axis, so 2D texture appear right side up.
328
// We're probably rendering directly to an XR device.
329
float y_scale = texture_storage->render_target_get_override_color(p_to_render_target).is_valid() ? -2.0f : 2.0f;
330
331
Transform3D screen_transform;
332
screen_transform.translate_local(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
333
screen_transform.scale(Vector3(2.0f / ssize.width, y_scale / ssize.height, 1.0f));
334
_update_transform_to_mat4(screen_transform, state_buffer.screen_transform);
335
_update_transform_2d_to_mat4(p_canvas_transform, state_buffer.canvas_transform);
336
337
Transform2D normal_transform = p_canvas_transform;
338
normal_transform.columns[0].normalize();
339
normal_transform.columns[1].normalize();
340
normal_transform.columns[2] = Vector2();
341
_update_transform_2d_to_mat4(normal_transform, state_buffer.canvas_normal_transform);
342
343
state_buffer.canvas_modulate[0] = p_modulate.r;
344
state_buffer.canvas_modulate[1] = p_modulate.g;
345
state_buffer.canvas_modulate[2] = p_modulate.b;
346
state_buffer.canvas_modulate[3] = p_modulate.a;
347
348
Size2 render_target_size = texture_storage->render_target_get_size(p_to_render_target);
349
state_buffer.screen_pixel_size[0] = 1.0 / render_target_size.x;
350
state_buffer.screen_pixel_size[1] = 1.0 / render_target_size.y;
351
352
state_buffer.time = state.time;
353
state_buffer.use_pixel_snap = p_snap_2d_vertices_to_pixel;
354
355
state_buffer.directional_light_count = directional_light_count;
356
357
Vector2 canvas_scale = p_canvas_transform.get_scale();
358
359
state_buffer.sdf_to_screen[0] = render_target_size.width / canvas_scale.x;
360
state_buffer.sdf_to_screen[1] = render_target_size.height / canvas_scale.y;
361
362
state_buffer.screen_to_sdf[0] = 1.0 / state_buffer.sdf_to_screen[0];
363
state_buffer.screen_to_sdf[1] = 1.0 / state_buffer.sdf_to_screen[1];
364
365
Rect2 sdf_rect = texture_storage->render_target_get_sdf_rect(p_to_render_target);
366
Rect2 sdf_tex_rect(sdf_rect.position / canvas_scale, sdf_rect.size / canvas_scale);
367
368
state_buffer.sdf_to_tex[0] = 1.0 / sdf_tex_rect.size.width;
369
state_buffer.sdf_to_tex[1] = 1.0 / sdf_tex_rect.size.height;
370
state_buffer.sdf_to_tex[2] = -sdf_tex_rect.position.x / sdf_tex_rect.size.width;
371
state_buffer.sdf_to_tex[3] = -sdf_tex_rect.position.y / sdf_tex_rect.size.height;
372
373
state_buffer.tex_to_sdf = 1.0 / ((canvas_scale.x + canvas_scale.y) * 0.5);
374
375
glBindBufferBase(GL_UNIFORM_BUFFER, BASE_UNIFORM_LOCATION, state.canvas_instance_data_buffers[state.current_data_buffer_index].state_ubo);
376
glBufferData(GL_UNIFORM_BUFFER, sizeof(StateBuffer), &state_buffer, GL_STREAM_DRAW);
377
378
GLuint global_buffer = material_storage->global_shader_parameters_get_uniform_buffer();
379
380
glBindBufferBase(GL_UNIFORM_BUFFER, GLOBAL_UNIFORM_LOCATION, global_buffer);
381
glBindBuffer(GL_UNIFORM_BUFFER, 0);
382
}
383
384
glActiveTexture(GL_TEXTURE0 + GLES3::Config::get_singleton()->max_texture_image_units - 5);
385
glBindTexture(GL_TEXTURE_2D, texture_storage->render_target_get_sdf_texture(p_to_render_target));
386
387
{
388
state.default_filter = p_default_filter;
389
state.default_repeat = p_default_repeat;
390
}
391
392
Size2 render_target_size = texture_storage->render_target_get_size(p_to_render_target);
393
glViewport(0, 0, render_target_size.x, render_target_size.y);
394
395
r_sdf_used = false;
396
int item_count = 0;
397
bool backbuffer_cleared = false;
398
bool time_used = false;
399
bool material_screen_texture_cached = false;
400
bool material_screen_texture_mipmaps_cached = false;
401
Rect2 back_buffer_rect;
402
bool backbuffer_copy = false;
403
bool backbuffer_gen_mipmaps = false;
404
bool update_skeletons = false;
405
406
Item *ci = p_item_list;
407
Item *canvas_group_owner = nullptr;
408
bool skip_item = false;
409
410
state.last_item_index = 0;
411
412
while (ci) {
413
if (ci->copy_back_buffer && canvas_group_owner == nullptr) {
414
backbuffer_copy = true;
415
416
if (ci->copy_back_buffer->full) {
417
back_buffer_rect = Rect2();
418
} else {
419
back_buffer_rect = ci->copy_back_buffer->rect;
420
}
421
}
422
423
// Check material for something that may change flow of rendering, but do not bind for now.
424
RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material;
425
if (material.is_valid()) {
426
GLES3::CanvasMaterialData *md = static_cast<GLES3::CanvasMaterialData *>(material_storage->material_get_data(material, RS::SHADER_CANVAS_ITEM));
427
if (md && md->shader_data->valid) {
428
if (md->shader_data->uses_screen_texture && canvas_group_owner == nullptr) {
429
if (!material_screen_texture_cached) {
430
backbuffer_copy = true;
431
back_buffer_rect = Rect2();
432
backbuffer_gen_mipmaps = md->shader_data->uses_screen_texture_mipmaps;
433
} else if (!material_screen_texture_mipmaps_cached) {
434
backbuffer_gen_mipmaps = md->shader_data->uses_screen_texture_mipmaps;
435
}
436
}
437
438
if (md->shader_data->uses_sdf) {
439
r_sdf_used = true;
440
}
441
if (md->shader_data->uses_time) {
442
time_used = true;
443
}
444
}
445
}
446
447
if (ci->skeleton.is_valid()) {
448
const Item::Command *c = ci->commands;
449
450
while (c) {
451
if (c->type == Item::Command::TYPE_MESH) {
452
const Item::CommandMesh *cm = static_cast<const Item::CommandMesh *>(c);
453
if (cm->mesh_instance.is_valid()) {
454
mesh_storage->mesh_instance_check_for_update(cm->mesh_instance);
455
mesh_storage->mesh_instance_set_canvas_item_transform(cm->mesh_instance, canvas_transform_inverse * ci->final_transform);
456
update_skeletons = true;
457
}
458
}
459
c = c->next;
460
}
461
}
462
463
if (ci->canvas_group_owner != nullptr) {
464
if (canvas_group_owner == nullptr) {
465
if (update_skeletons) {
466
mesh_storage->update_mesh_instances();
467
update_skeletons = false;
468
}
469
// Canvas group begins here, render until before this item
470
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false, r_render_info, material_screen_texture_mipmaps_cached);
471
item_count = 0;
472
473
if (ci->canvas_group_owner->canvas_group->mode != RS::CANVAS_GROUP_MODE_TRANSPARENT) {
474
Rect2i group_rect = ci->canvas_group_owner->global_rect_cache;
475
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false);
476
if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) {
477
ci->canvas_group_owner->use_canvas_group = false;
478
items[item_count++] = ci->canvas_group_owner;
479
}
480
} else if (!backbuffer_cleared) {
481
texture_storage->render_target_clear_back_buffer(p_to_render_target, Rect2i(), Color(0, 0, 0, 0));
482
backbuffer_cleared = true;
483
}
484
485
backbuffer_copy = false;
486
canvas_group_owner = ci->canvas_group_owner; //continue until owner found
487
}
488
489
ci->canvas_group_owner = nullptr; //must be cleared
490
}
491
492
if (canvas_group_owner == nullptr && ci->canvas_group != nullptr && ci->canvas_group->mode != RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) {
493
skip_item = true;
494
}
495
496
if (ci == canvas_group_owner) {
497
if (update_skeletons) {
498
mesh_storage->update_mesh_instances();
499
update_skeletons = false;
500
}
501
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, true, r_render_info, material_screen_texture_mipmaps_cached);
502
item_count = 0;
503
504
if (ci->canvas_group->blur_mipmaps) {
505
texture_storage->render_target_gen_back_buffer_mipmaps(p_to_render_target, ci->global_rect_cache);
506
}
507
508
canvas_group_owner = nullptr;
509
// Backbuffer is dirty now and needs to be re-cleared if another CanvasGroup needs it.
510
backbuffer_cleared = false;
511
512
// Tell the renderer to paint this as a canvas group
513
ci->use_canvas_group = true;
514
} else {
515
ci->use_canvas_group = false;
516
}
517
518
if (backbuffer_copy) {
519
if (update_skeletons) {
520
mesh_storage->update_mesh_instances();
521
update_skeletons = false;
522
}
523
//render anything pending, including clearing if no items
524
525
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, false, r_render_info, material_screen_texture_mipmaps_cached);
526
item_count = 0;
527
528
texture_storage->render_target_copy_to_back_buffer(p_to_render_target, back_buffer_rect, backbuffer_gen_mipmaps);
529
530
backbuffer_copy = false;
531
material_screen_texture_cached = true; // After a backbuffer copy, screen texture makes no further copies.
532
material_screen_texture_mipmaps_cached = backbuffer_gen_mipmaps;
533
backbuffer_gen_mipmaps = false;
534
}
535
536
if (backbuffer_gen_mipmaps) {
537
texture_storage->render_target_gen_back_buffer_mipmaps(p_to_render_target, back_buffer_rect);
538
539
backbuffer_gen_mipmaps = false;
540
material_screen_texture_mipmaps_cached = true;
541
}
542
543
// just add all items for now
544
if (skip_item) {
545
skip_item = false;
546
} else {
547
items[item_count++] = ci;
548
}
549
550
if (!ci->next || item_count == MAX_RENDER_ITEMS - 1) {
551
if (update_skeletons) {
552
mesh_storage->update_mesh_instances();
553
update_skeletons = false;
554
}
555
_render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list, r_sdf_used, canvas_group_owner != nullptr, r_render_info, material_screen_texture_mipmaps_cached);
556
//then reset
557
item_count = 0;
558
}
559
560
ci = ci->next;
561
}
562
563
if (time_used) {
564
RenderingServerDefault::redraw_request();
565
}
566
567
state.canvas_instance_data_buffers[state.current_data_buffer_index].fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
568
569
// Clear out state used in 2D pass
570
reset_canvas();
571
state.current_data_buffer_index = (state.current_data_buffer_index + 1) % state.canvas_instance_data_buffers.size();
572
state.current_instance_buffer_index = 0;
573
}
574
575
void RasterizerCanvasGLES3::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, bool &r_sdf_used, bool p_to_backbuffer, RenderingMethod::RenderInfo *r_render_info, bool p_backbuffer_has_mipmaps) {
576
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
577
578
canvas_begin(p_to_render_target, p_to_backbuffer, p_backbuffer_has_mipmaps);
579
580
if (p_item_count <= 0) {
581
// Nothing to draw, just call canvas_begin() to clear the render target and return.
582
return;
583
}
584
585
uint32_t index = 0;
586
Item *current_clip = nullptr;
587
GLES3::CanvasShaderData *shader_data_cache = nullptr;
588
589
// Record Batches.
590
// First item always forms its own batch.
591
bool batch_broken = false;
592
_new_batch(batch_broken);
593
594
// Override the start position and index as we want to start from where we finished off last time.
595
state.canvas_instance_batches[state.current_batch_index].start = state.last_item_index;
596
index = 0;
597
598
for (int i = 0; i < p_item_count; i++) {
599
Item *ci = items[i];
600
601
if (ci->final_clip_owner != state.canvas_instance_batches[state.current_batch_index].clip) {
602
_new_batch(batch_broken);
603
state.canvas_instance_batches[state.current_batch_index].clip = ci->final_clip_owner;
604
current_clip = ci->final_clip_owner;
605
}
606
607
RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material;
608
if (ci->use_canvas_group) {
609
if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) {
610
material = default_clip_children_material;
611
} else {
612
if (material.is_null()) {
613
if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_ONLY) {
614
material = default_clip_children_material;
615
} else {
616
material = default_canvas_group_material;
617
}
618
}
619
}
620
}
621
622
if (material != state.canvas_instance_batches[state.current_batch_index].material) {
623
_new_batch(batch_broken);
624
625
GLES3::CanvasMaterialData *material_data = nullptr;
626
if (material.is_valid()) {
627
material_data = static_cast<GLES3::CanvasMaterialData *>(material_storage->material_get_data(material, RS::SHADER_CANVAS_ITEM));
628
}
629
shader_data_cache = nullptr;
630
if (material_data) {
631
if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) {
632
shader_data_cache = material_data->shader_data;
633
}
634
}
635
636
state.canvas_instance_batches[state.current_batch_index].material = material;
637
state.canvas_instance_batches[state.current_batch_index].material_data = material_data;
638
if (shader_data_cache) {
639
state.canvas_instance_batches[state.current_batch_index].vertex_input_mask = shader_data_cache->vertex_input_mask;
640
}
641
}
642
643
GLES3::CanvasShaderData::BlendMode blend_mode = shader_data_cache ? shader_data_cache->blend_mode : GLES3::CanvasShaderData::BLEND_MODE_MIX;
644
645
if (!ci->repeat_size.x && !ci->repeat_size.y) {
646
_record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken, r_sdf_used, Point2());
647
} else {
648
Point2 start_pos = ci->repeat_size * -(ci->repeat_times / 2);
649
Point2 offset;
650
651
int repeat_times_x = ci->repeat_size.x ? ci->repeat_times : 0;
652
int repeat_times_y = ci->repeat_size.y ? ci->repeat_times : 0;
653
for (int ry = 0; ry <= repeat_times_y; ry++) {
654
offset.y = start_pos.y + ry * ci->repeat_size.y;
655
for (int rx = 0; rx <= repeat_times_x; rx++) {
656
offset.x = start_pos.x + rx * ci->repeat_size.x;
657
_record_item_commands(ci, p_to_render_target, p_canvas_transform_inverse, current_clip, blend_mode, p_lights, index, batch_broken, r_sdf_used, offset);
658
}
659
}
660
}
661
}
662
663
if (index == 0) {
664
// Nothing to render, just return.
665
return;
666
}
667
668
// Copy over all data needed for rendering.
669
glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.current_instance_buffer_index]);
670
#ifdef WEB_ENABLED
671
glBufferSubData(GL_ARRAY_BUFFER, state.last_item_index * sizeof(InstanceData), sizeof(InstanceData) * index, state.instance_data_array);
672
#else
673
// On Desktop and mobile we map the memory without synchronizing for maximum speed.
674
void *buffer = glMapBufferRange(GL_ARRAY_BUFFER, state.last_item_index * sizeof(InstanceData), index * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
675
memcpy(buffer, state.instance_data_array, index * sizeof(InstanceData));
676
glUnmapBuffer(GL_ARRAY_BUFFER);
677
#endif
678
679
glDisable(GL_SCISSOR_TEST);
680
current_clip = nullptr;
681
682
GLES3::CanvasShaderData::BlendMode last_blend_mode = GLES3::CanvasShaderData::BLEND_MODE_MIX;
683
Color last_blend_color;
684
685
state.current_tex = RID();
686
687
const uint64_t base_specialization = GLES3::Config::get_singleton()->float_texture_supported ? 0 : CanvasShaderGLES3::USE_RGBA_SHADOWS;
688
689
for (uint32_t i = 0; i <= state.current_batch_index; i++) {
690
// Skipping when there is no instances.
691
if (state.canvas_instance_batches[i].instance_count == 0) {
692
continue;
693
}
694
695
//setup clip
696
if (current_clip != state.canvas_instance_batches[i].clip) {
697
current_clip = state.canvas_instance_batches[i].clip;
698
if (current_clip) {
699
glEnable(GL_SCISSOR_TEST);
700
glScissor(current_clip->final_clip_rect.position.x, current_clip->final_clip_rect.position.y, current_clip->final_clip_rect.size.x, current_clip->final_clip_rect.size.y);
701
} else {
702
glDisable(GL_SCISSOR_TEST);
703
}
704
}
705
706
GLES3::CanvasMaterialData *material_data = state.canvas_instance_batches[i].material_data;
707
CanvasShaderGLES3::ShaderVariant variant = CanvasShaderGLES3::MODE_DEFAULT;
708
uint64_t specialization = state.canvas_instance_batches[i].specialization;
709
specialization |= base_specialization;
710
RID shader_version = data.canvas_shader_default_version;
711
712
if (material_data) {
713
if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) {
714
// Bind uniform buffer and textures
715
material_data->bind_uniforms();
716
shader_version = material_data->shader_data->version;
717
}
718
}
719
720
bool success = material_storage->shaders.canvas_shader.version_bind_shader(shader_version, variant, specialization);
721
if (!success) {
722
continue;
723
}
724
725
// Bind per-batch uniforms.
726
material_storage->shaders.canvas_shader.version_set_uniform(CanvasShaderGLES3::BATCH_FLAGS, state.canvas_instance_batches[i].flags, shader_version, variant, specialization);
727
material_storage->shaders.canvas_shader.version_set_uniform(CanvasShaderGLES3::SPECULAR_SHININESS_IN, state.canvas_instance_batches[i].specular_shininess, shader_version, variant, specialization);
728
729
GLES3::CanvasShaderData::BlendMode blend_mode = state.canvas_instance_batches[i].blend_mode;
730
Color blend_color = state.canvas_instance_batches[i].blend_color;
731
732
if (last_blend_mode != blend_mode || last_blend_color != blend_color) {
733
if (last_blend_mode == GLES3::CanvasShaderData::BLEND_MODE_DISABLED) {
734
// re-enable it
735
glEnable(GL_BLEND);
736
} else if (blend_mode == GLES3::CanvasShaderData::BLEND_MODE_DISABLED) {
737
// disable it
738
glDisable(GL_BLEND);
739
}
740
741
switch (blend_mode) {
742
case GLES3::CanvasShaderData::BLEND_MODE_DISABLED: {
743
// Nothing to do here.
744
} break;
745
case GLES3::CanvasShaderData::BLEND_MODE_LCD: {
746
glBlendEquation(GL_FUNC_ADD);
747
if (state.transparent_render_target) {
748
glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
749
} else {
750
glBlendFuncSeparate(GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE);
751
}
752
glBlendColor(blend_color.r, blend_color.g, blend_color.b, blend_color.a);
753
754
} break;
755
case GLES3::CanvasShaderData::BLEND_MODE_MIX: {
756
glBlendEquation(GL_FUNC_ADD);
757
if (state.transparent_render_target) {
758
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
759
} else {
760
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
761
}
762
763
} break;
764
case GLES3::CanvasShaderData::BLEND_MODE_ADD: {
765
glBlendEquation(GL_FUNC_ADD);
766
if (state.transparent_render_target) {
767
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE);
768
} else {
769
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
770
}
771
772
} break;
773
case GLES3::CanvasShaderData::BLEND_MODE_SUB: {
774
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
775
if (state.transparent_render_target) {
776
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE);
777
} else {
778
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
779
}
780
} break;
781
case GLES3::CanvasShaderData::BLEND_MODE_MUL: {
782
glBlendEquation(GL_FUNC_ADD);
783
if (state.transparent_render_target) {
784
glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_DST_ALPHA, GL_ZERO);
785
} else {
786
glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ZERO, GL_ONE);
787
}
788
789
} break;
790
case GLES3::CanvasShaderData::BLEND_MODE_PMALPHA: {
791
glBlendEquation(GL_FUNC_ADD);
792
if (state.transparent_render_target) {
793
glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
794
} else {
795
glBlendFuncSeparate(GL_ONE, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
796
}
797
798
} break;
799
}
800
last_blend_mode = blend_mode;
801
last_blend_color = blend_color;
802
}
803
804
_render_batch(p_lights, i, r_render_info);
805
}
806
807
glDisable(GL_SCISSOR_TEST);
808
state.current_batch_index = 0;
809
state.canvas_instance_batches.clear();
810
state.last_item_index += index;
811
}
812
813
void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_render_target, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, GLES3::CanvasShaderData::BlendMode p_blend_mode, Light *p_lights, uint32_t &r_index, bool &r_batch_broken, bool &r_sdf_used, const Point2 &p_repeat_offset) {
814
RenderingServer::CanvasItemTextureFilter texture_filter = p_item->texture_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? state.default_filter : p_item->texture_filter;
815
const uint64_t specialization_command_mask = ~(CanvasShaderGLES3::USE_NINEPATCH | CanvasShaderGLES3::USE_PRIMITIVE | CanvasShaderGLES3::USE_ATTRIBUTES | CanvasShaderGLES3::USE_INSTANCING);
816
817
if (texture_filter != state.canvas_instance_batches[state.current_batch_index].filter) {
818
_new_batch(r_batch_broken);
819
820
state.canvas_instance_batches[state.current_batch_index].filter = texture_filter;
821
}
822
823
RenderingServer::CanvasItemTextureRepeat texture_repeat = p_item->texture_repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? state.default_repeat : p_item->texture_repeat;
824
825
if (texture_repeat != state.canvas_instance_batches[state.current_batch_index].repeat) {
826
_new_batch(r_batch_broken);
827
828
state.canvas_instance_batches[state.current_batch_index].repeat = texture_repeat;
829
}
830
831
Transform2D base_transform = p_item->final_transform;
832
if (p_item->repeat_source_item && (p_repeat_offset.x || p_repeat_offset.y)) {
833
base_transform.columns[2] += p_item->repeat_source_item->final_transform.basis_xform(p_repeat_offset);
834
}
835
base_transform = p_canvas_transform_inverse * base_transform;
836
837
Transform2D draw_transform; // Used by transform command
838
839
Color base_color = p_item->final_modulate;
840
uint32_t base_flags = 0;
841
Size2 texpixel_size;
842
843
bool reclip = false;
844
845
bool skipping = false;
846
847
// TODO: consider making lights a per-batch property and then baking light operations in the shader for better performance.
848
uint32_t lights[4] = { 0, 0, 0, 0 };
849
850
uint16_t light_count = 0;
851
uint16_t shadow_mask = 0;
852
853
{
854
Light *light = p_lights;
855
856
while (light) {
857
if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects(light->rect_cache)) {
858
uint32_t light_index = light->render_index_cache;
859
lights[light_count >> 2] |= light_index << ((light_count & 3) * 8);
860
861
if (p_item->light_mask & light->item_shadow_mask) {
862
shadow_mask |= 1 << light_count;
863
}
864
865
light_count++;
866
867
if (light_count == data.max_lights_per_item - 1) {
868
break;
869
}
870
}
871
light = light->next_ptr;
872
}
873
874
base_flags |= light_count << INSTANCE_FLAGS_LIGHT_COUNT_SHIFT;
875
base_flags |= shadow_mask << INSTANCE_FLAGS_SHADOW_MASKED_SHIFT;
876
}
877
878
bool lights_disabled = light_count == 0 && !state.using_directional_lights;
879
880
if (lights_disabled != bool(state.canvas_instance_batches[state.current_batch_index].specialization & CanvasShaderGLES3::DISABLE_LIGHTING)) {
881
_new_batch(r_batch_broken);
882
state.canvas_instance_batches[state.current_batch_index].specialization ^= CanvasShaderGLES3::DISABLE_LIGHTING;
883
}
884
885
const Item::Command *c = p_item->commands;
886
while (c) {
887
if (skipping && c->type != Item::Command::TYPE_ANIMATION_SLICE) {
888
c = c->next;
889
continue;
890
}
891
892
if (c->type != Item::Command::TYPE_MESH) {
893
// For Meshes, this gets updated below.
894
_update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world);
895
}
896
897
// Zero out most fields.
898
for (int i = 0; i < 4; i++) {
899
state.instance_data_array[r_index].modulation[i] = 0.0;
900
state.instance_data_array[r_index].ninepatch_margins[i] = 0.0;
901
state.instance_data_array[r_index].src_rect[i] = 0.0;
902
state.instance_data_array[r_index].dst_rect[i] = 0.0;
903
state.instance_data_array[r_index].lights[i] = uint32_t(0);
904
}
905
state.instance_data_array[r_index].color_texture_pixel_size[0] = 0.0;
906
state.instance_data_array[r_index].color_texture_pixel_size[1] = 0.0;
907
908
state.instance_data_array[r_index].lights[0] = lights[0];
909
state.instance_data_array[r_index].lights[1] = lights[1];
910
state.instance_data_array[r_index].lights[2] = lights[2];
911
state.instance_data_array[r_index].lights[3] = lights[3];
912
913
state.instance_data_array[r_index].flags = base_flags;
914
state.instance_data_array[r_index].instance_uniforms_ofs = p_item->instance_allocated_shader_uniforms_offset;
915
916
Color blend_color = base_color;
917
GLES3::CanvasShaderData::BlendMode blend_mode = p_blend_mode;
918
if (c->type == Item::Command::TYPE_RECT) {
919
const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c);
920
if (rect->flags & CANVAS_RECT_LCD) {
921
blend_mode = GLES3::CanvasShaderData::BLEND_MODE_LCD;
922
blend_color = rect->modulate * base_color;
923
}
924
}
925
926
if (blend_mode != state.canvas_instance_batches[state.current_batch_index].blend_mode || blend_color != state.canvas_instance_batches[state.current_batch_index].blend_color) {
927
_new_batch(r_batch_broken);
928
state.canvas_instance_batches[state.current_batch_index].blend_mode = blend_mode;
929
state.canvas_instance_batches[state.current_batch_index].blend_color = blend_color;
930
}
931
932
switch (c->type) {
933
case Item::Command::TYPE_RECT: {
934
const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c);
935
936
if (rect->flags & CANVAS_RECT_TILE && state.canvas_instance_batches[state.current_batch_index].repeat != RenderingServer::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED) {
937
_new_batch(r_batch_broken);
938
state.canvas_instance_batches[state.current_batch_index].repeat = RenderingServer::CanvasItemTextureRepeat::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED;
939
}
940
941
if (rect->texture != state.canvas_instance_batches[state.current_batch_index].tex || state.canvas_instance_batches[state.current_batch_index].command_type != Item::Command::TYPE_RECT) {
942
_new_batch(r_batch_broken);
943
state.canvas_instance_batches[state.current_batch_index].tex = rect->texture;
944
state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_RECT;
945
state.canvas_instance_batches[state.current_batch_index].command = c;
946
state.canvas_instance_batches[state.current_batch_index].specialization &= specialization_command_mask;
947
state.canvas_instance_batches[state.current_batch_index].flags = 0;
948
}
949
950
_prepare_canvas_texture(rect->texture, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size);
951
952
Rect2 src_rect;
953
Rect2 dst_rect;
954
955
if (rect->texture != RID()) {
956
src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * texpixel_size, rect->source.size * texpixel_size) : Rect2(0, 0, 1, 1);
957
dst_rect = Rect2(rect->rect.position, rect->rect.size);
958
959
if (dst_rect.size.width < 0) {
960
dst_rect.position.x += dst_rect.size.width;
961
dst_rect.size.width *= -1;
962
}
963
if (dst_rect.size.height < 0) {
964
dst_rect.position.y += dst_rect.size.height;
965
dst_rect.size.height *= -1;
966
}
967
968
if (rect->flags & CANVAS_RECT_FLIP_H) {
969
src_rect.size.x *= -1;
970
}
971
972
if (rect->flags & CANVAS_RECT_FLIP_V) {
973
src_rect.size.y *= -1;
974
}
975
976
if (rect->flags & CANVAS_RECT_TRANSPOSE) {
977
state.instance_data_array[r_index].flags |= INSTANCE_FLAGS_TRANSPOSE_RECT;
978
}
979
980
if (rect->flags & CANVAS_RECT_CLIP_UV) {
981
state.instance_data_array[r_index].flags |= INSTANCE_FLAGS_CLIP_RECT_UV;
982
}
983
984
} else {
985
dst_rect = Rect2(rect->rect.position, rect->rect.size);
986
987
if (dst_rect.size.width < 0) {
988
dst_rect.position.x += dst_rect.size.width;
989
dst_rect.size.width *= -1;
990
}
991
if (dst_rect.size.height < 0) {
992
dst_rect.position.y += dst_rect.size.height;
993
dst_rect.size.height *= -1;
994
}
995
996
src_rect = Rect2(0, 0, 1, 1);
997
}
998
999
if (rect->flags & CANVAS_RECT_MSDF) {
1000
state.instance_data_array[r_index].flags |= INSTANCE_FLAGS_USE_MSDF;
1001
state.instance_data_array[r_index].msdf[0] = rect->px_range; // Pixel range.
1002
state.instance_data_array[r_index].msdf[1] = rect->outline; // Outline size.
1003
state.instance_data_array[r_index].msdf[2] = 0.f; // Reserved.
1004
state.instance_data_array[r_index].msdf[3] = 0.f; // Reserved.
1005
} else if (rect->flags & CANVAS_RECT_LCD) {
1006
state.instance_data_array[r_index].flags |= INSTANCE_FLAGS_USE_LCD;
1007
}
1008
1009
state.instance_data_array[r_index].modulation[0] = rect->modulate.r * base_color.r;
1010
state.instance_data_array[r_index].modulation[1] = rect->modulate.g * base_color.g;
1011
state.instance_data_array[r_index].modulation[2] = rect->modulate.b * base_color.b;
1012
state.instance_data_array[r_index].modulation[3] = rect->modulate.a * base_color.a;
1013
1014
state.instance_data_array[r_index].src_rect[0] = src_rect.position.x;
1015
state.instance_data_array[r_index].src_rect[1] = src_rect.position.y;
1016
state.instance_data_array[r_index].src_rect[2] = src_rect.size.width;
1017
state.instance_data_array[r_index].src_rect[3] = src_rect.size.height;
1018
1019
state.instance_data_array[r_index].dst_rect[0] = dst_rect.position.x;
1020
state.instance_data_array[r_index].dst_rect[1] = dst_rect.position.y;
1021
state.instance_data_array[r_index].dst_rect[2] = dst_rect.size.width;
1022
state.instance_data_array[r_index].dst_rect[3] = dst_rect.size.height;
1023
1024
_add_to_batch(r_index, r_batch_broken);
1025
} break;
1026
1027
case Item::Command::TYPE_NINEPATCH: {
1028
const Item::CommandNinePatch *np = static_cast<const Item::CommandNinePatch *>(c);
1029
1030
if (np->texture != state.canvas_instance_batches[state.current_batch_index].tex || state.canvas_instance_batches[state.current_batch_index].command_type != Item::Command::TYPE_NINEPATCH) {
1031
_new_batch(r_batch_broken);
1032
state.canvas_instance_batches[state.current_batch_index].tex = np->texture;
1033
state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_NINEPATCH;
1034
state.canvas_instance_batches[state.current_batch_index].command = c;
1035
state.canvas_instance_batches[state.current_batch_index].specialization &= specialization_command_mask;
1036
state.canvas_instance_batches[state.current_batch_index].specialization |= CanvasShaderGLES3::USE_NINEPATCH;
1037
state.canvas_instance_batches[state.current_batch_index].flags = 0;
1038
}
1039
1040
_prepare_canvas_texture(np->texture, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size);
1041
1042
Rect2 src_rect;
1043
Rect2 dst_rect(np->rect.position.x, np->rect.position.y, np->rect.size.x, np->rect.size.y);
1044
1045
if (np->texture == RID()) {
1046
texpixel_size = Size2(1, 1);
1047
src_rect = Rect2(0, 0, 1, 1);
1048
1049
} else {
1050
if (np->source != Rect2()) {
1051
src_rect = Rect2(np->source.position.x * texpixel_size.width, np->source.position.y * texpixel_size.height, np->source.size.x * texpixel_size.width, np->source.size.y * texpixel_size.height);
1052
state.instance_data_array[r_index].color_texture_pixel_size[0] = 1.0 / np->source.size.width;
1053
state.instance_data_array[r_index].color_texture_pixel_size[1] = 1.0 / np->source.size.height;
1054
1055
} else {
1056
src_rect = Rect2(0, 0, 1, 1);
1057
}
1058
}
1059
1060
state.instance_data_array[r_index].modulation[0] = np->color.r * base_color.r;
1061
state.instance_data_array[r_index].modulation[1] = np->color.g * base_color.g;
1062
state.instance_data_array[r_index].modulation[2] = np->color.b * base_color.b;
1063
state.instance_data_array[r_index].modulation[3] = np->color.a * base_color.a;
1064
1065
state.instance_data_array[r_index].src_rect[0] = src_rect.position.x;
1066
state.instance_data_array[r_index].src_rect[1] = src_rect.position.y;
1067
state.instance_data_array[r_index].src_rect[2] = src_rect.size.width;
1068
state.instance_data_array[r_index].src_rect[3] = src_rect.size.height;
1069
1070
state.instance_data_array[r_index].dst_rect[0] = dst_rect.position.x;
1071
state.instance_data_array[r_index].dst_rect[1] = dst_rect.position.y;
1072
state.instance_data_array[r_index].dst_rect[2] = dst_rect.size.width;
1073
state.instance_data_array[r_index].dst_rect[3] = dst_rect.size.height;
1074
1075
state.instance_data_array[r_index].flags |= int(np->axis_x) << INSTANCE_FLAGS_NINEPATCH_H_MODE_SHIFT;
1076
state.instance_data_array[r_index].flags |= int(np->axis_y) << INSTANCE_FLAGS_NINEPATCH_V_MODE_SHIFT;
1077
1078
if (np->draw_center) {
1079
state.instance_data_array[r_index].flags |= INSTANCE_FLAGS_NINEPACH_DRAW_CENTER;
1080
}
1081
1082
state.instance_data_array[r_index].ninepatch_margins[0] = np->margin[SIDE_LEFT];
1083
state.instance_data_array[r_index].ninepatch_margins[1] = np->margin[SIDE_TOP];
1084
state.instance_data_array[r_index].ninepatch_margins[2] = np->margin[SIDE_RIGHT];
1085
state.instance_data_array[r_index].ninepatch_margins[3] = np->margin[SIDE_BOTTOM];
1086
1087
_add_to_batch(r_index, r_batch_broken);
1088
1089
// Restore if overridden.
1090
state.instance_data_array[r_index].color_texture_pixel_size[0] = texpixel_size.x;
1091
state.instance_data_array[r_index].color_texture_pixel_size[1] = texpixel_size.y;
1092
} break;
1093
1094
case Item::Command::TYPE_POLYGON: {
1095
const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
1096
1097
// Polygon's can't be batched, so always create a new batch
1098
_new_batch(r_batch_broken);
1099
1100
state.canvas_instance_batches[state.current_batch_index].tex = polygon->texture;
1101
state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_POLYGON;
1102
state.canvas_instance_batches[state.current_batch_index].command = c;
1103
state.canvas_instance_batches[state.current_batch_index].specialization &= specialization_command_mask;
1104
state.canvas_instance_batches[state.current_batch_index].specialization |= CanvasShaderGLES3::USE_ATTRIBUTES;
1105
state.canvas_instance_batches[state.current_batch_index].flags = 0;
1106
1107
_prepare_canvas_texture(polygon->texture, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size);
1108
1109
state.instance_data_array[r_index].modulation[0] = base_color.r;
1110
state.instance_data_array[r_index].modulation[1] = base_color.g;
1111
state.instance_data_array[r_index].modulation[2] = base_color.b;
1112
state.instance_data_array[r_index].modulation[3] = base_color.a;
1113
1114
for (int j = 0; j < 4; j++) {
1115
state.instance_data_array[r_index].src_rect[j] = 0;
1116
state.instance_data_array[r_index].dst_rect[j] = 0;
1117
state.instance_data_array[r_index].ninepatch_margins[j] = 0;
1118
}
1119
1120
_add_to_batch(r_index, r_batch_broken);
1121
} break;
1122
1123
case Item::Command::TYPE_PRIMITIVE: {
1124
const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
1125
1126
if (primitive->point_count != state.canvas_instance_batches[state.current_batch_index].primitive_points || state.canvas_instance_batches[state.current_batch_index].command_type != Item::Command::TYPE_PRIMITIVE || primitive->texture != state.canvas_instance_batches[state.current_batch_index].tex) {
1127
_new_batch(r_batch_broken);
1128
state.canvas_instance_batches[state.current_batch_index].tex = primitive->texture;
1129
state.canvas_instance_batches[state.current_batch_index].primitive_points = primitive->point_count;
1130
state.canvas_instance_batches[state.current_batch_index].command_type = Item::Command::TYPE_PRIMITIVE;
1131
state.canvas_instance_batches[state.current_batch_index].command = c;
1132
state.canvas_instance_batches[state.current_batch_index].specialization &= specialization_command_mask;
1133
state.canvas_instance_batches[state.current_batch_index].specialization |= CanvasShaderGLES3::USE_PRIMITIVE;
1134
state.canvas_instance_batches[state.current_batch_index].flags = 0;
1135
}
1136
1137
_prepare_canvas_texture(state.canvas_instance_batches[state.current_batch_index].tex, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size);
1138
1139
for (uint32_t j = 0; j < MIN(3u, primitive->point_count); j++) {
1140
state.instance_data_array[r_index].points[j * 2 + 0] = primitive->points[j].x;
1141
state.instance_data_array[r_index].points[j * 2 + 1] = primitive->points[j].y;
1142
state.instance_data_array[r_index].uvs[j * 2 + 0] = primitive->uvs[j].x;
1143
state.instance_data_array[r_index].uvs[j * 2 + 1] = primitive->uvs[j].y;
1144
Color col = primitive->colors[j] * base_color;
1145
state.instance_data_array[r_index].colors[j * 2 + 0] = (uint32_t(Math::make_half_float(col.g)) << 16) | Math::make_half_float(col.r);
1146
state.instance_data_array[r_index].colors[j * 2 + 1] = (uint32_t(Math::make_half_float(col.a)) << 16) | Math::make_half_float(col.b);
1147
}
1148
1149
_add_to_batch(r_index, r_batch_broken);
1150
1151
if (primitive->point_count == 4) {
1152
// Reset base data.
1153
_update_transform_2d_to_mat2x3(base_transform * draw_transform, state.instance_data_array[r_index].world);
1154
_prepare_canvas_texture(state.canvas_instance_batches[state.current_batch_index].tex, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size);
1155
state.instance_data_array[r_index].lights[0] = lights[0];
1156
state.instance_data_array[r_index].lights[1] = lights[1];
1157
state.instance_data_array[r_index].lights[2] = lights[2];
1158
state.instance_data_array[r_index].lights[3] = lights[3];
1159
state.instance_data_array[r_index].flags = base_flags;
1160
state.instance_data_array[r_index].instance_uniforms_ofs = p_item->instance_allocated_shader_uniforms_offset;
1161
1162
for (uint32_t j = 0; j < 3; j++) {
1163
int offset = j == 0 ? 0 : 1;
1164
// Second triangle in the quad. Uses vertices 0, 2, 3.
1165
state.instance_data_array[r_index].points[j * 2 + 0] = primitive->points[j + offset].x;
1166
state.instance_data_array[r_index].points[j * 2 + 1] = primitive->points[j + offset].y;
1167
state.instance_data_array[r_index].uvs[j * 2 + 0] = primitive->uvs[j + offset].x;
1168
state.instance_data_array[r_index].uvs[j * 2 + 1] = primitive->uvs[j + offset].y;
1169
Color col = primitive->colors[j + offset] * base_color;
1170
state.instance_data_array[r_index].colors[j * 2 + 0] = (uint32_t(Math::make_half_float(col.g)) << 16) | Math::make_half_float(col.r);
1171
state.instance_data_array[r_index].colors[j * 2 + 1] = (uint32_t(Math::make_half_float(col.a)) << 16) | Math::make_half_float(col.b);
1172
}
1173
1174
_add_to_batch(r_index, r_batch_broken);
1175
}
1176
} break;
1177
1178
case Item::Command::TYPE_MESH:
1179
case Item::Command::TYPE_MULTIMESH:
1180
case Item::Command::TYPE_PARTICLES: {
1181
// Meshes can't be batched, so always create a new batch.
1182
_new_batch(r_batch_broken);
1183
1184
Color modulate(1, 1, 1, 1);
1185
state.canvas_instance_batches[state.current_batch_index].specialization &= specialization_command_mask;
1186
state.canvas_instance_batches[state.current_batch_index].specialization |= CanvasShaderGLES3::USE_ATTRIBUTES;
1187
state.canvas_instance_batches[state.current_batch_index].flags = 0;
1188
if (c->type == Item::Command::TYPE_MESH) {
1189
const Item::CommandMesh *m = static_cast<const Item::CommandMesh *>(c);
1190
state.canvas_instance_batches[state.current_batch_index].tex = m->texture;
1191
_update_transform_2d_to_mat2x3(base_transform * draw_transform * m->transform, state.instance_data_array[r_index].world);
1192
modulate = m->modulate;
1193
1194
} else if (c->type == Item::Command::TYPE_MULTIMESH) {
1195
const Item::CommandMultiMesh *mm = static_cast<const Item::CommandMultiMesh *>(c);
1196
state.canvas_instance_batches[state.current_batch_index].tex = mm->texture;
1197
state.canvas_instance_batches[state.current_batch_index].specialization |= CanvasShaderGLES3::USE_INSTANCING;
1198
1199
if (GLES3::MeshStorage::get_singleton()->multimesh_uses_colors(mm->multimesh)) {
1200
state.canvas_instance_batches[state.current_batch_index].flags |= BATCH_FLAGS_INSTANCING_HAS_COLORS;
1201
}
1202
if (GLES3::MeshStorage::get_singleton()->multimesh_uses_custom_data(mm->multimesh)) {
1203
state.canvas_instance_batches[state.current_batch_index].flags |= BATCH_FLAGS_INSTANCING_HAS_CUSTOM_DATA;
1204
}
1205
} else if (c->type == Item::Command::TYPE_PARTICLES) {
1206
GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();
1207
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
1208
1209
const Item::CommandParticles *pt = static_cast<const Item::CommandParticles *>(c);
1210
RID particles = pt->particles;
1211
state.canvas_instance_batches[state.current_batch_index].tex = pt->texture;
1212
state.canvas_instance_batches[state.current_batch_index].specialization |= CanvasShaderGLES3::USE_INSTANCING;
1213
state.canvas_instance_batches[state.current_batch_index].flags |= BATCH_FLAGS_INSTANCING_HAS_COLORS;
1214
state.canvas_instance_batches[state.current_batch_index].flags |= BATCH_FLAGS_INSTANCING_HAS_CUSTOM_DATA;
1215
1216
if (particles_storage->particles_has_collision(particles) && texture_storage->render_target_is_sdf_enabled(p_render_target)) {
1217
// Pass collision information.
1218
Transform2D xform = p_item->final_transform;
1219
1220
GLuint sdf_texture = texture_storage->render_target_get_sdf_texture(p_render_target);
1221
1222
Rect2 to_screen;
1223
{
1224
Rect2 sdf_rect = texture_storage->render_target_get_sdf_rect(p_render_target);
1225
1226
to_screen.size = Vector2(1.0 / sdf_rect.size.width, 1.0 / sdf_rect.size.height);
1227
to_screen.position = -sdf_rect.position * to_screen.size;
1228
}
1229
1230
particles_storage->particles_set_canvas_sdf_collision(pt->particles, true, xform, to_screen, sdf_texture);
1231
} else {
1232
particles_storage->particles_set_canvas_sdf_collision(pt->particles, false, Transform2D(), Rect2(), 0);
1233
}
1234
r_sdf_used |= particles_storage->particles_has_collision(particles);
1235
}
1236
1237
state.canvas_instance_batches[state.current_batch_index].command = c;
1238
state.canvas_instance_batches[state.current_batch_index].command_type = c->type;
1239
1240
_prepare_canvas_texture(state.canvas_instance_batches[state.current_batch_index].tex, state.canvas_instance_batches[state.current_batch_index].filter, state.canvas_instance_batches[state.current_batch_index].repeat, r_index, texpixel_size);
1241
1242
state.instance_data_array[r_index].modulation[0] = base_color.r * modulate.r;
1243
state.instance_data_array[r_index].modulation[1] = base_color.g * modulate.g;
1244
state.instance_data_array[r_index].modulation[2] = base_color.b * modulate.b;
1245
state.instance_data_array[r_index].modulation[3] = base_color.a * modulate.a;
1246
1247
for (int j = 0; j < 4; j++) {
1248
state.instance_data_array[r_index].src_rect[j] = 0;
1249
state.instance_data_array[r_index].dst_rect[j] = 0;
1250
state.instance_data_array[r_index].ninepatch_margins[j] = 0;
1251
}
1252
_add_to_batch(r_index, r_batch_broken);
1253
} break;
1254
1255
case Item::Command::TYPE_TRANSFORM: {
1256
const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
1257
draw_transform = transform->xform;
1258
} break;
1259
1260
case Item::Command::TYPE_CLIP_IGNORE: {
1261
const Item::CommandClipIgnore *ci = static_cast<const Item::CommandClipIgnore *>(c);
1262
if (current_clip) {
1263
if (ci->ignore != reclip) {
1264
_new_batch(r_batch_broken);
1265
if (ci->ignore) {
1266
state.canvas_instance_batches[state.current_batch_index].clip = nullptr;
1267
reclip = true;
1268
} else {
1269
state.canvas_instance_batches[state.current_batch_index].clip = current_clip;
1270
reclip = false;
1271
}
1272
}
1273
}
1274
} break;
1275
1276
case Item::Command::TYPE_ANIMATION_SLICE: {
1277
const Item::CommandAnimationSlice *as = static_cast<const Item::CommandAnimationSlice *>(c);
1278
double current_time = RSG::rasterizer->get_total_time();
1279
double local_time = Math::fposmod(current_time - as->offset, as->animation_length);
1280
skipping = !(local_time >= as->slice_begin && local_time < as->slice_end);
1281
1282
RenderingServerDefault::redraw_request(); // animation visible means redraw request
1283
} break;
1284
}
1285
1286
c = c->next;
1287
r_batch_broken = false;
1288
}
1289
1290
if (current_clip && reclip) {
1291
//will make it re-enable clipping if needed afterwards
1292
current_clip = nullptr;
1293
}
1294
}
1295
1296
_FORCE_INLINE_ static uint32_t _indices_to_primitives(RS::PrimitiveType p_primitive, uint32_t p_indices) {
1297
static const uint32_t divisor[RS::PRIMITIVE_MAX] = { 1, 2, 1, 3, 1 };
1298
static const uint32_t subtractor[RS::PRIMITIVE_MAX] = { 0, 0, 1, 0, 2 };
1299
return (p_indices - subtractor[p_primitive]) / divisor[p_primitive];
1300
}
1301
1302
void RasterizerCanvasGLES3::_render_batch(Light *p_lights, uint32_t p_index, RenderingMethod::RenderInfo *r_render_info) {
1303
ERR_FAIL_NULL(state.canvas_instance_batches[state.current_batch_index].command);
1304
1305
// Used by Polygon and Mesh.
1306
static const GLenum prim[5] = { GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP };
1307
1308
_bind_canvas_texture(state.canvas_instance_batches[p_index].tex, state.canvas_instance_batches[p_index].filter, state.canvas_instance_batches[p_index].repeat);
1309
1310
switch (state.canvas_instance_batches[p_index].command_type) {
1311
case Item::Command::TYPE_RECT:
1312
case Item::Command::TYPE_NINEPATCH: {
1313
glBindVertexArray(data.indexed_quad_array);
1314
glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.canvas_instance_batches[p_index].instance_buffer_index]);
1315
uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData);
1316
_enable_attributes(range_start, false);
1317
1318
glDrawElementsInstanced(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr, state.canvas_instance_batches[p_index].instance_count);
1319
glBindVertexArray(0);
1320
1321
if (r_render_info) {
1322
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += state.canvas_instance_batches[p_index].instance_count;
1323
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += 2 * state.canvas_instance_batches[p_index].instance_count;
1324
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
1325
}
1326
1327
} break;
1328
1329
case Item::Command::TYPE_POLYGON: {
1330
const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(state.canvas_instance_batches[p_index].command);
1331
1332
PolygonBuffers *pb = polygon_buffers.polygons.getptr(polygon->polygon.polygon_id);
1333
ERR_FAIL_NULL(pb);
1334
1335
glBindVertexArray(pb->vertex_array);
1336
glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.canvas_instance_batches[p_index].instance_buffer_index]);
1337
1338
uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData);
1339
_enable_attributes(range_start, false);
1340
1341
if (pb->color_disabled && pb->color != Color(1.0, 1.0, 1.0, 1.0)) {
1342
glVertexAttrib4f(RS::ARRAY_COLOR, pb->color.r, pb->color.g, pb->color.b, pb->color.a);
1343
}
1344
1345
if (pb->index_buffer != 0) {
1346
glDrawElementsInstanced(prim[polygon->primitive], pb->count, GL_UNSIGNED_INT, nullptr, 1);
1347
} else {
1348
glDrawArraysInstanced(prim[polygon->primitive], 0, pb->count, 1);
1349
}
1350
glBindVertexArray(0);
1351
1352
if (pb->color_disabled && pb->color != Color(1.0, 1.0, 1.0, 1.0)) {
1353
// Reset so this doesn't pollute other draw calls.
1354
glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);
1355
}
1356
1357
if (r_render_info) {
1358
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME]++;
1359
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += _indices_to_primitives(polygon->primitive, pb->count);
1360
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
1361
}
1362
} break;
1363
1364
case Item::Command::TYPE_PRIMITIVE: {
1365
glBindVertexArray(data.canvas_quad_array);
1366
glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.canvas_instance_batches[p_index].instance_buffer_index]);
1367
uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData);
1368
_enable_attributes(range_start, true);
1369
1370
const GLenum primitive[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLES };
1371
int instance_count = state.canvas_instance_batches[p_index].instance_count;
1372
ERR_FAIL_COND(instance_count <= 0);
1373
if (instance_count >= 1) {
1374
glDrawArraysInstanced(primitive[state.canvas_instance_batches[p_index].primitive_points], 0, state.canvas_instance_batches[p_index].primitive_points, instance_count);
1375
}
1376
if (r_render_info) {
1377
const RenderingServer::PrimitiveType rs_primitive[5] = { RS::PRIMITIVE_POINTS, RS::PRIMITIVE_POINTS, RS::PRIMITIVE_LINES, RS::PRIMITIVE_TRIANGLES, RS::PRIMITIVE_TRIANGLES };
1378
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] += instance_count;
1379
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += _indices_to_primitives(rs_primitive[state.canvas_instance_batches[p_index].primitive_points], state.canvas_instance_batches[p_index].primitive_points) * instance_count;
1380
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
1381
}
1382
1383
} break;
1384
1385
case Item::Command::TYPE_MESH:
1386
case Item::Command::TYPE_MULTIMESH:
1387
case Item::Command::TYPE_PARTICLES: {
1388
GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();
1389
GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();
1390
RID mesh;
1391
RID mesh_instance;
1392
uint32_t instance_count = 1;
1393
GLuint instance_buffer = 0;
1394
uint32_t instance_stride = 0;
1395
uint32_t instance_color_offset = 0;
1396
bool instance_uses_color = false;
1397
bool instance_uses_custom_data = false;
1398
bool use_instancing = false;
1399
1400
if (state.canvas_instance_batches[p_index].command_type == Item::Command::TYPE_MESH) {
1401
const Item::CommandMesh *m = static_cast<const Item::CommandMesh *>(state.canvas_instance_batches[p_index].command);
1402
mesh = m->mesh;
1403
mesh_instance = m->mesh_instance;
1404
1405
} else if (state.canvas_instance_batches[p_index].command_type == Item::Command::TYPE_MULTIMESH) {
1406
const Item::CommandMultiMesh *mm = static_cast<const Item::CommandMultiMesh *>(state.canvas_instance_batches[p_index].command);
1407
RID multimesh = mm->multimesh;
1408
mesh = mesh_storage->multimesh_get_mesh(multimesh);
1409
1410
if (mesh_storage->multimesh_get_transform_format(multimesh) != RS::MULTIMESH_TRANSFORM_2D) {
1411
break;
1412
}
1413
1414
instance_count = mesh_storage->multimesh_get_instances_to_draw(multimesh);
1415
1416
if (instance_count == 0) {
1417
break;
1418
}
1419
1420
instance_buffer = mesh_storage->multimesh_get_gl_buffer(multimesh);
1421
instance_stride = mesh_storage->multimesh_get_stride(multimesh);
1422
instance_color_offset = mesh_storage->multimesh_get_color_offset(multimesh);
1423
instance_uses_color = mesh_storage->multimesh_uses_colors(multimesh);
1424
instance_uses_custom_data = mesh_storage->multimesh_uses_custom_data(multimesh);
1425
use_instancing = true;
1426
1427
} else if (state.canvas_instance_batches[p_index].command_type == Item::Command::TYPE_PARTICLES) {
1428
const Item::CommandParticles *pt = static_cast<const Item::CommandParticles *>(state.canvas_instance_batches[p_index].command);
1429
RID particles = pt->particles;
1430
mesh = particles_storage->particles_get_draw_pass_mesh(particles, 0);
1431
1432
ERR_BREAK(particles_storage->particles_get_mode(particles) != RS::PARTICLES_MODE_2D);
1433
particles_storage->particles_request_process(particles);
1434
1435
if (particles_storage->particles_is_inactive(particles)) {
1436
break;
1437
}
1438
1439
RenderingServerDefault::redraw_request(); // Active particles means redraw request.
1440
1441
int dpc = particles_storage->particles_get_draw_passes(particles);
1442
if (dpc == 0) {
1443
break; // Nothing to draw.
1444
}
1445
1446
instance_count = particles_storage->particles_get_amount(particles);
1447
instance_buffer = particles_storage->particles_get_gl_buffer(particles);
1448
instance_stride = 12; // 8 bytes for instance transform and 4 bytes for packed color and custom.
1449
instance_color_offset = 8; // 8 bytes for instance transform.
1450
instance_uses_color = true;
1451
instance_uses_custom_data = true;
1452
use_instancing = true;
1453
}
1454
1455
ERR_FAIL_COND(mesh.is_null());
1456
1457
uint32_t surf_count = mesh_storage->mesh_get_surface_count(mesh);
1458
1459
for (uint32_t j = 0; j < surf_count; j++) {
1460
void *surface = mesh_storage->mesh_get_surface(mesh, j);
1461
1462
RS::PrimitiveType primitive = mesh_storage->mesh_surface_get_primitive(surface);
1463
ERR_CONTINUE(primitive < 0 || primitive >= RS::PRIMITIVE_MAX);
1464
1465
GLuint vertex_array_gl = 0;
1466
GLuint index_array_gl = 0;
1467
1468
uint64_t vertex_input_mask = state.canvas_instance_batches[p_index].vertex_input_mask;
1469
1470
if (mesh_instance.is_valid()) {
1471
mesh_storage->mesh_instance_surface_get_vertex_arrays_and_format(mesh_instance, j, vertex_input_mask, vertex_array_gl);
1472
} else {
1473
mesh_storage->mesh_surface_get_vertex_arrays_and_format(surface, vertex_input_mask, vertex_array_gl);
1474
}
1475
1476
index_array_gl = mesh_storage->mesh_surface_get_index_buffer(surface, 0);
1477
bool use_index_buffer = false;
1478
glBindVertexArray(vertex_array_gl);
1479
glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.canvas_instance_batches[p_index].instance_buffer_index]);
1480
1481
uint32_t range_start = state.canvas_instance_batches[p_index].start * sizeof(InstanceData);
1482
_enable_attributes(range_start, false, instance_count);
1483
1484
if (index_array_gl != 0) {
1485
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_array_gl);
1486
use_index_buffer = true;
1487
}
1488
1489
if (use_instancing) {
1490
if (instance_buffer == 0) {
1491
break;
1492
}
1493
// Bind instance buffers.
1494
glBindBuffer(GL_ARRAY_BUFFER, instance_buffer);
1495
glEnableVertexAttribArray(1);
1496
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, instance_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(0));
1497
glVertexAttribDivisor(1, 1);
1498
glEnableVertexAttribArray(2);
1499
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, instance_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(4 * 4));
1500
glVertexAttribDivisor(2, 1);
1501
1502
if (instance_uses_color || instance_uses_custom_data) {
1503
glEnableVertexAttribArray(5);
1504
glVertexAttribIPointer(5, 4, GL_UNSIGNED_INT, instance_stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(instance_color_offset * sizeof(float)));
1505
glVertexAttribDivisor(5, 1);
1506
} else {
1507
// Set all default instance color and custom data values to 1.0 or 0.0 using a compressed format.
1508
uint16_t zero = Math::make_half_float(0.0f);
1509
uint16_t one = Math::make_half_float(1.0f);
1510
GLuint default_color = (uint32_t(one) << 16) | one;
1511
GLuint default_custom = (uint32_t(zero) << 16) | zero;
1512
glVertexAttribI4ui(5, default_color, default_color, default_custom, default_custom);
1513
}
1514
}
1515
1516
GLenum primitive_gl = prim[int(primitive)];
1517
1518
uint32_t vertex_count = mesh_storage->mesh_surface_get_vertices_drawn_count(surface);
1519
1520
if (use_index_buffer) {
1521
glDrawElementsInstanced(primitive_gl, vertex_count, mesh_storage->mesh_surface_get_index_type(surface), nullptr, instance_count);
1522
} else {
1523
glDrawArraysInstanced(primitive_gl, 0, vertex_count, instance_count);
1524
}
1525
glBindBuffer(GL_ARRAY_BUFFER, 0);
1526
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1527
if (use_instancing) {
1528
glDisableVertexAttribArray(5);
1529
glDisableVertexAttribArray(8);
1530
glDisableVertexAttribArray(9);
1531
glDisableVertexAttribArray(10);
1532
}
1533
if (r_render_info) {
1534
// Meshes, Particles, and MultiMesh are always just one object with one draw call.
1535
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME]++;
1536
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_PRIMITIVES_IN_FRAME] += _indices_to_primitives(primitive, vertex_count) * instance_count;
1537
r_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_CANVAS][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME]++;
1538
}
1539
}
1540
1541
} break;
1542
case Item::Command::TYPE_TRANSFORM:
1543
case Item::Command::TYPE_CLIP_IGNORE:
1544
case Item::Command::TYPE_ANIMATION_SLICE: {
1545
// Can ignore these as they only impact batch creation.
1546
} break;
1547
}
1548
}
1549
1550
void RasterizerCanvasGLES3::_add_to_batch(uint32_t &r_index, bool &r_batch_broken) {
1551
state.canvas_instance_batches[state.current_batch_index].instance_count++;
1552
r_index++;
1553
if (r_index + state.last_item_index >= data.max_instances_per_buffer) {
1554
// Copy over all data needed for rendering right away
1555
// then go back to recording item commands.
1556
glBindBuffer(GL_ARRAY_BUFFER, state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers[state.current_instance_buffer_index]);
1557
#ifdef WEB_ENABLED
1558
glBufferSubData(GL_ARRAY_BUFFER, state.last_item_index * sizeof(InstanceData), sizeof(InstanceData) * r_index, state.instance_data_array);
1559
#else
1560
// On Desktop and mobile we map the memory without synchronizing for maximum speed.
1561
void *buffer = glMapBufferRange(GL_ARRAY_BUFFER, state.last_item_index * sizeof(InstanceData), r_index * sizeof(InstanceData), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
1562
memcpy(buffer, state.instance_data_array, r_index * sizeof(InstanceData));
1563
glUnmapBuffer(GL_ARRAY_BUFFER);
1564
#endif
1565
_allocate_instance_buffer();
1566
r_index = 0;
1567
state.last_item_index = 0;
1568
r_batch_broken = false; // Force a new batch to be created
1569
_new_batch(r_batch_broken);
1570
state.canvas_instance_batches[state.current_batch_index].start = 0;
1571
}
1572
}
1573
1574
void RasterizerCanvasGLES3::_new_batch(bool &r_batch_broken) {
1575
if (state.canvas_instance_batches.is_empty()) {
1576
Batch new_batch;
1577
new_batch.instance_buffer_index = state.current_instance_buffer_index;
1578
state.canvas_instance_batches.push_back(new_batch);
1579
return;
1580
}
1581
1582
if (r_batch_broken || state.canvas_instance_batches[state.current_batch_index].instance_count == 0) {
1583
return;
1584
}
1585
1586
r_batch_broken = true;
1587
1588
// Copy the properties of the current batch, we will manually update the things that changed.
1589
Batch new_batch = state.canvas_instance_batches[state.current_batch_index];
1590
new_batch.instance_count = 0;
1591
new_batch.start = state.canvas_instance_batches[state.current_batch_index].start + state.canvas_instance_batches[state.current_batch_index].instance_count;
1592
new_batch.instance_buffer_index = state.current_instance_buffer_index;
1593
state.current_batch_index++;
1594
state.canvas_instance_batches.push_back(new_batch);
1595
}
1596
1597
void RasterizerCanvasGLES3::_enable_attributes(uint32_t p_start, bool p_primitive, uint32_t p_rate) {
1598
uint32_t split = p_primitive ? 13 : 14;
1599
for (uint32_t i = 8; i < split; i++) {
1600
glEnableVertexAttribArray(i);
1601
glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 8) * 4 * sizeof(float)));
1602
glVertexAttribDivisor(i, p_rate);
1603
}
1604
for (uint32_t i = split; i <= 15; i++) {
1605
glEnableVertexAttribArray(i);
1606
glVertexAttribIPointer(i, 4, GL_UNSIGNED_INT, sizeof(InstanceData), CAST_INT_TO_UCHAR_PTR(p_start + (i - 8) * 4 * sizeof(float)));
1607
glVertexAttribDivisor(i, p_rate);
1608
}
1609
}
1610
RID RasterizerCanvasGLES3::light_create() {
1611
CanvasLight canvas_light;
1612
return canvas_light_owner.make_rid(canvas_light);
1613
}
1614
1615
void RasterizerCanvasGLES3::light_set_texture(RID p_rid, RID p_texture) {
1616
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
1617
1618
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
1619
ERR_FAIL_NULL(cl);
1620
if (cl->texture == p_texture) {
1621
return;
1622
}
1623
1624
ERR_FAIL_COND(p_texture.is_valid() && !texture_storage->owns_texture(p_texture));
1625
1626
if (cl->texture.is_valid()) {
1627
texture_storage->texture_remove_from_texture_atlas(cl->texture);
1628
}
1629
cl->texture = p_texture;
1630
1631
if (cl->texture.is_valid()) {
1632
texture_storage->texture_add_to_texture_atlas(cl->texture);
1633
}
1634
}
1635
1636
void RasterizerCanvasGLES3::light_set_use_shadow(RID p_rid, bool p_enable) {
1637
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
1638
ERR_FAIL_NULL(cl);
1639
1640
cl->shadow.enabled = p_enable;
1641
}
1642
1643
void RasterizerCanvasGLES3::light_update_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, const Rect2 &p_light_rect) {
1644
GLES3::Config *config = GLES3::Config::get_singleton();
1645
1646
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
1647
ERR_FAIL_COND(!cl->shadow.enabled);
1648
1649
_update_shadow_atlas();
1650
1651
cl->shadow.z_far = p_far;
1652
cl->shadow.y_offset = float(p_shadow_index * 2 + 1) / float(data.max_lights_per_render * 2);
1653
1654
glBindFramebuffer(GL_FRAMEBUFFER, state.shadow_fb);
1655
glViewport(0, p_shadow_index * 2, state.shadow_texture_size, 2);
1656
1657
glDepthMask(GL_TRUE);
1658
glEnable(GL_DEPTH_TEST);
1659
glDepthFunc(GL_LESS);
1660
glDisable(GL_BLEND);
1661
1662
glEnable(GL_SCISSOR_TEST);
1663
glScissor(0, p_shadow_index * 2, state.shadow_texture_size, 2);
1664
glClearColor(p_far, p_far, p_far, 1.0);
1665
RasterizerGLES3::clear_depth(1.0);
1666
1667
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1668
1669
glCullFace(GL_BACK);
1670
glDisable(GL_CULL_FACE);
1671
RS::CanvasOccluderPolygonCullMode cull_mode = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
1672
1673
CanvasOcclusionShaderGLES3::ShaderVariant variant = config->float_texture_supported ? CanvasOcclusionShaderGLES3::MODE_SHADOW : CanvasOcclusionShaderGLES3::MODE_SHADOW_RGBA;
1674
bool success = shadow_render.shader.version_bind_shader(shadow_render.shader_version, variant);
1675
if (!success) {
1676
return;
1677
}
1678
1679
Projection projection;
1680
{
1681
real_t fov = 90;
1682
real_t nearp = p_near;
1683
real_t farp = p_far;
1684
real_t aspect = 1.0;
1685
1686
real_t ymax = nearp * Math::tan(Math::deg_to_rad(fov * 0.5));
1687
real_t ymin = -ymax;
1688
real_t xmin = ymin * aspect;
1689
real_t xmax = ymax * aspect;
1690
1691
projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp);
1692
}
1693
1694
// Precomputed:
1695
// Vector3 cam_target = Basis::from_euler(Vector3(0, 0, Math::TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0));
1696
// projection = projection * Projection(Transform3D().looking_at(cam_targets[i], Vector3(0, 0, -1)).affine_inverse());
1697
const Projection projections[4] = {
1698
projection * Projection(Vector4(0, 0, -1, 0), Vector4(1, 0, 0, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)),
1699
1700
projection * Projection(Vector4(-1, 0, 0, 0), Vector4(0, 0, -1, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)),
1701
1702
projection * Projection(Vector4(0, 0, 1, 0), Vector4(-1, 0, 0, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1)),
1703
1704
projection * Projection(Vector4(1, 0, 0, 0), Vector4(0, 0, 1, 0), Vector4(0, -1, 0, 0), Vector4(0, 0, 0, 1))
1705
1706
};
1707
1708
for (int i = 0; i < 4; i++) {
1709
glViewport((state.shadow_texture_size / 4) * i, p_shadow_index * 2, (state.shadow_texture_size / 4), 2);
1710
1711
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::PROJECTION, projections[i], shadow_render.shader_version, variant);
1712
1713
static const Vector2 directions[4] = { Vector2(1, 0), Vector2(0, 1), Vector2(-1, 0), Vector2(0, -1) };
1714
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::DIRECTION, directions[i].x, directions[i].y, shadow_render.shader_version, variant);
1715
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::Z_FAR, p_far, shadow_render.shader_version, variant);
1716
1717
LightOccluderInstance *instance = p_occluders;
1718
1719
while (instance) {
1720
OccluderPolygon *co = occluder_polygon_owner.get_or_null(instance->occluder);
1721
1722
if (!co || co->vertex_array == 0 || !(p_light_mask & instance->light_mask)) {
1723
instance = instance->next;
1724
continue;
1725
}
1726
1727
Transform2D modelview = p_light_xform * instance->xform_cache;
1728
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::MODELVIEW1, modelview.columns[0][0], modelview.columns[1][0], 0, modelview.columns[2][0], shadow_render.shader_version, variant);
1729
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::MODELVIEW2, modelview.columns[0][1], modelview.columns[1][1], 0, modelview.columns[2][1], shadow_render.shader_version, variant);
1730
1731
if (co->cull_mode != cull_mode) {
1732
if (co->cull_mode == RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED) {
1733
glDisable(GL_CULL_FACE);
1734
} else {
1735
if (cull_mode == RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED) {
1736
// Last time was disabled, so enable and set proper face.
1737
glEnable(GL_CULL_FACE);
1738
}
1739
glCullFace(co->cull_mode == RS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE ? GL_FRONT : GL_BACK);
1740
}
1741
cull_mode = co->cull_mode;
1742
}
1743
1744
glBindVertexArray(co->vertex_array);
1745
glDrawElements(GL_TRIANGLES, 3 * co->line_point_count, GL_UNSIGNED_SHORT, nullptr);
1746
1747
instance = instance->next;
1748
}
1749
}
1750
1751
glBindVertexArray(0);
1752
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
1753
glDepthMask(GL_FALSE);
1754
glDisable(GL_DEPTH_TEST);
1755
glDisable(GL_SCISSOR_TEST);
1756
}
1757
1758
void RasterizerCanvasGLES3::light_update_directional_shadow(RID p_rid, int p_shadow_index, const Transform2D &p_light_xform, int p_light_mask, float p_cull_distance, const Rect2 &p_clip_rect, LightOccluderInstance *p_occluders) {
1759
GLES3::Config *config = GLES3::Config::get_singleton();
1760
1761
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
1762
ERR_FAIL_COND(!cl->shadow.enabled);
1763
1764
_update_shadow_atlas();
1765
1766
Vector2 light_dir = p_light_xform.columns[1].normalized();
1767
1768
Vector2 center = p_clip_rect.get_center();
1769
1770
float to_edge_distance = Math::abs(light_dir.dot(p_clip_rect.get_support(-light_dir)) - light_dir.dot(center));
1771
1772
Vector2 from_pos = center - light_dir * (to_edge_distance + p_cull_distance);
1773
float distance = to_edge_distance * 2.0 + p_cull_distance;
1774
float half_size = p_clip_rect.size.length() * 0.5; //shadow length, must keep this no matter the angle
1775
1776
cl->shadow.z_far = distance;
1777
cl->shadow.y_offset = float(p_shadow_index * 2 + 1) / float(data.max_lights_per_render * 2);
1778
1779
Transform2D to_light_xform;
1780
1781
to_light_xform[2] = from_pos;
1782
to_light_xform[1] = light_dir;
1783
to_light_xform[0] = -light_dir.orthogonal();
1784
1785
to_light_xform.invert();
1786
1787
glBindFramebuffer(GL_FRAMEBUFFER, state.shadow_fb);
1788
glViewport(0, p_shadow_index * 2, state.shadow_texture_size, 2);
1789
1790
glDepthMask(GL_TRUE);
1791
glEnable(GL_DEPTH_TEST);
1792
glDepthFunc(GL_LESS);
1793
glDisable(GL_BLEND);
1794
1795
glEnable(GL_SCISSOR_TEST);
1796
glScissor(0, p_shadow_index * 2, state.shadow_texture_size, 2);
1797
glClearColor(1.0, 1.0, 1.0, 1.0);
1798
RasterizerGLES3::clear_depth(1.0);
1799
1800
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1801
1802
glCullFace(GL_BACK);
1803
glDisable(GL_CULL_FACE);
1804
RS::CanvasOccluderPolygonCullMode cull_mode = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
1805
1806
CanvasOcclusionShaderGLES3::ShaderVariant variant = config->float_texture_supported ? CanvasOcclusionShaderGLES3::MODE_SHADOW : CanvasOcclusionShaderGLES3::MODE_SHADOW_RGBA;
1807
bool success = shadow_render.shader.version_bind_shader(shadow_render.shader_version, variant);
1808
if (!success) {
1809
return;
1810
}
1811
1812
Projection projection;
1813
projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance);
1814
projection = projection * Projection(Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse());
1815
1816
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::PROJECTION, projection, shadow_render.shader_version, variant);
1817
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::DIRECTION, 0.0, 1.0, shadow_render.shader_version, variant);
1818
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::Z_FAR, distance, shadow_render.shader_version, variant);
1819
1820
LightOccluderInstance *instance = p_occluders;
1821
1822
while (instance) {
1823
OccluderPolygon *co = occluder_polygon_owner.get_or_null(instance->occluder);
1824
1825
if (!co || co->vertex_array == 0 || !(p_light_mask & instance->light_mask)) {
1826
instance = instance->next;
1827
continue;
1828
}
1829
1830
Transform2D modelview = to_light_xform * instance->xform_cache;
1831
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::MODELVIEW1, modelview.columns[0][0], modelview.columns[1][0], 0, modelview.columns[2][0], shadow_render.shader_version, variant);
1832
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::MODELVIEW2, modelview.columns[0][1], modelview.columns[1][1], 0, modelview.columns[2][1], shadow_render.shader_version, variant);
1833
1834
if (co->cull_mode != cull_mode) {
1835
if (co->cull_mode == RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED) {
1836
glDisable(GL_CULL_FACE);
1837
} else {
1838
if (cull_mode == RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED) {
1839
// Last time was disabled, so enable and set proper face.
1840
glEnable(GL_CULL_FACE);
1841
}
1842
glCullFace(co->cull_mode == RS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE ? GL_FRONT : GL_BACK);
1843
}
1844
cull_mode = co->cull_mode;
1845
}
1846
1847
glBindVertexArray(co->vertex_array);
1848
glDrawElements(GL_TRIANGLES, 3 * co->line_point_count, GL_UNSIGNED_SHORT, nullptr);
1849
1850
instance = instance->next;
1851
}
1852
1853
Transform2D to_shadow;
1854
to_shadow.columns[0].x = 1.0 / -(half_size * 2.0);
1855
to_shadow.columns[2].x = 0.5;
1856
1857
cl->shadow.directional_xform = to_shadow * to_light_xform;
1858
1859
glBindVertexArray(0);
1860
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
1861
glDepthMask(GL_FALSE);
1862
glDisable(GL_DEPTH_TEST);
1863
glDisable(GL_SCISSOR_TEST);
1864
glDisable(GL_CULL_FACE);
1865
}
1866
1867
void RasterizerCanvasGLES3::_update_shadow_atlas() {
1868
GLES3::Config *config = GLES3::Config::get_singleton();
1869
1870
if (state.shadow_fb == 0) {
1871
glActiveTexture(GL_TEXTURE0);
1872
1873
glGenFramebuffers(1, &state.shadow_fb);
1874
glBindFramebuffer(GL_FRAMEBUFFER, state.shadow_fb);
1875
1876
glGenRenderbuffers(1, &state.shadow_depth_buffer);
1877
glBindRenderbuffer(GL_RENDERBUFFER, state.shadow_depth_buffer);
1878
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, state.shadow_texture_size, data.max_lights_per_render * 2);
1879
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, state.shadow_depth_buffer);
1880
1881
glGenTextures(1, &state.shadow_texture);
1882
glBindTexture(GL_TEXTURE_2D, state.shadow_texture);
1883
if (config->float_texture_supported) {
1884
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, state.shadow_texture_size, data.max_lights_per_render * 2, 0, GL_RED, GL_FLOAT, nullptr);
1885
} else {
1886
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, state.shadow_texture_size, data.max_lights_per_render * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1887
}
1888
1889
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1890
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1891
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1892
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1893
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
1894
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1895
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, state.shadow_texture, 0);
1896
1897
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
1898
if (status != GL_FRAMEBUFFER_COMPLETE) {
1899
glDeleteFramebuffers(1, &state.shadow_fb);
1900
glDeleteTextures(1, &state.shadow_texture);
1901
glDeleteRenderbuffers(1, &state.shadow_depth_buffer);
1902
state.shadow_fb = 0;
1903
state.shadow_texture = 0;
1904
state.shadow_depth_buffer = 0;
1905
WARN_PRINT("Could not create CanvasItem shadow atlas, status: " + GLES3::TextureStorage::get_singleton()->get_framebuffer_error(status));
1906
}
1907
GLES3::Utilities::get_singleton()->texture_allocated_data(state.shadow_texture, state.shadow_texture_size * data.max_lights_per_render * 2 * 4, "2D shadow atlas texture");
1908
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
1909
}
1910
}
1911
1912
void RasterizerCanvasGLES3::render_sdf(RID p_render_target, LightOccluderInstance *p_occluders) {
1913
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
1914
1915
GLuint fb = texture_storage->render_target_get_sdf_framebuffer(p_render_target);
1916
Rect2i rect = texture_storage->render_target_get_sdf_rect(p_render_target);
1917
1918
Transform2D to_sdf;
1919
to_sdf.columns[0] *= rect.size.width;
1920
to_sdf.columns[1] *= rect.size.height;
1921
to_sdf.columns[2] = rect.position;
1922
1923
Transform2D to_clip;
1924
to_clip.columns[0] *= 2.0;
1925
to_clip.columns[1] *= 2.0;
1926
to_clip.columns[2] = -Vector2(1.0, 1.0);
1927
1928
to_clip = to_clip * to_sdf.affine_inverse();
1929
1930
glBindFramebuffer(GL_FRAMEBUFFER, fb);
1931
glViewport(0, 0, rect.size.width, rect.size.height);
1932
1933
glDepthMask(GL_FALSE);
1934
glDisable(GL_DEPTH_TEST);
1935
glDisable(GL_BLEND);
1936
glDisable(GL_CULL_FACE);
1937
glDisable(GL_SCISSOR_TEST);
1938
1939
glClearColor(0.0, 0.0, 0.0, 0.0);
1940
glClear(GL_COLOR_BUFFER_BIT);
1941
1942
CanvasOcclusionShaderGLES3::ShaderVariant variant = CanvasOcclusionShaderGLES3::MODE_SDF;
1943
bool success = shadow_render.shader.version_bind_shader(shadow_render.shader_version, variant);
1944
if (!success) {
1945
return;
1946
}
1947
1948
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::PROJECTION, Projection(), shadow_render.shader_version, variant);
1949
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::DIRECTION, 0.0, 0.0, shadow_render.shader_version, variant);
1950
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::Z_FAR, 0.0, shadow_render.shader_version, variant);
1951
1952
LightOccluderInstance *instance = p_occluders;
1953
1954
while (instance) {
1955
OccluderPolygon *oc = occluder_polygon_owner.get_or_null(instance->occluder);
1956
1957
if (!oc || oc->sdf_vertex_array == 0 || !instance->sdf_collision) {
1958
instance = instance->next;
1959
continue;
1960
}
1961
1962
Transform2D modelview = to_clip * instance->xform_cache;
1963
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::MODELVIEW1, modelview.columns[0][0], modelview.columns[1][0], 0, modelview.columns[2][0], shadow_render.shader_version, variant);
1964
shadow_render.shader.version_set_uniform(CanvasOcclusionShaderGLES3::MODELVIEW2, modelview.columns[0][1], modelview.columns[1][1], 0, modelview.columns[2][1], shadow_render.shader_version, variant);
1965
1966
glBindVertexArray(oc->sdf_vertex_array);
1967
glDrawElements(oc->sdf_is_lines ? GL_LINES : GL_TRIANGLES, oc->sdf_index_count, GL_UNSIGNED_INT, nullptr);
1968
1969
instance = instance->next;
1970
}
1971
1972
texture_storage->render_target_sdf_process(p_render_target); //done rendering, process it
1973
glBindVertexArray(0);
1974
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
1975
}
1976
1977
RID RasterizerCanvasGLES3::occluder_polygon_create() {
1978
OccluderPolygon occluder;
1979
1980
return occluder_polygon_owner.make_rid(occluder);
1981
}
1982
1983
void RasterizerCanvasGLES3::occluder_polygon_set_shape(RID p_occluder, const Vector<Vector2> &p_points, bool p_closed) {
1984
OccluderPolygon *oc = occluder_polygon_owner.get_or_null(p_occluder);
1985
ERR_FAIL_NULL(oc);
1986
1987
Vector<Vector2> lines;
1988
1989
if (p_points.size()) {
1990
int lc = p_points.size() * 2;
1991
1992
lines.resize(lc - (p_closed ? 0 : 2));
1993
{
1994
Vector2 *w = lines.ptrw();
1995
const Vector2 *r = p_points.ptr();
1996
1997
int max = lc / 2;
1998
if (!p_closed) {
1999
max--;
2000
}
2001
for (int i = 0; i < max; i++) {
2002
Vector2 a = r[i];
2003
Vector2 b = r[(i + 1) % (lc / 2)];
2004
w[i * 2 + 0] = a;
2005
w[i * 2 + 1] = b;
2006
}
2007
}
2008
}
2009
2010
if (oc->line_point_count != lines.size() && oc->vertex_array != 0) {
2011
glDeleteVertexArrays(1, &oc->vertex_array);
2012
GLES3::Utilities::get_singleton()->buffer_free_data(oc->vertex_buffer);
2013
GLES3::Utilities::get_singleton()->buffer_free_data(oc->index_buffer);
2014
2015
oc->vertex_array = 0;
2016
oc->vertex_buffer = 0;
2017
oc->index_buffer = 0;
2018
}
2019
2020
if (lines.size()) {
2021
Vector<uint8_t> geometry;
2022
Vector<uint8_t> indices;
2023
int lc = lines.size();
2024
2025
geometry.resize(lc * 6 * sizeof(float));
2026
indices.resize(lc * 3 * sizeof(uint16_t));
2027
2028
{
2029
uint8_t *vw = geometry.ptrw();
2030
float *vwptr = reinterpret_cast<float *>(vw);
2031
uint8_t *iw = indices.ptrw();
2032
uint16_t *iwptr = (uint16_t *)iw;
2033
2034
const Vector2 *lr = lines.ptr();
2035
2036
const int POLY_HEIGHT = 16384;
2037
2038
for (int i = 0; i < lc / 2; i++) {
2039
vwptr[i * 12 + 0] = lr[i * 2 + 0].x;
2040
vwptr[i * 12 + 1] = lr[i * 2 + 0].y;
2041
vwptr[i * 12 + 2] = POLY_HEIGHT;
2042
2043
vwptr[i * 12 + 3] = lr[i * 2 + 1].x;
2044
vwptr[i * 12 + 4] = lr[i * 2 + 1].y;
2045
vwptr[i * 12 + 5] = POLY_HEIGHT;
2046
2047
vwptr[i * 12 + 6] = lr[i * 2 + 1].x;
2048
vwptr[i * 12 + 7] = lr[i * 2 + 1].y;
2049
vwptr[i * 12 + 8] = -POLY_HEIGHT;
2050
2051
vwptr[i * 12 + 9] = lr[i * 2 + 0].x;
2052
vwptr[i * 12 + 10] = lr[i * 2 + 0].y;
2053
vwptr[i * 12 + 11] = -POLY_HEIGHT;
2054
2055
iwptr[i * 6 + 0] = i * 4 + 0;
2056
iwptr[i * 6 + 1] = i * 4 + 1;
2057
iwptr[i * 6 + 2] = i * 4 + 2;
2058
2059
iwptr[i * 6 + 3] = i * 4 + 2;
2060
iwptr[i * 6 + 4] = i * 4 + 3;
2061
iwptr[i * 6 + 5] = i * 4 + 0;
2062
}
2063
}
2064
2065
if (oc->vertex_array == 0) {
2066
oc->line_point_count = lc;
2067
glGenVertexArrays(1, &oc->vertex_array);
2068
glBindVertexArray(oc->vertex_array);
2069
glGenBuffers(1, &oc->vertex_buffer);
2070
glBindBuffer(GL_ARRAY_BUFFER, oc->vertex_buffer);
2071
2072
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, oc->vertex_buffer, lc * 6 * sizeof(float), geometry.ptr(), GL_STATIC_DRAW, "Occluder polygon vertex buffer");
2073
2074
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
2075
glVertexAttribPointer(RS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
2076
2077
glGenBuffers(1, &oc->index_buffer);
2078
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oc->index_buffer);
2079
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, oc->index_buffer, 3 * lc * sizeof(uint16_t), indices.ptr(), GL_STATIC_DRAW, "Occluder polygon index buffer");
2080
2081
glBindVertexArray(0);
2082
} else {
2083
glBindBuffer(GL_ARRAY_BUFFER, oc->vertex_buffer);
2084
glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(float), geometry.ptr(), GL_STATIC_DRAW);
2085
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oc->index_buffer);
2086
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * lc * sizeof(uint16_t), indices.ptr(), GL_STATIC_DRAW);
2087
glBindBuffer(GL_ARRAY_BUFFER, 0);
2088
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2089
}
2090
}
2091
2092
// sdf
2093
2094
Vector<int> sdf_indices;
2095
2096
if (p_points.size()) {
2097
if (p_closed) {
2098
sdf_indices = Geometry2D::triangulate_polygon(p_points);
2099
oc->sdf_is_lines = false;
2100
} else {
2101
int max = p_points.size();
2102
sdf_indices.resize(max * 2);
2103
2104
int *iw = sdf_indices.ptrw();
2105
for (int i = 0; i < max; i++) {
2106
iw[i * 2 + 0] = i;
2107
iw[i * 2 + 1] = (i + 1) % max;
2108
}
2109
oc->sdf_is_lines = true;
2110
}
2111
}
2112
2113
if (oc->sdf_index_count != sdf_indices.size() && oc->sdf_point_count != p_points.size() && oc->sdf_vertex_array != 0) {
2114
glDeleteVertexArrays(1, &oc->sdf_vertex_array);
2115
GLES3::Utilities::get_singleton()->buffer_free_data(oc->sdf_vertex_buffer);
2116
GLES3::Utilities::get_singleton()->buffer_free_data(oc->sdf_index_buffer);
2117
2118
oc->sdf_vertex_array = 0;
2119
oc->sdf_vertex_buffer = 0;
2120
oc->sdf_index_buffer = 0;
2121
2122
oc->sdf_index_count = sdf_indices.size();
2123
oc->sdf_point_count = p_points.size();
2124
}
2125
2126
if (sdf_indices.size()) {
2127
if (oc->sdf_vertex_array == 0) {
2128
oc->sdf_index_count = sdf_indices.size();
2129
oc->sdf_point_count = p_points.size();
2130
glGenVertexArrays(1, &oc->sdf_vertex_array);
2131
glBindVertexArray(oc->sdf_vertex_array);
2132
glGenBuffers(1, &oc->sdf_vertex_buffer);
2133
glBindBuffer(GL_ARRAY_BUFFER, oc->sdf_vertex_buffer);
2134
2135
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, oc->sdf_vertex_buffer, oc->sdf_point_count * 2 * sizeof(float), p_points.ptr(), GL_STATIC_DRAW, "Occluder polygon SDF vertex buffer");
2136
2137
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
2138
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), nullptr);
2139
2140
glGenBuffers(1, &oc->sdf_index_buffer);
2141
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oc->sdf_index_buffer);
2142
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, oc->sdf_index_buffer, oc->sdf_index_count * sizeof(uint32_t), sdf_indices.ptr(), GL_STATIC_DRAW, "Occluder polygon SDF index buffer");
2143
2144
glBindVertexArray(0);
2145
} else {
2146
glBindBuffer(GL_ARRAY_BUFFER, oc->sdf_vertex_buffer);
2147
glBufferData(GL_ARRAY_BUFFER, p_points.size() * 2 * sizeof(float), p_points.ptr(), GL_STATIC_DRAW);
2148
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, oc->sdf_index_buffer);
2149
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sdf_indices.size() * sizeof(uint32_t), sdf_indices.ptr(), GL_STATIC_DRAW);
2150
glBindBuffer(GL_ARRAY_BUFFER, 0);
2151
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2152
}
2153
}
2154
}
2155
2156
void RasterizerCanvasGLES3::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) {
2157
OccluderPolygon *oc = occluder_polygon_owner.get_or_null(p_occluder);
2158
ERR_FAIL_NULL(oc);
2159
oc->cull_mode = p_mode;
2160
}
2161
2162
void RasterizerCanvasGLES3::set_shadow_texture_size(int p_size) {
2163
GLES3::Config *config = GLES3::Config::get_singleton();
2164
p_size = nearest_power_of_2_templated(p_size);
2165
2166
if (p_size > config->max_texture_size) {
2167
p_size = config->max_texture_size;
2168
WARN_PRINT("Attempting to set CanvasItem shadow atlas size to " + itos(p_size) + " which is beyond limit of " + itos(config->max_texture_size) + "supported by hardware.");
2169
}
2170
2171
if (p_size == state.shadow_texture_size) {
2172
return;
2173
}
2174
state.shadow_texture_size = p_size;
2175
2176
if (state.shadow_fb != 0) {
2177
glDeleteFramebuffers(1, &state.shadow_fb);
2178
GLES3::Utilities::get_singleton()->texture_free_data(state.shadow_texture);
2179
glDeleteRenderbuffers(1, &state.shadow_depth_buffer);
2180
state.shadow_fb = 0;
2181
state.shadow_texture = 0;
2182
state.shadow_depth_buffer = 0;
2183
}
2184
_update_shadow_atlas();
2185
}
2186
2187
bool RasterizerCanvasGLES3::free(RID p_rid) {
2188
if (canvas_light_owner.owns(p_rid)) {
2189
CanvasLight *cl = canvas_light_owner.get_or_null(p_rid);
2190
ERR_FAIL_NULL_V(cl, false);
2191
canvas_light_owner.free(p_rid);
2192
} else if (occluder_polygon_owner.owns(p_rid)) {
2193
occluder_polygon_set_shape(p_rid, Vector<Vector2>(), false);
2194
occluder_polygon_owner.free(p_rid);
2195
} else {
2196
return false;
2197
}
2198
2199
return true;
2200
}
2201
2202
void RasterizerCanvasGLES3::update() {
2203
}
2204
2205
void RasterizerCanvasGLES3::canvas_begin(RID p_to_render_target, bool p_to_backbuffer, bool p_backbuffer_has_mipmaps) {
2206
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
2207
GLES3::Config *config = GLES3::Config::get_singleton();
2208
2209
GLES3::RenderTarget *render_target = texture_storage->get_render_target(p_to_render_target);
2210
2211
if (p_to_backbuffer) {
2212
glBindFramebuffer(GL_FRAMEBUFFER, render_target->backbuffer_fbo);
2213
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 4);
2214
GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE));
2215
glBindTexture(GL_TEXTURE_2D, tex->tex_id);
2216
} else {
2217
glBindFramebuffer(GL_FRAMEBUFFER, render_target->fbo);
2218
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 4);
2219
glBindTexture(GL_TEXTURE_2D, render_target->backbuffer);
2220
if (render_target->backbuffer != 0) {
2221
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, p_backbuffer_has_mipmaps ? render_target->mipmap_count - 1 : 0);
2222
}
2223
}
2224
2225
if (render_target->is_transparent || p_to_backbuffer) {
2226
state.transparent_render_target = true;
2227
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
2228
} else {
2229
state.transparent_render_target = false;
2230
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
2231
}
2232
2233
if (render_target && render_target->clear_requested) {
2234
const Color &col = render_target->clear_color;
2235
glClearColor(col.r, col.g, col.b, render_target->is_transparent ? col.a : 1.0f);
2236
2237
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2238
render_target->clear_requested = false;
2239
}
2240
2241
glActiveTexture(GL_TEXTURE0);
2242
GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE));
2243
glBindTexture(GL_TEXTURE_2D, tex->tex_id);
2244
}
2245
2246
void RasterizerCanvasGLES3::_bind_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat) {
2247
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
2248
GLES3::Config *config = GLES3::Config::get_singleton();
2249
2250
if (p_texture == RID()) {
2251
p_texture = default_canvas_texture;
2252
}
2253
2254
if (state.current_tex == p_texture && state.current_filter_mode == p_base_filter && state.current_repeat_mode == p_base_repeat) {
2255
return;
2256
}
2257
2258
state.current_tex = p_texture;
2259
state.current_filter_mode = p_base_filter;
2260
state.current_repeat_mode = p_base_repeat;
2261
2262
GLES3::CanvasTexture *ct = nullptr;
2263
2264
GLES3::Texture *t = texture_storage->get_texture(p_texture);
2265
2266
if (t) {
2267
ERR_FAIL_NULL(t->canvas_texture);
2268
ct = t->canvas_texture;
2269
if (t->render_target) {
2270
t->render_target->used_in_frame = true;
2271
}
2272
} else {
2273
ct = texture_storage->get_canvas_texture(p_texture);
2274
}
2275
2276
if (!ct) {
2277
// Invalid Texture RID.
2278
_bind_canvas_texture(default_canvas_texture, p_base_filter, p_base_repeat);
2279
return;
2280
}
2281
2282
RS::CanvasItemTextureFilter filter = ct->texture_filter != RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT ? ct->texture_filter : p_base_filter;
2283
ERR_FAIL_COND(filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT);
2284
2285
RS::CanvasItemTextureRepeat repeat = ct->texture_repeat != RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT ? ct->texture_repeat : p_base_repeat;
2286
ERR_FAIL_COND(repeat == RS::CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT);
2287
2288
GLES3::Texture *texture = texture_storage->get_texture(ct->diffuse);
2289
2290
if (!texture) {
2291
GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE));
2292
glActiveTexture(GL_TEXTURE0);
2293
glBindTexture(GL_TEXTURE_2D, tex->tex_id);
2294
} else {
2295
glActiveTexture(GL_TEXTURE0);
2296
glBindTexture(GL_TEXTURE_2D, texture->tex_id);
2297
texture->gl_set_filter(filter);
2298
texture->gl_set_repeat(repeat);
2299
if (texture->render_target) {
2300
texture->render_target->used_in_frame = true;
2301
}
2302
}
2303
2304
GLES3::Texture *normal_map = texture_storage->get_texture(ct->normal_map);
2305
2306
if (!normal_map) {
2307
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 6);
2308
GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_NORMAL));
2309
glBindTexture(GL_TEXTURE_2D, tex->tex_id);
2310
} else {
2311
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 6);
2312
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
2313
normal_map->gl_set_filter(filter);
2314
normal_map->gl_set_repeat(repeat);
2315
if (normal_map->render_target) {
2316
normal_map->render_target->used_in_frame = true;
2317
}
2318
}
2319
2320
GLES3::Texture *specular_map = texture_storage->get_texture(ct->specular);
2321
2322
if (!specular_map) {
2323
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 7);
2324
GLES3::Texture *tex = texture_storage->get_texture(texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE));
2325
glBindTexture(GL_TEXTURE_2D, tex->tex_id);
2326
} else {
2327
glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 7);
2328
glBindTexture(GL_TEXTURE_2D, specular_map->tex_id);
2329
specular_map->gl_set_filter(filter);
2330
specular_map->gl_set_repeat(repeat);
2331
if (specular_map->render_target) {
2332
specular_map->render_target->used_in_frame = true;
2333
}
2334
}
2335
}
2336
2337
void RasterizerCanvasGLES3::_prepare_canvas_texture(RID p_texture, RS::CanvasItemTextureFilter p_base_filter, RS::CanvasItemTextureRepeat p_base_repeat, uint32_t &r_index, Size2 &r_texpixel_size) {
2338
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
2339
2340
if (p_texture == RID()) {
2341
p_texture = default_canvas_texture;
2342
}
2343
2344
GLES3::CanvasTexture *ct = nullptr;
2345
2346
GLES3::Texture *t = texture_storage->get_texture(p_texture);
2347
2348
if (t) {
2349
//regular texture
2350
if (!t->canvas_texture) {
2351
t->canvas_texture = memnew(GLES3::CanvasTexture);
2352
t->canvas_texture->diffuse = p_texture;
2353
}
2354
2355
ct = t->canvas_texture;
2356
} else {
2357
ct = texture_storage->get_canvas_texture(p_texture);
2358
}
2359
2360
if (!ct) {
2361
// Invalid Texture RID.
2362
_prepare_canvas_texture(default_canvas_texture, p_base_filter, p_base_repeat, r_index, r_texpixel_size);
2363
return;
2364
}
2365
2366
GLES3::Texture *texture = texture_storage->get_texture(ct->diffuse);
2367
Size2i size_cache;
2368
2369
// Cache default white resource ID.
2370
const RID default_texture_id = texture_storage->texture_gl_get_default(GLES3::DEFAULT_GL_TEXTURE_WHITE);
2371
2372
// If no texture is assigned, assign default white.
2373
if (!texture) {
2374
ct->diffuse = default_texture_id;
2375
}
2376
2377
// Enforce a 1x1 size if default white texture.
2378
size_cache = ct->diffuse == default_texture_id ? Size2i(1, 1) : Size2i(texture->width, texture->height);
2379
2380
GLES3::Texture *normal_map = texture_storage->get_texture(ct->normal_map);
2381
2382
if (ct->specular_color.a < 0.999) {
2383
state.canvas_instance_batches[state.current_batch_index].flags |= BATCH_FLAGS_DEFAULT_SPECULAR_MAP_USED;
2384
} else {
2385
state.canvas_instance_batches[state.current_batch_index].flags &= ~BATCH_FLAGS_DEFAULT_SPECULAR_MAP_USED;
2386
}
2387
2388
if (normal_map) {
2389
state.canvas_instance_batches[state.current_batch_index].flags |= BATCH_FLAGS_DEFAULT_NORMAL_MAP_USED;
2390
} else {
2391
state.canvas_instance_batches[state.current_batch_index].flags &= ~BATCH_FLAGS_DEFAULT_NORMAL_MAP_USED;
2392
}
2393
2394
state.canvas_instance_batches[state.current_batch_index].specular_shininess = uint32_t(CLAMP(ct->specular_color.a * 255.0, 0, 255)) << 24;
2395
state.canvas_instance_batches[state.current_batch_index].specular_shininess |= uint32_t(CLAMP(ct->specular_color.b * 255.0, 0, 255)) << 16;
2396
state.canvas_instance_batches[state.current_batch_index].specular_shininess |= uint32_t(CLAMP(ct->specular_color.g * 255.0, 0, 255)) << 8;
2397
state.canvas_instance_batches[state.current_batch_index].specular_shininess |= uint32_t(CLAMP(ct->specular_color.r * 255.0, 0, 255));
2398
2399
r_texpixel_size.x = 1.0 / float(size_cache.x);
2400
r_texpixel_size.y = 1.0 / float(size_cache.y);
2401
2402
state.instance_data_array[r_index].color_texture_pixel_size[0] = r_texpixel_size.x;
2403
state.instance_data_array[r_index].color_texture_pixel_size[1] = r_texpixel_size.y;
2404
}
2405
2406
void RasterizerCanvasGLES3::reset_canvas() {
2407
glDisable(GL_CULL_FACE);
2408
glDisable(GL_DEPTH_TEST);
2409
glDisable(GL_SCISSOR_TEST);
2410
glEnable(GL_BLEND);
2411
glBlendEquation(GL_FUNC_ADD);
2412
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
2413
2414
glActiveTexture(GL_TEXTURE0 + GLES3::Config::get_singleton()->max_texture_image_units - 2);
2415
glBindTexture(GL_TEXTURE_2D, 0);
2416
glActiveTexture(GL_TEXTURE0 + GLES3::Config::get_singleton()->max_texture_image_units - 3);
2417
glBindTexture(GL_TEXTURE_2D, 0);
2418
glActiveTexture(GL_TEXTURE0);
2419
2420
glBindBuffer(GL_ARRAY_BUFFER, 0);
2421
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2422
}
2423
2424
void RasterizerCanvasGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
2425
}
2426
2427
RendererCanvasRender::PolygonID RasterizerCanvasGLES3::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, int p_count) {
2428
// We interleave the vertex data into one big VBO to improve cache coherence
2429
uint32_t vertex_count = p_points.size();
2430
uint32_t stride = 2;
2431
if ((uint32_t)p_colors.size() == vertex_count) {
2432
stride += 4;
2433
}
2434
if ((uint32_t)p_uvs.size() == vertex_count) {
2435
stride += 2;
2436
}
2437
if ((uint32_t)p_bones.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
2438
stride += 4;
2439
}
2440
2441
PolygonBuffers pb;
2442
glGenBuffers(1, &pb.vertex_buffer);
2443
glGenVertexArrays(1, &pb.vertex_array);
2444
glBindVertexArray(pb.vertex_array);
2445
pb.count = vertex_count;
2446
pb.index_buffer = 0;
2447
2448
uint32_t buffer_size = stride * p_points.size();
2449
2450
Vector<uint8_t> polygon_buffer;
2451
polygon_buffer.resize(buffer_size * sizeof(float));
2452
{
2453
glBindBuffer(GL_ARRAY_BUFFER, pb.vertex_buffer);
2454
uint8_t *r = polygon_buffer.ptrw();
2455
float *fptr = reinterpret_cast<float *>(r);
2456
uint32_t *uptr = (uint32_t *)r;
2457
uint32_t base_offset = 0;
2458
{
2459
// Always uses vertex positions
2460
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
2461
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), nullptr);
2462
const Vector2 *points_ptr = p_points.ptr();
2463
2464
for (uint32_t i = 0; i < vertex_count; i++) {
2465
fptr[base_offset + i * stride + 0] = points_ptr[i].x;
2466
fptr[base_offset + i * stride + 1] = points_ptr[i].y;
2467
}
2468
2469
base_offset += 2;
2470
}
2471
2472
// Next add colors
2473
if ((uint32_t)p_colors.size() == vertex_count) {
2474
glEnableVertexAttribArray(RS::ARRAY_COLOR);
2475
glVertexAttribPointer(RS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float)));
2476
2477
const Color *color_ptr = p_colors.ptr();
2478
2479
for (uint32_t i = 0; i < vertex_count; i++) {
2480
fptr[base_offset + i * stride + 0] = color_ptr[i].r;
2481
fptr[base_offset + i * stride + 1] = color_ptr[i].g;
2482
fptr[base_offset + i * stride + 2] = color_ptr[i].b;
2483
fptr[base_offset + i * stride + 3] = color_ptr[i].a;
2484
}
2485
base_offset += 4;
2486
} else {
2487
glDisableVertexAttribArray(RS::ARRAY_COLOR);
2488
pb.color_disabled = true;
2489
pb.color = p_colors.size() == 1 ? p_colors[0] : Color(1.0, 1.0, 1.0, 1.0);
2490
}
2491
2492
if ((uint32_t)p_uvs.size() == vertex_count) {
2493
glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
2494
glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float)));
2495
2496
const Vector2 *uv_ptr = p_uvs.ptr();
2497
2498
for (uint32_t i = 0; i < vertex_count; i++) {
2499
fptr[base_offset + i * stride + 0] = uv_ptr[i].x;
2500
fptr[base_offset + i * stride + 1] = uv_ptr[i].y;
2501
}
2502
2503
base_offset += 2;
2504
} else {
2505
glDisableVertexAttribArray(RS::ARRAY_TEX_UV);
2506
}
2507
2508
if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
2509
glEnableVertexAttribArray(RS::ARRAY_BONES);
2510
glVertexAttribPointer(RS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float)));
2511
2512
const int *bone_ptr = p_bones.ptr();
2513
2514
for (uint32_t i = 0; i < vertex_count; i++) {
2515
uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride];
2516
2517
bone16w[0] = bone_ptr[i * 4 + 0];
2518
bone16w[1] = bone_ptr[i * 4 + 1];
2519
bone16w[2] = bone_ptr[i * 4 + 2];
2520
bone16w[3] = bone_ptr[i * 4 + 3];
2521
}
2522
2523
base_offset += 2;
2524
} else {
2525
glDisableVertexAttribArray(RS::ARRAY_BONES);
2526
}
2527
2528
if ((uint32_t)p_weights.size() == vertex_count * 4) {
2529
glEnableVertexAttribArray(RS::ARRAY_WEIGHTS);
2530
glVertexAttribPointer(RS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(base_offset * sizeof(float)));
2531
2532
const float *weight_ptr = p_weights.ptr();
2533
2534
for (uint32_t i = 0; i < vertex_count; i++) {
2535
uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride];
2536
2537
weight16w[0] = CLAMP(weight_ptr[i * 4 + 0] * 65535, 0, 65535);
2538
weight16w[1] = CLAMP(weight_ptr[i * 4 + 1] * 65535, 0, 65535);
2539
weight16w[2] = CLAMP(weight_ptr[i * 4 + 2] * 65535, 0, 65535);
2540
weight16w[3] = CLAMP(weight_ptr[i * 4 + 3] * 65535, 0, 65535);
2541
}
2542
2543
base_offset += 2;
2544
} else {
2545
glDisableVertexAttribArray(RS::ARRAY_WEIGHTS);
2546
}
2547
2548
ERR_FAIL_COND_V(base_offset != stride, 0);
2549
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, pb.vertex_buffer, vertex_count * stride * sizeof(float), polygon_buffer.ptr(), GL_STATIC_DRAW, "Polygon 2D vertex buffer");
2550
}
2551
2552
if (p_indices.size()) {
2553
//create indices, as indices were requested
2554
Vector<uint8_t> index_buffer;
2555
index_buffer.resize(p_count * sizeof(int32_t));
2556
{
2557
uint8_t *w = index_buffer.ptrw();
2558
memcpy(w, p_indices.ptr(), sizeof(int32_t) * p_count);
2559
}
2560
glGenBuffers(1, &pb.index_buffer);
2561
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer);
2562
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ELEMENT_ARRAY_BUFFER, pb.index_buffer, p_count * 4, index_buffer.ptr(), GL_STATIC_DRAW, "Polygon 2D index buffer");
2563
pb.count = p_count;
2564
}
2565
2566
glBindVertexArray(0);
2567
glBindBuffer(GL_ARRAY_BUFFER, 0);
2568
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2569
2570
PolygonID id = polygon_buffers.last_id++;
2571
2572
polygon_buffers.polygons[id] = pb;
2573
2574
return id;
2575
}
2576
2577
void RasterizerCanvasGLES3::free_polygon(PolygonID p_polygon) {
2578
PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon);
2579
ERR_FAIL_NULL(pb_ptr);
2580
2581
PolygonBuffers &pb = *pb_ptr;
2582
2583
if (pb.index_buffer != 0) {
2584
GLES3::Utilities::get_singleton()->buffer_free_data(pb.index_buffer);
2585
}
2586
2587
glDeleteVertexArrays(1, &pb.vertex_array);
2588
GLES3::Utilities::get_singleton()->buffer_free_data(pb.vertex_buffer);
2589
2590
polygon_buffers.polygons.erase(p_polygon);
2591
}
2592
2593
// Creates a new uniform buffer and uses it right away
2594
// This expands the instance buffer continually
2595
// In theory allocations can reach as high as number of windows * 3 frames
2596
// because OpenGL can start rendering subsequent frames before finishing the current one
2597
void RasterizerCanvasGLES3::_allocate_instance_data_buffer() {
2598
GLuint new_buffers[3];
2599
glGenBuffers(3, new_buffers);
2600
// Batch UBO.
2601
glBindBuffer(GL_ARRAY_BUFFER, new_buffers[0]);
2602
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffers[0], data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW, "2D Batch UBO[" + itos(state.current_data_buffer_index) + "][0]");
2603
// Light uniform buffer.
2604
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[1]);
2605
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[1], sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW, "2D Lights UBO[" + itos(state.current_data_buffer_index) + "]");
2606
// State buffer.
2607
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[2]);
2608
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[2], sizeof(StateBuffer), nullptr, GL_STREAM_DRAW, "2D State UBO[" + itos(state.current_data_buffer_index) + "]");
2609
2610
state.current_data_buffer_index = (state.current_data_buffer_index + 1);
2611
DataBuffer db;
2612
db.instance_buffers.push_back(new_buffers[0]);
2613
db.light_ubo = new_buffers[1];
2614
db.state_ubo = new_buffers[2];
2615
db.last_frame_used = RSG::rasterizer->get_frame_number();
2616
state.canvas_instance_data_buffers.insert(state.current_data_buffer_index, db);
2617
state.current_data_buffer_index = state.current_data_buffer_index % state.canvas_instance_data_buffers.size();
2618
glBindBuffer(GL_ARRAY_BUFFER, 0);
2619
glBindBuffer(GL_UNIFORM_BUFFER, 0);
2620
}
2621
void RasterizerCanvasGLES3::_allocate_instance_buffer() {
2622
state.current_instance_buffer_index++;
2623
2624
if (int(state.current_instance_buffer_index) < state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.size()) {
2625
// We already allocated another buffer in a previous frame, so we can just use it.
2626
return;
2627
}
2628
2629
GLuint new_buffer;
2630
glGenBuffers(1, &new_buffer);
2631
2632
glBindBuffer(GL_ARRAY_BUFFER, new_buffer);
2633
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffer, data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW, "Batch UBO[" + itos(state.current_data_buffer_index) + "][" + itos(state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.size()) + "]");
2634
2635
state.canvas_instance_data_buffers[state.current_data_buffer_index].instance_buffers.push_back(new_buffer);
2636
2637
glBindBuffer(GL_ARRAY_BUFFER, 0);
2638
}
2639
2640
void RasterizerCanvasGLES3::set_time(double p_time) {
2641
state.time = p_time;
2642
}
2643
2644
RasterizerCanvasGLES3 *RasterizerCanvasGLES3::singleton = nullptr;
2645
2646
RasterizerCanvasGLES3 *RasterizerCanvasGLES3::get_singleton() {
2647
return singleton;
2648
}
2649
2650
RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
2651
singleton = this;
2652
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
2653
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
2654
GLES3::Config *config = GLES3::Config::get_singleton();
2655
2656
glVertexAttrib4f(RS::ARRAY_COLOR, 1.0, 1.0, 1.0, 1.0);
2657
2658
polygon_buffers.last_id = 1;
2659
// quad buffer
2660
{
2661
glGenBuffers(1, &data.canvas_quad_vertices);
2662
glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices);
2663
2664
const float qv[8] = {
2665
0, 0,
2666
0, 1,
2667
1, 1,
2668
1, 0
2669
};
2670
2671
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, qv, GL_STATIC_DRAW);
2672
2673
glBindBuffer(GL_ARRAY_BUFFER, 0);
2674
2675
glGenVertexArrays(1, &data.canvas_quad_array);
2676
glBindVertexArray(data.canvas_quad_array);
2677
glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices);
2678
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, nullptr);
2679
glEnableVertexAttribArray(0);
2680
glBindVertexArray(0);
2681
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
2682
}
2683
2684
{
2685
//particle quad buffers
2686
2687
glGenBuffers(1, &data.particle_quad_vertices);
2688
glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices);
2689
{
2690
//quad of size 1, with pivot on the center for particles, then regular UVS. Color is general plus fetched from particle
2691
const float qv[16] = {
2692
-0.5, -0.5,
2693
0.0, 0.0,
2694
-0.5, 0.5,
2695
0.0, 1.0,
2696
0.5, 0.5,
2697
1.0, 1.0,
2698
0.5, -0.5,
2699
1.0, 0.0
2700
};
2701
2702
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 16, qv, GL_STATIC_DRAW);
2703
}
2704
2705
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
2706
2707
glGenVertexArrays(1, &data.particle_quad_array);
2708
glBindVertexArray(data.particle_quad_array);
2709
glBindBuffer(GL_ARRAY_BUFFER, data.particle_quad_vertices);
2710
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
2711
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, nullptr);
2712
glEnableVertexAttribArray(RS::ARRAY_TEX_UV);
2713
glVertexAttribPointer(RS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(8));
2714
glBindVertexArray(0);
2715
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
2716
}
2717
2718
// ninepatch buffers
2719
{
2720
// array buffer
2721
glGenBuffers(1, &data.ninepatch_vertices);
2722
glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices);
2723
2724
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, nullptr, GL_DYNAMIC_DRAW);
2725
2726
glBindBuffer(GL_ARRAY_BUFFER, 0);
2727
2728
// element buffer
2729
glGenBuffers(1, &data.ninepatch_elements);
2730
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements);
2731
2732
#define _EIDX(y, x) (y * 4 + x)
2733
uint8_t elems[3 * 2 * 9] = {
2734
// first row
2735
2736
_EIDX(0, 0), _EIDX(0, 1), _EIDX(1, 1),
2737
_EIDX(1, 1), _EIDX(1, 0), _EIDX(0, 0),
2738
2739
_EIDX(0, 1), _EIDX(0, 2), _EIDX(1, 2),
2740
_EIDX(1, 2), _EIDX(1, 1), _EIDX(0, 1),
2741
2742
_EIDX(0, 2), _EIDX(0, 3), _EIDX(1, 3),
2743
_EIDX(1, 3), _EIDX(1, 2), _EIDX(0, 2),
2744
2745
// second row
2746
2747
_EIDX(1, 0), _EIDX(1, 1), _EIDX(2, 1),
2748
_EIDX(2, 1), _EIDX(2, 0), _EIDX(1, 0),
2749
2750
// the center one would be here, but we'll put it at the end
2751
// so it's easier to disable the center and be able to use
2752
// one draw call for both
2753
2754
_EIDX(1, 2), _EIDX(1, 3), _EIDX(2, 3),
2755
_EIDX(2, 3), _EIDX(2, 2), _EIDX(1, 2),
2756
2757
// third row
2758
2759
_EIDX(2, 0), _EIDX(2, 1), _EIDX(3, 1),
2760
_EIDX(3, 1), _EIDX(3, 0), _EIDX(2, 0),
2761
2762
_EIDX(2, 1), _EIDX(2, 2), _EIDX(3, 2),
2763
_EIDX(3, 2), _EIDX(3, 1), _EIDX(2, 1),
2764
2765
_EIDX(2, 2), _EIDX(2, 3), _EIDX(3, 3),
2766
_EIDX(3, 3), _EIDX(3, 2), _EIDX(2, 2),
2767
2768
// center field
2769
2770
_EIDX(1, 1), _EIDX(1, 2), _EIDX(2, 2),
2771
_EIDX(2, 2), _EIDX(2, 1), _EIDX(1, 1)
2772
};
2773
#undef _EIDX
2774
2775
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elems), elems, GL_STATIC_DRAW);
2776
2777
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2778
}
2779
2780
if (config->max_uniform_buffer_size < 65536) {
2781
data.max_lights_per_render = 64;
2782
} else {
2783
data.max_lights_per_render = 256;
2784
}
2785
2786
// Reserve 3 Uniform Buffers for instance data Frame N, N+1 and N+2
2787
data.max_instances_per_buffer = uint32_t(GLOBAL_GET("rendering/gl_compatibility/item_buffer_size"));
2788
data.max_instance_buffer_size = data.max_instances_per_buffer * sizeof(InstanceData); // 16,384 instances * 128 bytes = 2,097,152 bytes = 2,048 kb
2789
state.canvas_instance_data_buffers.resize(3);
2790
state.canvas_instance_batches.reserve(200);
2791
2792
for (int i = 0; i < 3; i++) {
2793
GLuint new_buffers[3];
2794
glGenBuffers(3, new_buffers);
2795
// Batch UBO.
2796
glBindBuffer(GL_ARRAY_BUFFER, new_buffers[0]);
2797
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_ARRAY_BUFFER, new_buffers[0], data.max_instance_buffer_size, nullptr, GL_STREAM_DRAW, "Batch UBO[0][0]");
2798
// Light uniform buffer.
2799
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[1]);
2800
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[1], sizeof(LightUniform) * data.max_lights_per_render, nullptr, GL_STREAM_DRAW, "2D lights UBO[0]");
2801
// State buffer.
2802
glBindBuffer(GL_UNIFORM_BUFFER, new_buffers[2]);
2803
GLES3::Utilities::get_singleton()->buffer_allocate_data(GL_UNIFORM_BUFFER, new_buffers[2], sizeof(StateBuffer), nullptr, GL_STREAM_DRAW, "2D state UBO[0]");
2804
DataBuffer db;
2805
db.instance_buffers.push_back(new_buffers[0]);
2806
db.light_ubo = new_buffers[1];
2807
db.state_ubo = new_buffers[2];
2808
db.last_frame_used = 0;
2809
db.fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
2810
state.canvas_instance_data_buffers[i] = db;
2811
}
2812
glBindBuffer(GL_ARRAY_BUFFER, 0);
2813
glBindBuffer(GL_UNIFORM_BUFFER, 0);
2814
2815
state.instance_data_array = memnew_arr(InstanceData, data.max_instances_per_buffer);
2816
state.light_uniforms = memnew_arr(LightUniform, data.max_lights_per_render);
2817
2818
{
2819
const uint32_t indices[6] = { 0, 2, 1, 3, 2, 0 };
2820
glGenVertexArrays(1, &data.indexed_quad_array);
2821
glBindVertexArray(data.indexed_quad_array);
2822
glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices);
2823
glGenBuffers(1, &data.indexed_quad_buffer);
2824
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.indexed_quad_buffer);
2825
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint32_t) * 6, indices, GL_STATIC_DRAW);
2826
glBindVertexArray(0);
2827
}
2828
2829
String global_defines;
2830
global_defines += "#define MAX_GLOBAL_SHADER_UNIFORMS 256\n"; // TODO: this is arbitrary for now
2831
global_defines += "#define MAX_LIGHTS " + itos(data.max_lights_per_render) + "\n";
2832
2833
GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.initialize(global_defines, 1);
2834
data.canvas_shader_default_version = GLES3::MaterialStorage::get_singleton()->shaders.canvas_shader.version_create();
2835
2836
state.shadow_texture_size = GLOBAL_GET("rendering/2d/shadow_atlas/size");
2837
shadow_render.shader.initialize();
2838
shadow_render.shader_version = shadow_render.shader.version_create();
2839
2840
{
2841
default_canvas_group_shader = material_storage->shader_allocate();
2842
material_storage->shader_initialize(default_canvas_group_shader);
2843
2844
material_storage->shader_set_code(default_canvas_group_shader, R"(
2845
// Default CanvasGroup shader.
2846
2847
shader_type canvas_item;
2848
render_mode unshaded;
2849
2850
uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
2851
2852
void fragment() {
2853
vec4 c = textureLod(screen_texture, SCREEN_UV, 0.0);
2854
2855
if (c.a > 0.0001) {
2856
c.rgb /= c.a;
2857
}
2858
2859
COLOR *= c;
2860
}
2861
)");
2862
default_canvas_group_material = material_storage->material_allocate();
2863
material_storage->material_initialize(default_canvas_group_material);
2864
2865
material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader);
2866
}
2867
2868
{
2869
default_clip_children_shader = material_storage->shader_allocate();
2870
material_storage->shader_initialize(default_clip_children_shader);
2871
2872
material_storage->shader_set_code(default_clip_children_shader, R"(
2873
// Default clip children shader.
2874
2875
shader_type canvas_item;
2876
render_mode unshaded;
2877
2878
uniform sampler2D screen_texture : hint_screen_texture, repeat_disable, filter_nearest;
2879
2880
void fragment() {
2881
vec4 c = textureLod(screen_texture, SCREEN_UV, 0.0);
2882
COLOR.rgb = c.rgb;
2883
}
2884
)");
2885
default_clip_children_material = material_storage->material_allocate();
2886
material_storage->material_initialize(default_clip_children_material);
2887
2888
material_storage->material_set_shader(default_clip_children_material, default_clip_children_shader);
2889
}
2890
2891
default_canvas_texture = texture_storage->canvas_texture_allocate();
2892
texture_storage->canvas_texture_initialize(default_canvas_texture);
2893
2894
state.time = 0.0;
2895
}
2896
2897
RasterizerCanvasGLES3::~RasterizerCanvasGLES3() {
2898
singleton = nullptr;
2899
2900
GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
2901
material_storage->shaders.canvas_shader.version_free(data.canvas_shader_default_version);
2902
shadow_render.shader.version_free(shadow_render.shader_version);
2903
material_storage->material_free(default_canvas_group_material);
2904
material_storage->shader_free(default_canvas_group_shader);
2905
material_storage->material_free(default_clip_children_material);
2906
material_storage->shader_free(default_clip_children_shader);
2907
singleton = nullptr;
2908
2909
glDeleteBuffers(1, &data.canvas_quad_vertices);
2910
glDeleteVertexArrays(1, &data.canvas_quad_array);
2911
2912
glDeleteBuffers(1, &data.canvas_quad_vertices);
2913
glDeleteVertexArrays(1, &data.canvas_quad_array);
2914
2915
GLES3::TextureStorage::get_singleton()->canvas_texture_free(default_canvas_texture);
2916
memdelete_arr(state.instance_data_array);
2917
memdelete_arr(state.light_uniforms);
2918
2919
if (state.shadow_fb != 0) {
2920
glDeleteFramebuffers(1, &state.shadow_fb);
2921
GLES3::Utilities::get_singleton()->texture_free_data(state.shadow_texture);
2922
glDeleteRenderbuffers(1, &state.shadow_depth_buffer);
2923
state.shadow_fb = 0;
2924
state.shadow_texture = 0;
2925
state.shadow_depth_buffer = 0;
2926
}
2927
2928
for (uint32_t i = 0; i < state.canvas_instance_data_buffers.size(); i++) {
2929
for (int j = 0; j < state.canvas_instance_data_buffers[i].instance_buffers.size(); j++) {
2930
if (state.canvas_instance_data_buffers[i].instance_buffers[j]) {
2931
GLES3::Utilities::get_singleton()->buffer_free_data(state.canvas_instance_data_buffers[i].instance_buffers[j]);
2932
}
2933
}
2934
if (state.canvas_instance_data_buffers[i].light_ubo) {
2935
GLES3::Utilities::get_singleton()->buffer_free_data(state.canvas_instance_data_buffers[i].light_ubo);
2936
}
2937
if (state.canvas_instance_data_buffers[i].state_ubo) {
2938
GLES3::Utilities::get_singleton()->buffer_free_data(state.canvas_instance_data_buffers[i].state_ubo);
2939
}
2940
}
2941
}
2942
2943
#endif // GLES3_ENABLED
2944
2945