1 /*************************************************************************/
2 /* rasterizer_canvas_base_gles2.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
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_base_gles2.h"
32
33 #include "core/os/os.h"
34 #include "core/project_settings.h"
35 #include "rasterizer_scene_gles2.h"
36 #include "servers/visual/visual_server_raster.h"
37
38 #ifndef GLES_OVER_GL
39 #define glClearDepth glClearDepthf
40 #endif
41
light_internal_create()42 RID RasterizerCanvasBaseGLES2::light_internal_create() {
43
44 return RID();
45 }
46
light_internal_update(RID p_rid,Light * p_light)47 void RasterizerCanvasBaseGLES2::light_internal_update(RID p_rid, Light *p_light) {
48 }
49
light_internal_free(RID p_rid)50 void RasterizerCanvasBaseGLES2::light_internal_free(RID p_rid) {
51 }
52
canvas_begin()53 void RasterizerCanvasBaseGLES2::canvas_begin() {
54
55 state.canvas_shader.bind();
56 state.using_transparent_rt = false;
57 int viewport_x, viewport_y, viewport_width, viewport_height;
58
59 if (storage->frame.current_rt) {
60 glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
61 state.using_transparent_rt = storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT];
62
63 if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
64 // set Viewport and Scissor when rendering directly to screen
65 viewport_width = storage->frame.current_rt->width;
66 viewport_height = storage->frame.current_rt->height;
67 viewport_x = storage->frame.current_rt->x;
68 viewport_y = OS::get_singleton()->get_window_size().height - viewport_height - storage->frame.current_rt->y;
69 glScissor(viewport_x, viewport_y, viewport_width, viewport_height);
70 glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
71 glEnable(GL_SCISSOR_TEST);
72 }
73 }
74
75 if (storage->frame.clear_request) {
76 glClearColor(storage->frame.clear_request_color.r,
77 storage->frame.clear_request_color.g,
78 storage->frame.clear_request_color.b,
79 state.using_transparent_rt ? storage->frame.clear_request_color.a : 1.0);
80 glClear(GL_COLOR_BUFFER_BIT);
81 storage->frame.clear_request = false;
82 }
83
84 /*
85 if (storage->frame.current_rt) {
86 glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
87 glColorMask(1, 1, 1, 1);
88 }
89 */
90
91 reset_canvas();
92
93 glActiveTexture(GL_TEXTURE0);
94 glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
95
96 glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
97 glDisableVertexAttribArray(VS::ARRAY_COLOR);
98
99 // set up default uniforms
100
101 Transform canvas_transform;
102
103 if (storage->frame.current_rt) {
104
105 float csy = 1.0;
106 if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
107 csy = -1.0;
108 }
109 canvas_transform.translate(-(storage->frame.current_rt->width / 2.0f), -(storage->frame.current_rt->height / 2.0f), 0.0f);
110 canvas_transform.scale(Vector3(2.0f / storage->frame.current_rt->width, csy * -2.0f / storage->frame.current_rt->height, 1.0f));
111 } else {
112 Vector2 ssize = OS::get_singleton()->get_window_size();
113 canvas_transform.translate(-(ssize.width / 2.0f), -(ssize.height / 2.0f), 0.0f);
114 canvas_transform.scale(Vector3(2.0f / ssize.width, -2.0f / ssize.height, 1.0f));
115 }
116
117 state.uniforms.projection_matrix = canvas_transform;
118
119 state.uniforms.final_modulate = Color(1, 1, 1, 1);
120
121 state.uniforms.modelview_matrix = Transform2D();
122 state.uniforms.extra_matrix = Transform2D();
123
124 _set_uniforms();
125 _bind_quad_buffer();
126 }
127
canvas_end()128 void RasterizerCanvasBaseGLES2::canvas_end() {
129
130 glBindBuffer(GL_ARRAY_BUFFER, 0);
131
132 for (int i = 0; i < VS::ARRAY_MAX; i++) {
133 glDisableVertexAttribArray(i);
134 }
135
136 if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
137 //reset viewport to full window size
138 int viewport_width = OS::get_singleton()->get_window_size().width;
139 int viewport_height = OS::get_singleton()->get_window_size().height;
140 glViewport(0, 0, viewport_width, viewport_height);
141 glScissor(0, 0, viewport_width, viewport_height);
142 }
143
144 state.using_texture_rect = false;
145 state.using_skeleton = false;
146 state.using_ninepatch = false;
147 state.using_transparent_rt = false;
148 }
149
draw_generic_textured_rect(const Rect2 & p_rect,const Rect2 & p_src)150 void RasterizerCanvasBaseGLES2::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) {
151
152 state.canvas_shader.set_uniform(CanvasShaderGLES2::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y));
153 state.canvas_shader.set_uniform(CanvasShaderGLES2::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y));
154
155 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
156 }
157
_bind_canvas_texture(const RID & p_texture,const RID & p_normal_map)158 RasterizerStorageGLES2::Texture *RasterizerCanvasBaseGLES2::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) {
159
160 RasterizerStorageGLES2::Texture *tex_return = NULL;
161
162 if (p_texture.is_valid()) {
163
164 RasterizerStorageGLES2::Texture *texture = storage->texture_owner.getornull(p_texture);
165
166 if (!texture) {
167 state.current_tex = RID();
168 state.current_tex_ptr = NULL;
169
170 glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
171 glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
172
173 } else {
174
175 if (texture->redraw_if_visible) {
176 VisualServerRaster::redraw_request();
177 }
178
179 texture = texture->get_ptr();
180
181 if (texture->render_target) {
182 texture->render_target->used_in_frame = true;
183 }
184
185 glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
186 glBindTexture(GL_TEXTURE_2D, texture->tex_id);
187
188 state.current_tex = p_texture;
189 state.current_tex_ptr = texture;
190
191 tex_return = texture;
192 }
193 } else {
194 state.current_tex = RID();
195 state.current_tex_ptr = NULL;
196
197 glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
198 glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
199 }
200
201 if (p_normal_map == state.current_normal) {
202 //do none
203 state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, state.current_normal.is_valid());
204
205 } else if (p_normal_map.is_valid()) {
206
207 RasterizerStorageGLES2::Texture *normal_map = storage->texture_owner.getornull(p_normal_map);
208
209 if (!normal_map) {
210 state.current_normal = RID();
211 glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
212 glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
213 state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, false);
214
215 } else {
216
217 if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies
218 VisualServerRaster::redraw_request();
219 }
220
221 normal_map = normal_map->get_ptr();
222
223 glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
224 glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
225 state.current_normal = p_normal_map;
226 state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, true);
227 }
228
229 } else {
230
231 state.current_normal = RID();
232 glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
233 glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
234 state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, false);
235 }
236
237 return tex_return;
238 }
239
draw_window_margins(int * black_margin,RID * black_image)240 void RasterizerCanvasBaseGLES2::draw_window_margins(int *black_margin, RID *black_image) {
241
242 Vector2 window_size = OS::get_singleton()->get_window_size();
243 int window_h = window_size.height;
244 int window_w = window_size.width;
245
246 glBindFramebuffer(GL_FRAMEBUFFER, storage->system_fbo);
247 glViewport(0, 0, window_size.width, window_size.height);
248 canvas_begin();
249
250 if (black_image[MARGIN_LEFT].is_valid()) {
251 _bind_canvas_texture(black_image[MARGIN_LEFT], RID());
252 Size2 sz(storage->texture_get_width(black_image[MARGIN_LEFT]), storage->texture_get_height(black_image[MARGIN_LEFT]));
253 draw_generic_textured_rect(Rect2(0, 0, black_margin[MARGIN_LEFT], window_h),
254 Rect2(0, 0, (float)black_margin[MARGIN_LEFT] / sz.x, (float)(window_h) / sz.y));
255 } else if (black_margin[MARGIN_LEFT]) {
256 glActiveTexture(GL_TEXTURE0);
257 glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
258
259 draw_generic_textured_rect(Rect2(0, 0, black_margin[MARGIN_LEFT], window_h), Rect2(0, 0, 1, 1));
260 }
261
262 if (black_image[MARGIN_RIGHT].is_valid()) {
263 _bind_canvas_texture(black_image[MARGIN_RIGHT], RID());
264 Size2 sz(storage->texture_get_width(black_image[MARGIN_RIGHT]), storage->texture_get_height(black_image[MARGIN_RIGHT]));
265 draw_generic_textured_rect(Rect2(window_w - black_margin[MARGIN_RIGHT], 0, black_margin[MARGIN_RIGHT], window_h),
266 Rect2(0, 0, (float)black_margin[MARGIN_RIGHT] / sz.x, (float)window_h / sz.y));
267 } else if (black_margin[MARGIN_RIGHT]) {
268 glActiveTexture(GL_TEXTURE0);
269 glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
270
271 draw_generic_textured_rect(Rect2(window_w - black_margin[MARGIN_RIGHT], 0, black_margin[MARGIN_RIGHT], window_h), Rect2(0, 0, 1, 1));
272 }
273
274 if (black_image[MARGIN_TOP].is_valid()) {
275 _bind_canvas_texture(black_image[MARGIN_TOP], RID());
276
277 Size2 sz(storage->texture_get_width(black_image[MARGIN_TOP]), storage->texture_get_height(black_image[MARGIN_TOP]));
278 draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[MARGIN_TOP]),
279 Rect2(0, 0, (float)window_w / sz.x, (float)black_margin[MARGIN_TOP] / sz.y));
280
281 } else if (black_margin[MARGIN_TOP]) {
282 glActiveTexture(GL_TEXTURE0);
283 glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
284
285 draw_generic_textured_rect(Rect2(0, 0, window_w, black_margin[MARGIN_TOP]), Rect2(0, 0, 1, 1));
286 }
287
288 if (black_image[MARGIN_BOTTOM].is_valid()) {
289
290 _bind_canvas_texture(black_image[MARGIN_BOTTOM], RID());
291
292 Size2 sz(storage->texture_get_width(black_image[MARGIN_BOTTOM]), storage->texture_get_height(black_image[MARGIN_BOTTOM]));
293 draw_generic_textured_rect(Rect2(0, window_h - black_margin[MARGIN_BOTTOM], window_w, black_margin[MARGIN_BOTTOM]),
294 Rect2(0, 0, (float)window_w / sz.x, (float)black_margin[MARGIN_BOTTOM] / sz.y));
295
296 } else if (black_margin[MARGIN_BOTTOM]) {
297
298 glActiveTexture(GL_TEXTURE0);
299 glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
300
301 draw_generic_textured_rect(Rect2(0, window_h - black_margin[MARGIN_BOTTOM], window_w, black_margin[MARGIN_BOTTOM]), Rect2(0, 0, 1, 1));
302 }
303
304 canvas_end();
305 }
306
_bind_quad_buffer()307 void RasterizerCanvasBaseGLES2::_bind_quad_buffer() {
308 glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices);
309 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
310 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, NULL);
311 }
312
_set_uniforms()313 void RasterizerCanvasBaseGLES2::_set_uniforms() {
314
315 state.canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX, state.uniforms.projection_matrix);
316 state.canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
317 state.canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, state.uniforms.extra_matrix);
318
319 state.canvas_shader.set_uniform(CanvasShaderGLES2::FINAL_MODULATE, state.uniforms.final_modulate);
320
321 state.canvas_shader.set_uniform(CanvasShaderGLES2::TIME, storage->frame.time[0]);
322
323 if (storage->frame.current_rt) {
324 Vector2 screen_pixel_size;
325 screen_pixel_size.x = 1.0 / storage->frame.current_rt->width;
326 screen_pixel_size.y = 1.0 / storage->frame.current_rt->height;
327
328 state.canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_PIXEL_SIZE, screen_pixel_size);
329 }
330
331 if (state.using_skeleton) {
332 state.canvas_shader.set_uniform(CanvasShaderGLES2::SKELETON_TRANSFORM, state.skeleton_transform);
333 state.canvas_shader.set_uniform(CanvasShaderGLES2::SKELETON_TRANSFORM_INVERSE, state.skeleton_transform_inverse);
334 state.canvas_shader.set_uniform(CanvasShaderGLES2::SKELETON_TEXTURE_SIZE, state.skeleton_texture_size);
335 }
336
337 if (state.using_light) {
338
339 Light *light = state.using_light;
340 state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX, light->light_shader_xform);
341 Transform2D basis_inverse = light->light_shader_xform.affine_inverse().orthonormalized();
342 basis_inverse[2] = Vector2();
343 state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX_INVERSE, basis_inverse);
344 state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX, light->xform_cache.affine_inverse());
345 state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR, light->color * light->energy);
346 state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_POS, light->light_shader_pos);
347 state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT, light->height);
348 state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_OUTSIDE_ALPHA, light->mode == VS::CANVAS_LIGHT_MODE_MASK ? 1.0 : 0.0);
349
350 if (state.using_shadow) {
351 RasterizerStorageGLES2::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(light->shadow_buffer);
352 glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
353 glBindTexture(GL_TEXTURE_2D, cls->distance);
354 state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX, light->shadow_matrix_cache);
355 state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_SHADOW_COLOR, light->shadow_color);
356
357 state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOWPIXEL_SIZE, (1.0 / light->shadow_buffer_size) * (1.0 + light->shadow_smooth));
358 if (light->radius_cache == 0) {
359 state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_GRADIENT, 0.0);
360 } else {
361 state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_GRADIENT, light->shadow_gradient_length / (light->radius_cache * 1.1));
362 }
363 state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_DISTANCE_MULT, light->radius_cache * 1.1);
364
365 /*canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX,light->shadow_matrix_cache);
366 canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_ESM_MULTIPLIER,light->shadow_esm_mult);
367 canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_SHADOW_COLOR,light->shadow_color);*/
368 }
369 }
370 }
371
reset_canvas()372 void RasterizerCanvasBaseGLES2::reset_canvas() {
373
374 glDisable(GL_CULL_FACE);
375 glDisable(GL_DEPTH_TEST);
376 glDisable(GL_SCISSOR_TEST);
377 glDisable(GL_DITHER);
378 glEnable(GL_BLEND);
379
380 if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
381 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
382 } else {
383 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
384 }
385
386 // bind the back buffer to a texture so shaders can use it.
387 // It should probably use texture unit -3 (as GLES2 does as well) but currently that's buggy.
388 // keeping this for now as there's nothing else that uses texture unit 2
389 // TODO ^
390 if (storage->frame.current_rt) {
391 // glActiveTexture(GL_TEXTURE0 + 2);
392 // glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->copy_screen_effect.color);
393 }
394
395 glBindBuffer(GL_ARRAY_BUFFER, 0);
396 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
397 }
398
canvas_debug_viewport_shadows(Light * p_lights_with_shadow)399 void RasterizerCanvasBaseGLES2::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {
400 }
401
_copy_texscreen(const Rect2 & p_rect)402 void RasterizerCanvasBaseGLES2::_copy_texscreen(const Rect2 &p_rect) {
403
404 state.canvas_texscreen_used = true;
405
406 _copy_screen(p_rect);
407
408 // back to canvas, force rebind
409 state.using_texture_rect = false;
410 state.canvas_shader.bind();
411 _bind_canvas_texture(state.current_tex, state.current_normal);
412 _set_uniforms();
413 }
414
_draw_polygon(const int * p_indices,int p_index_count,int p_vertex_count,const Vector2 * p_vertices,const Vector2 * p_uvs,const Color * p_colors,bool p_singlecolor,const float * p_weights,const int * p_bones)415 void RasterizerCanvasBaseGLES2::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights, const int *p_bones) {
416
417 glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
418 #ifndef GLES_OVER_GL
419 // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
420 glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
421 #endif
422
423 uint32_t buffer_ofs = 0;
424
425 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * p_vertex_count, p_vertices);
426 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
427 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
428 buffer_ofs += sizeof(Vector2) * p_vertex_count;
429
430 if (p_singlecolor) {
431 glDisableVertexAttribArray(VS::ARRAY_COLOR);
432 Color m = *p_colors;
433 glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
434 } else if (!p_colors) {
435 glDisableVertexAttribArray(VS::ARRAY_COLOR);
436 glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
437 } else {
438 glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors);
439 glEnableVertexAttribArray(VS::ARRAY_COLOR);
440 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
441 buffer_ofs += sizeof(Color) * p_vertex_count;
442 }
443
444 if (p_uvs) {
445 glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
446 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
447 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
448 buffer_ofs += sizeof(Vector2) * p_vertex_count;
449 } else {
450 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
451 }
452
453 if (p_weights && p_bones) {
454 glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights);
455 glEnableVertexAttribArray(VS::ARRAY_WEIGHTS);
456 glVertexAttribPointer(VS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs));
457 buffer_ofs += sizeof(float) * 4 * p_vertex_count;
458
459 glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones);
460 glEnableVertexAttribArray(VS::ARRAY_BONES);
461 glVertexAttribPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, sizeof(int) * 4, CAST_INT_TO_UCHAR_PTR(buffer_ofs));
462 buffer_ofs += sizeof(int) * 4 * p_vertex_count;
463
464 } else {
465 glDisableVertexAttribArray(VS::ARRAY_WEIGHTS);
466 glDisableVertexAttribArray(VS::ARRAY_BONES);
467 }
468
469 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
470 #ifndef GLES_OVER_GL
471 // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
472 glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
473 #endif
474
475 if (storage->config.support_32_bits_indices) { //should check for
476 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices);
477 glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_INT, 0);
478 storage->info.render._2d_draw_call_count++;
479 } else {
480 uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count);
481 for (int i = 0; i < p_index_count; i++) {
482 index16[i] = uint16_t(p_indices[i]);
483 }
484 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(uint16_t) * p_index_count, index16);
485 glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_SHORT, 0);
486 storage->info.render._2d_draw_call_count++;
487 }
488
489 glBindBuffer(GL_ARRAY_BUFFER, 0);
490 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
491 }
492
_draw_generic(GLuint p_primitive,int p_vertex_count,const Vector2 * p_vertices,const Vector2 * p_uvs,const Color * p_colors,bool p_singlecolor)493 void RasterizerCanvasBaseGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
494
495 glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
496 #ifndef GLES_OVER_GL
497 // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
498 glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
499 #endif
500
501 uint32_t buffer_ofs = 0;
502
503 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * p_vertex_count, p_vertices);
504 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
505 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
506 buffer_ofs += sizeof(Vector2) * p_vertex_count;
507
508 if (p_singlecolor) {
509 glDisableVertexAttribArray(VS::ARRAY_COLOR);
510 Color m = *p_colors;
511 glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
512 } else if (!p_colors) {
513 glDisableVertexAttribArray(VS::ARRAY_COLOR);
514 glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
515 } else {
516 glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors);
517 glEnableVertexAttribArray(VS::ARRAY_COLOR);
518 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
519 buffer_ofs += sizeof(Color) * p_vertex_count;
520 }
521
522 if (p_uvs) {
523 glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
524 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
525 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
526 } else {
527 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
528 }
529
530 glDrawArrays(p_primitive, 0, p_vertex_count);
531 storage->info.render._2d_draw_call_count++;
532
533 glBindBuffer(GL_ARRAY_BUFFER, 0);
534 }
535
_draw_generic_indices(GLuint p_primitive,const int * p_indices,int p_index_count,int p_vertex_count,const Vector2 * p_vertices,const Vector2 * p_uvs,const Color * p_colors,bool p_singlecolor)536 void RasterizerCanvasBaseGLES2::_draw_generic_indices(GLuint p_primitive, const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
537
538 glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
539 #ifndef GLES_OVER_GL
540 // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
541 glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
542 #endif
543
544 uint32_t buffer_ofs = 0;
545
546 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector2) * p_vertex_count, p_vertices);
547 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
548 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), NULL);
549 buffer_ofs += sizeof(Vector2) * p_vertex_count;
550
551 if (p_singlecolor) {
552 glDisableVertexAttribArray(VS::ARRAY_COLOR);
553 Color m = *p_colors;
554 glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
555 } else if (!p_colors) {
556 glDisableVertexAttribArray(VS::ARRAY_COLOR);
557 glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
558 } else {
559 glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors);
560 glEnableVertexAttribArray(VS::ARRAY_COLOR);
561 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(Color), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
562 buffer_ofs += sizeof(Color) * p_vertex_count;
563 }
564
565 if (p_uvs) {
566 glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
567 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
568 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, sizeof(Vector2), CAST_INT_TO_UCHAR_PTR(buffer_ofs));
569 buffer_ofs += sizeof(Vector2) * p_vertex_count;
570 } else {
571 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
572 }
573
574 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
575 #ifndef GLES_OVER_GL
576 // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
577 glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
578 #endif
579
580 if (storage->config.support_32_bits_indices) { //should check for
581 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices);
582 glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_INT, 0);
583 storage->info.render._2d_draw_call_count++;
584 } else {
585 uint16_t *index16 = (uint16_t *)alloca(sizeof(uint16_t) * p_index_count);
586 for (int i = 0; i < p_index_count; i++) {
587 index16[i] = uint16_t(p_indices[i]);
588 }
589 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(uint16_t) * p_index_count, index16);
590 glDrawElements(p_primitive, p_index_count, GL_UNSIGNED_SHORT, 0);
591 storage->info.render._2d_draw_call_count++;
592 }
593
594 glBindBuffer(GL_ARRAY_BUFFER, 0);
595 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
596 }
597
_draw_gui_primitive(int p_points,const Vector2 * p_vertices,const Color * p_colors,const Vector2 * p_uvs)598 void RasterizerCanvasBaseGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) {
599
600 static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
601
602 int color_offset = 0;
603 int uv_offset = 0;
604 int stride = 2;
605
606 if (p_colors) {
607 color_offset = stride;
608 stride += 4;
609 }
610
611 if (p_uvs) {
612 uv_offset = stride;
613 stride += 2;
614 }
615
616 float buffer_data[(2 + 2 + 4) * 4];
617
618 for (int i = 0; i < p_points; i++) {
619 buffer_data[stride * i + 0] = p_vertices[i].x;
620 buffer_data[stride * i + 1] = p_vertices[i].y;
621 }
622
623 if (p_colors) {
624 for (int i = 0; i < p_points; i++) {
625 buffer_data[stride * i + color_offset + 0] = p_colors[i].r;
626 buffer_data[stride * i + color_offset + 1] = p_colors[i].g;
627 buffer_data[stride * i + color_offset + 2] = p_colors[i].b;
628 buffer_data[stride * i + color_offset + 3] = p_colors[i].a;
629 }
630 }
631
632 if (p_uvs) {
633 for (int i = 0; i < p_points; i++) {
634 buffer_data[stride * i + uv_offset + 0] = p_uvs[i].x;
635 buffer_data[stride * i + uv_offset + 1] = p_uvs[i].y;
636 }
637 }
638
639 glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
640 #ifndef GLES_OVER_GL
641 // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
642 glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
643 #endif
644 glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4 * sizeof(float), buffer_data);
645
646 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), NULL);
647
648 if (p_colors) {
649 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(color_offset * sizeof(float)));
650 glEnableVertexAttribArray(VS::ARRAY_COLOR);
651 }
652
653 if (p_uvs) {
654 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), CAST_INT_TO_UCHAR_PTR(uv_offset * sizeof(float)));
655 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
656 }
657
658 glDrawArrays(prim[p_points], 0, p_points);
659 storage->info.render._2d_draw_call_count++;
660
661 glBindBuffer(GL_ARRAY_BUFFER, 0);
662 }
663
_copy_screen(const Rect2 & p_rect)664 void RasterizerCanvasBaseGLES2::_copy_screen(const Rect2 &p_rect) {
665
666 if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
667 ERR_PRINT_ONCE("Cannot use screen texture copying in render target set to render direct to screen.");
668 return;
669 }
670
671 ERR_FAIL_COND_MSG(storage->frame.current_rt->copy_screen_effect.color == 0, "Can't use screen texture copying in a render target configured without copy buffers.");
672
673 glDisable(GL_BLEND);
674
675 Vector2 wh(storage->frame.current_rt->width, storage->frame.current_rt->height);
676
677 Color copy_section(p_rect.position.x / wh.x, p_rect.position.y / wh.y, p_rect.size.x / wh.x, p_rect.size.y / wh.y);
678
679 if (p_rect != Rect2()) {
680 storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, true);
681 }
682
683 storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_NO_ALPHA, !state.using_transparent_rt);
684
685 glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->copy_screen_effect.fbo);
686 glActiveTexture(GL_TEXTURE0);
687 glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
688
689 storage->shaders.copy.bind();
690 storage->shaders.copy.set_uniform(CopyShaderGLES2::COPY_SECTION, copy_section);
691
692 const Vector2 vertpos[4] = {
693 Vector2(-1, -1),
694 Vector2(-1, 1),
695 Vector2(1, 1),
696 Vector2(1, -1),
697 };
698
699 const Vector2 uvpos[4] = {
700 Vector2(0, 0),
701 Vector2(0, 1),
702 Vector2(1, 1),
703 Vector2(1, 0)
704 };
705
706 const int indexpos[6] = {
707 0, 1, 2,
708 2, 3, 0
709 };
710
711 _draw_polygon(indexpos, 6, 4, vertpos, uvpos, NULL, false);
712
713 storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_COPY_SECTION, false);
714 storage->shaders.copy.set_conditional(CopyShaderGLES2::USE_NO_ALPHA, false);
715
716 glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo); //back to front
717 glEnable(GL_BLEND);
718 }
719
canvas_light_shadow_buffer_update(RID p_buffer,const Transform2D & p_light_xform,int p_light_mask,float p_near,float p_far,LightOccluderInstance * p_occluders,CameraMatrix * p_xform_cache)720 void RasterizerCanvasBaseGLES2::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {
721
722 RasterizerStorageGLES2::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(p_buffer);
723 ERR_FAIL_COND(!cls);
724
725 glDisable(GL_BLEND);
726 glDisable(GL_SCISSOR_TEST);
727 glDisable(GL_DITHER);
728 glDisable(GL_CULL_FACE);
729 glDepthFunc(GL_LEQUAL);
730 glEnable(GL_DEPTH_TEST);
731 glDepthMask(true);
732
733 glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
734
735 state.canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES2::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
736 state.canvas_shadow_shader.bind();
737
738 glViewport(0, 0, cls->size, cls->height);
739 glClearDepth(1.0f);
740 glClearColor(1, 1, 1, 1);
741 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
742
743 VS::CanvasOccluderPolygonCullMode cull = VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
744
745 for (int i = 0; i < 4; i++) {
746
747 //make sure it remains orthogonal, makes easy to read angle later
748
749 Transform light;
750 light.origin[0] = p_light_xform[2][0];
751 light.origin[1] = p_light_xform[2][1];
752 light.basis[0][0] = p_light_xform[0][0];
753 light.basis[0][1] = p_light_xform[1][0];
754 light.basis[1][0] = p_light_xform[0][1];
755 light.basis[1][1] = p_light_xform[1][1];
756
757 //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1));
758
759 //p_near=1;
760 CameraMatrix projection;
761 {
762 real_t fov = 90;
763 real_t nearp = p_near;
764 real_t farp = p_far;
765 real_t aspect = 1.0;
766
767 real_t ymax = nearp * Math::tan(Math::deg2rad(fov * 0.5));
768 real_t ymin = -ymax;
769 real_t xmin = ymin * aspect;
770 real_t xmax = ymax * aspect;
771
772 projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp);
773 }
774
775 Vector3 cam_target = Basis(Vector3(0, 0, Math_PI * 2 * (i / 4.0))).xform(Vector3(0, 1, 0));
776 projection = projection * CameraMatrix(Transform().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse());
777
778 state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::PROJECTION_MATRIX, projection);
779 state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::LIGHT_MATRIX, light);
780 state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::DISTANCE_NORM, 1.0 / p_far);
781
782 if (i == 0)
783 *p_xform_cache = projection;
784
785 glViewport(0, (cls->height / 4) * i, cls->size, cls->height / 4);
786
787 LightOccluderInstance *instance = p_occluders;
788
789 while (instance) {
790
791 RasterizerStorageGLES2::CanvasOccluder *cc = storage->canvas_occluder_owner.getornull(instance->polygon_buffer);
792 if (!cc || cc->len == 0 || !(p_light_mask & instance->light_mask)) {
793
794 instance = instance->next;
795 continue;
796 }
797
798 state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::WORLD_MATRIX, instance->xform_cache);
799
800 VS::CanvasOccluderPolygonCullMode transformed_cull_cache = instance->cull_cache;
801
802 if (transformed_cull_cache != VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED &&
803 (p_light_xform.basis_determinant() * instance->xform_cache.basis_determinant()) < 0) {
804 transformed_cull_cache =
805 transformed_cull_cache == VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE ?
806 VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE :
807 VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE;
808 }
809
810 if (cull != transformed_cull_cache) {
811
812 cull = transformed_cull_cache;
813 switch (cull) {
814 case VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: {
815
816 glDisable(GL_CULL_FACE);
817
818 } break;
819 case VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE: {
820
821 glEnable(GL_CULL_FACE);
822 glCullFace(GL_FRONT);
823 } break;
824 case VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE: {
825
826 glEnable(GL_CULL_FACE);
827 glCullFace(GL_BACK);
828
829 } break;
830 }
831 }
832
833 glBindBuffer(GL_ARRAY_BUFFER, cc->vertex_id);
834 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
835 glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0);
836 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cc->index_id);
837
838 glDrawElements(GL_TRIANGLES, cc->len * 3, GL_UNSIGNED_SHORT, 0);
839
840 instance = instance->next;
841 }
842 }
843
844 glBindBuffer(GL_ARRAY_BUFFER, 0);
845 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
846 }
847
draw_lens_distortion_rect(const Rect2 & p_rect,float p_k1,float p_k2,const Vector2 & p_eye_center,float p_oversample)848 void RasterizerCanvasBaseGLES2::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) {
849 Vector2 half_size;
850 if (storage->frame.current_rt) {
851 half_size = Vector2(storage->frame.current_rt->width, storage->frame.current_rt->height);
852 } else {
853 half_size = OS::get_singleton()->get_window_size();
854 }
855 half_size *= 0.5;
856 Vector2 offset((p_rect.position.x - half_size.x) / half_size.x, (p_rect.position.y - half_size.y) / half_size.y);
857 Vector2 scale(p_rect.size.x / half_size.x, p_rect.size.y / half_size.y);
858
859 float aspect_ratio = p_rect.size.x / p_rect.size.y;
860
861 // setup our lens shader
862 state.lens_shader.bind();
863 state.lens_shader.set_uniform(LensDistortedShaderGLES2::OFFSET, offset);
864 state.lens_shader.set_uniform(LensDistortedShaderGLES2::SCALE, scale);
865 state.lens_shader.set_uniform(LensDistortedShaderGLES2::K1, p_k1);
866 state.lens_shader.set_uniform(LensDistortedShaderGLES2::K2, p_k2);
867 state.lens_shader.set_uniform(LensDistortedShaderGLES2::EYE_CENTER, p_eye_center);
868 state.lens_shader.set_uniform(LensDistortedShaderGLES2::UPSCALE, p_oversample);
869 state.lens_shader.set_uniform(LensDistortedShaderGLES2::ASPECT_RATIO, aspect_ratio);
870
871 // bind our quad buffer
872 _bind_quad_buffer();
873
874 // and draw
875 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
876
877 // and cleanup
878 glBindBuffer(GL_ARRAY_BUFFER, 0);
879
880 for (int i = 0; i < VS::ARRAY_MAX; i++) {
881 glDisableVertexAttribArray(i);
882 }
883 }
884
initialize()885 void RasterizerCanvasBaseGLES2::initialize() {
886
887 // quad buffer
888 {
889 glGenBuffers(1, &data.canvas_quad_vertices);
890 glBindBuffer(GL_ARRAY_BUFFER, data.canvas_quad_vertices);
891
892 const float qv[8] = {
893 0, 0,
894 0, 1,
895 1, 1,
896 1, 0
897 };
898
899 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, qv, GL_STATIC_DRAW);
900
901 glBindBuffer(GL_ARRAY_BUFFER, 0);
902 }
903
904 // polygon buffer
905 {
906 uint32_t poly_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128);
907 ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
908 poly_size *= 1024;
909 poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float));
910 glGenBuffers(1, &data.polygon_buffer);
911 glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
912 glBufferData(GL_ARRAY_BUFFER, poly_size, NULL, GL_DYNAMIC_DRAW);
913
914 data.polygon_buffer_size = poly_size;
915
916 glBindBuffer(GL_ARRAY_BUFFER, 0);
917
918 uint32_t index_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", 128);
919 ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PropertyInfo(Variant::INT, "rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", PROPERTY_HINT_RANGE, "0,256,1,or_greater"));
920 index_size *= 1024; // kb
921 glGenBuffers(1, &data.polygon_index_buffer);
922 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
923 glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, NULL, GL_DYNAMIC_DRAW);
924 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
925
926 data.polygon_index_buffer_size = index_size;
927 }
928
929 // ninepatch buffers
930 {
931 // array buffer
932 glGenBuffers(1, &data.ninepatch_vertices);
933 glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices);
934
935 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, NULL, GL_DYNAMIC_DRAW);
936
937 glBindBuffer(GL_ARRAY_BUFFER, 0);
938
939 // element buffer
940 glGenBuffers(1, &data.ninepatch_elements);
941 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements);
942
943 #define _EIDX(y, x) (y * 4 + x)
944 uint8_t elems[3 * 2 * 9] = {
945
946 // first row
947
948 _EIDX(0, 0), _EIDX(0, 1), _EIDX(1, 1),
949 _EIDX(1, 1), _EIDX(1, 0), _EIDX(0, 0),
950
951 _EIDX(0, 1), _EIDX(0, 2), _EIDX(1, 2),
952 _EIDX(1, 2), _EIDX(1, 1), _EIDX(0, 1),
953
954 _EIDX(0, 2), _EIDX(0, 3), _EIDX(1, 3),
955 _EIDX(1, 3), _EIDX(1, 2), _EIDX(0, 2),
956
957 // second row
958
959 _EIDX(1, 0), _EIDX(1, 1), _EIDX(2, 1),
960 _EIDX(2, 1), _EIDX(2, 0), _EIDX(1, 0),
961
962 // the center one would be here, but we'll put it at the end
963 // so it's easier to disable the center and be able to use
964 // one draw call for both
965
966 _EIDX(1, 2), _EIDX(1, 3), _EIDX(2, 3),
967 _EIDX(2, 3), _EIDX(2, 2), _EIDX(1, 2),
968
969 // third row
970
971 _EIDX(2, 0), _EIDX(2, 1), _EIDX(3, 1),
972 _EIDX(3, 1), _EIDX(3, 0), _EIDX(2, 0),
973
974 _EIDX(2, 1), _EIDX(2, 2), _EIDX(3, 2),
975 _EIDX(3, 2), _EIDX(3, 1), _EIDX(2, 1),
976
977 _EIDX(2, 2), _EIDX(2, 3), _EIDX(3, 3),
978 _EIDX(3, 3), _EIDX(3, 2), _EIDX(2, 2),
979
980 // center field
981
982 _EIDX(1, 1), _EIDX(1, 2), _EIDX(2, 2),
983 _EIDX(2, 2), _EIDX(2, 1), _EIDX(1, 1)
984 };
985 #undef _EIDX
986
987 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elems), elems, GL_STATIC_DRAW);
988
989 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
990 }
991
992 state.canvas_shadow_shader.init();
993
994 state.canvas_shader.init();
995
996 state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
997 state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
998
999 state.canvas_shader.bind();
1000
1001 state.lens_shader.init();
1002
1003 state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false));
1004
1005 state.using_light = NULL;
1006 state.using_transparent_rt = false;
1007 state.using_skeleton = false;
1008 }
1009
finalize()1010 void RasterizerCanvasBaseGLES2::finalize() {
1011 }
1012
RasterizerCanvasBaseGLES2()1013 RasterizerCanvasBaseGLES2::RasterizerCanvasBaseGLES2() {
1014 #ifdef GLES_OVER_GL
1015 use_nvidia_rect_workaround = GLOBAL_GET("rendering/quality/2d/use_nvidia_rect_flicker_workaround");
1016 #else
1017 // Not needed (a priori) on GLES devices
1018 use_nvidia_rect_workaround = false;
1019 #endif
1020 }
1021