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