1 /*************************************************************************/
2 /* rasterizer_gles2.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2019 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 #ifdef GLES2_ENABLED
31
32 #include "rasterizer_gles2.h"
33 #include "gl_context/context_gl.h"
34 #include "globals.h"
35 #include "os/os.h"
36 #include "servers/visual/particle_system_sw.h"
37 #include "servers/visual/shader_language.h"
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 #ifdef GLEW_ENABLED
43 #define _GL_HALF_FLOAT_OES 0x140B
44 #else
45 #define _GL_HALF_FLOAT_OES 0x8D61
46 #endif
47
48 #define _GL_RGBA16F_EXT 0x881A
49 #define _GL_RGB16F_EXT 0x881B
50 #define _GL_RG16F_EXT 0x822F
51 #define _GL_R16F_EXT 0x822D
52 #define _GL_R32F_EXT 0x822E
53
54 #define _GL_RED_EXT 0x1903
55 #define _GL_RG_EXT 0x8227
56 #define _GL_R8_EXT 0x8229
57 #define _GL_RG8_EXT 0x822B
58
59 #define _DEPTH_COMPONENT24_OES 0x81A6
60
61 #ifdef GLEW_ENABLED
62 #define _glClearDepth glClearDepth
63 #else
64 #define _glClearDepth glClearDepthf
65 #endif
66
67 #define _GL_SRGB_EXT 0x8C40
68 #define _GL_SRGB_ALPHA_EXT 0x8C42
69
70 #define _GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
71 #define _GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
72
73 //#define DEBUG_OPENGL
74
75 #ifdef DEBUG_OPENGL
76
77 #define DEBUG_TEST_ERROR(m_section) \
78 { \
79 print_line("AT: " + String(m_section)); \
80 glFlush(); \
81 uint32_t err = glGetError(); \
82 if (err) { \
83 print_line("OpenGL Error #" + itos(err) + " at: " + m_section); \
84 } \
85 }
86
87 #else
88
89 #define DEBUG_TEST_ERROR(m_section)
90
91 #endif
92
93 static RasterizerGLES2 *_singleton = NULL;
94
95 #ifdef GLES_NO_CLIENT_ARRAYS
96 static float GlobalVertexBuffer[MAX_POLYGON_VERTICES * 8] = { 0 };
97 #endif
98
99 static const GLenum prim_type[] = { GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
100
_set_color_attrib(const Color & p_color)101 _FORCE_INLINE_ static void _set_color_attrib(const Color &p_color) {
102
103 GLfloat c[4] = { p_color.r, p_color.g, p_color.b, p_color.a };
104 glVertexAttrib4fv(VS::ARRAY_COLOR, c);
105 }
106
make_half_float(float f)107 static _FORCE_INLINE_ uint16_t make_half_float(float f) {
108
109 union {
110 float fv;
111 uint32_t ui;
112 } ci;
113 ci.fv = f;
114
115 unsigned int x = ci.ui;
116 unsigned int sign = (unsigned short)(x >> 31);
117 unsigned int mantissa;
118 unsigned int exp;
119 uint16_t hf;
120
121 // get mantissa
122 mantissa = x & ((1 << 23) - 1);
123 // get exponent bits
124 exp = x & (0xFF << 23);
125 if (exp >= 0x47800000) {
126 // check if the original single precision float number is a NaN
127 if (mantissa && (exp == (0xFF << 23))) {
128 // we have a single precision NaN
129 mantissa = (1 << 23) - 1;
130 } else {
131 // 16-bit half-float representation stores number as Inf
132 mantissa = 0;
133 }
134 hf = (((uint16_t)sign) << 15) | (uint16_t)((0x1F << 10)) |
135 (uint16_t)(mantissa >> 13);
136 }
137 // check if exponent is <= -15
138 else if (exp <= 0x38000000) {
139
140 /*// store a denorm half-float value or zero
141 exp = (0x38000000 - exp) >> 23;
142 mantissa >>= (14 + exp);
143
144 hf = (((uint16_t)sign) << 15) | (uint16_t)(mantissa);
145 */
146 hf = 0; //denormals do not work for 3D, convert to zero
147 } else {
148 hf = (((uint16_t)sign) << 15) |
149 (uint16_t)((exp - 0x38000000) >> 13) |
150 (uint16_t)(mantissa >> 13);
151 }
152
153 return hf;
154 }
155
_draw_primitive(int p_points,const Vector3 * p_vertices,const Vector3 * p_normals,const Color * p_colors,const Vector3 * p_uvs,const Plane * p_tangents,int p_instanced)156 void RasterizerGLES2::_draw_primitive(int p_points, const Vector3 *p_vertices, const Vector3 *p_normals, const Color *p_colors, const Vector3 *p_uvs, const Plane *p_tangents, int p_instanced) {
157
158 ERR_FAIL_COND(!p_vertices);
159 ERR_FAIL_COND(p_points < 1 || p_points > 4);
160
161 bool quad = false;
162
163 GLenum type;
164 switch (p_points) {
165
166 case 1: type = GL_POINTS; break;
167 case 2: type = GL_LINES; break;
168 case 4: quad = true; p_points = 3;
169 case 3: type = GL_TRIANGLES; break;
170 };
171
172 glBindBuffer(GL_ARRAY_BUFFER, 0);
173 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
174
175 GLfloat vert_array[18];
176 GLfloat normal_array[18];
177 GLfloat color_array[24];
178 GLfloat tangent_array[24];
179 GLfloat uv_array[18];
180
181 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
182 glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, vert_array);
183
184 for (int i = 0; i < p_points; i++) {
185
186 vert_array[i * 3 + 0] = p_vertices[i].x;
187 vert_array[i * 3 + 1] = p_vertices[i].y;
188 vert_array[i * 3 + 2] = p_vertices[i].z;
189 if (quad) {
190 int idx = 2 + i;
191 if (idx == 4)
192 idx = 0;
193 vert_array[9 + i * 3 + 0] = p_vertices[idx].x;
194 vert_array[9 + i * 3 + 1] = p_vertices[idx].y;
195 vert_array[9 + i * 3 + 2] = p_vertices[idx].z;
196 }
197 }
198
199 if (p_normals) {
200 glEnableVertexAttribArray(VS::ARRAY_NORMAL);
201 glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, false, 0, normal_array);
202 for (int i = 0; i < p_points; i++) {
203
204 normal_array[i * 3 + 0] = p_normals[i].x;
205 normal_array[i * 3 + 1] = p_normals[i].y;
206 normal_array[i * 3 + 2] = p_normals[i].z;
207 if (quad) {
208 int idx = 2 + i;
209 if (idx == 4)
210 idx = 0;
211 normal_array[9 + i * 3 + 0] = p_normals[idx].x;
212 normal_array[9 + i * 3 + 1] = p_normals[idx].y;
213 normal_array[9 + i * 3 + 2] = p_normals[idx].z;
214 }
215 }
216 } else {
217 glDisableVertexAttribArray(VS::ARRAY_NORMAL);
218 }
219
220 if (p_colors) {
221 glEnableVertexAttribArray(VS::ARRAY_COLOR);
222 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, 0, color_array);
223 for (int i = 0; i < p_points; i++) {
224
225 color_array[i * 4 + 0] = p_colors[i].r;
226 color_array[i * 4 + 1] = p_colors[i].g;
227 color_array[i * 4 + 2] = p_colors[i].b;
228 color_array[i * 4 + 3] = p_colors[i].a;
229 if (quad) {
230 int idx = 2 + i;
231 if (idx == 4)
232 idx = 0;
233 color_array[12 + i * 4 + 0] = p_colors[idx].r;
234 color_array[12 + i * 4 + 1] = p_colors[idx].g;
235 color_array[12 + i * 4 + 2] = p_colors[idx].b;
236 color_array[12 + i * 4 + 3] = p_colors[idx].a;
237 }
238 }
239 } else {
240 glDisableVertexAttribArray(VS::ARRAY_COLOR);
241 }
242
243 if (p_tangents) {
244 glEnableVertexAttribArray(VS::ARRAY_TANGENT);
245 glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, false, 0, tangent_array);
246 for (int i = 0; i < p_points; i++) {
247
248 tangent_array[i * 4 + 0] = p_tangents[i].normal.x;
249 tangent_array[i * 4 + 1] = p_tangents[i].normal.y;
250 tangent_array[i * 4 + 2] = p_tangents[i].normal.z;
251 tangent_array[i * 4 + 3] = p_tangents[i].d;
252 if (quad) {
253 int idx = 2 + i;
254 if (idx == 4)
255 idx = 0;
256 tangent_array[12 + i * 4 + 0] = p_tangents[idx].normal.x;
257 tangent_array[12 + i * 4 + 1] = p_tangents[idx].normal.y;
258 tangent_array[12 + i * 4 + 2] = p_tangents[idx].normal.z;
259 tangent_array[12 + i * 4 + 3] = p_tangents[idx].d;
260 }
261 }
262 } else {
263 glDisableVertexAttribArray(VS::ARRAY_TANGENT);
264 }
265
266 if (p_uvs) {
267
268 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
269 glVertexAttribPointer(VS::ARRAY_TEX_UV, 3, GL_FLOAT, false, 0, uv_array);
270 for (int i = 0; i < p_points; i++) {
271
272 uv_array[i * 3 + 0] = p_uvs[i].x;
273 uv_array[i * 3 + 1] = p_uvs[i].y;
274 uv_array[i * 3 + 2] = p_uvs[i].z;
275 if (quad) {
276 int idx = 2 + i;
277 if (idx == 4)
278 idx = 0;
279 uv_array[9 + i * 3 + 0] = p_uvs[idx].x;
280 uv_array[9 + i * 3 + 1] = p_uvs[idx].y;
281 uv_array[9 + i * 3 + 2] = p_uvs[idx].z;
282 }
283 }
284
285 } else {
286 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
287 }
288
289 /*
290 if (p_instanced>1)
291 glDrawArraysInstanced(type,0,p_points,p_instanced);
292 else
293 */
294
295 glDrawArrays(type, 0, quad ? 6 : p_points);
296 };
297
298 /* TEXTURE API */
299 #define _EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
300 #define _EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG 0x8C01
301 #define _EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
302 #define _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03
303
304 #define _EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT 0x8A54
305 #define _EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT 0x8A55
306 #define _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT 0x8A56
307 #define _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT 0x8A57
308
309 #define _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
310 #define _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
311 #define _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
312
313 #define _EXT_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70
314 #define _EXT_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71
315 #define _EXT_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72
316 #define _EXT_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73
317
318 #define _EXT_COMPRESSED_RED_RGTC1_EXT 0x8DBB
319 #define _EXT_COMPRESSED_RED_RGTC1 0x8DBB
320 #define _EXT_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC
321 #define _EXT_COMPRESSED_RG_RGTC2 0x8DBD
322 #define _EXT_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
323 #define _EXT_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
324 #define _EXT_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
325 #define _EXT_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
326 #define _EXT_ETC1_RGB8_OES 0x8D64
327
328 #define _EXT_SLUMINANCE_NV 0x8C46
329 #define _EXT_SLUMINANCE_ALPHA_NV 0x8C44
330 #define _EXT_SRGB8_NV 0x8C41
331 #define _EXT_SLUMINANCE8_NV 0x8C47
332 #define _EXT_SLUMINANCE8_ALPHA8_NV 0x8C45
333
334 #define _EXT_COMPRESSED_SRGB_S3TC_DXT1_NV 0x8C4C
335 #define _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV 0x8C4D
336 #define _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV 0x8C4E
337 #define _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV 0x8C4F
338
339 #define _EXT_ATC_RGB_AMD 0x8C92
340 #define _EXT_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93
341 #define _EXT_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
342
343 /* TEXTURE API */
344
_get_gl_image_and_format(const Image & p_image,Image::Format p_format,uint32_t p_flags,GLenum & r_gl_format,GLenum & r_gl_internal_format,int & r_gl_components,bool & r_has_alpha_cache,bool & r_compressed)345 Image RasterizerGLES2::_get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, int &r_gl_components, bool &r_has_alpha_cache, bool &r_compressed) {
346
347 r_has_alpha_cache = false;
348 r_compressed = false;
349 r_gl_format = 0;
350 Image image = p_image;
351
352 switch (p_format) {
353
354 case Image::FORMAT_GRAYSCALE: {
355 r_gl_components = 1;
356 r_gl_format = GL_LUMINANCE;
357 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_SLUMINANCE_NV : GL_LUMINANCE;
358
359 } break;
360 case Image::FORMAT_INTENSITY: {
361
362 if (!image.empty())
363 image.convert(Image::FORMAT_RGBA);
364 r_gl_components = 4;
365 r_gl_format = GL_RGBA;
366 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _GL_SRGB_ALPHA_EXT : GL_RGBA;
367 r_has_alpha_cache = true;
368 } break;
369 case Image::FORMAT_GRAYSCALE_ALPHA: {
370
371 //image.convert(Image::FORMAT_RGBA);
372 r_gl_components = 2;
373 r_gl_format = GL_LUMINANCE_ALPHA;
374 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_SLUMINANCE_ALPHA_NV : GL_LUMINANCE_ALPHA;
375 r_has_alpha_cache = true;
376 } break;
377
378 case Image::FORMAT_INDEXED: {
379
380 if (!image.empty())
381 image.convert(Image::FORMAT_RGB);
382 r_gl_components = 3;
383 r_gl_format = GL_RGB;
384 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _GL_SRGB_EXT : GL_RGB;
385
386 } break;
387
388 case Image::FORMAT_INDEXED_ALPHA: {
389
390 if (!image.empty())
391 image.convert(Image::FORMAT_RGBA);
392 r_gl_components = 4;
393
394 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
395
396 if (srgb_supported) {
397 r_gl_format = GL_RGBA;
398 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
399 } else {
400 r_gl_internal_format = GL_RGBA;
401 if (!image.empty())
402 image.srgb_to_linear();
403 }
404 } else {
405 r_gl_internal_format = GL_RGBA;
406 }
407 r_has_alpha_cache = true;
408
409 } break;
410 case Image::FORMAT_RGB: {
411
412 r_gl_components = 3;
413
414 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
415
416 if (srgb_supported) {
417 r_gl_internal_format = _GL_SRGB_EXT;
418 r_gl_format = GL_RGB;
419 } else {
420 r_gl_internal_format = GL_RGB;
421 if (!image.empty())
422 image.srgb_to_linear();
423 }
424 } else {
425 r_gl_internal_format = GL_RGB;
426 }
427 } break;
428 case Image::FORMAT_RGBA: {
429
430 r_gl_components = 4;
431 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
432
433 if (srgb_supported) {
434 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
435 r_gl_format = GL_RGBA;
436 //r_gl_internal_format=GL_RGBA;
437 } else {
438 r_gl_internal_format = GL_RGBA;
439 if (!image.empty())
440 image.srgb_to_linear();
441 }
442 } else {
443 r_gl_internal_format = GL_RGBA;
444 }
445
446 r_has_alpha_cache = true;
447 } break;
448 case Image::FORMAT_BC1: {
449
450 if (!s3tc_supported || (!s3tc_srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
451
452 if (!image.empty()) {
453 image.decompress();
454 }
455 r_gl_components = 4;
456 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
457
458 if (srgb_supported) {
459 r_gl_format = GL_RGBA;
460 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
461 } else {
462 r_gl_internal_format = GL_RGBA;
463 if (!image.empty())
464 image.srgb_to_linear();
465 }
466 } else {
467 r_gl_internal_format = GL_RGBA;
468 }
469 r_has_alpha_cache = true;
470
471 } else {
472
473 r_gl_components = 1; //doesn't matter much
474 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
475 r_compressed = true;
476 };
477
478 } break;
479 case Image::FORMAT_BC2: {
480
481 if (!s3tc_supported || (!s3tc_srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
482
483 if (!image.empty()) {
484 image.decompress();
485 }
486 r_gl_components = 4;
487 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
488
489 if (srgb_supported) {
490 r_gl_format = GL_RGBA;
491 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
492 } else {
493 r_gl_internal_format = GL_RGBA;
494 if (!image.empty())
495 image.srgb_to_linear();
496 }
497 } else {
498 r_gl_internal_format = GL_RGBA;
499 }
500 r_has_alpha_cache = true;
501
502 } else {
503 r_gl_components = 1; //doesn't matter much
504 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
505
506 r_has_alpha_cache = true;
507 r_compressed = true;
508 };
509
510 } break;
511 case Image::FORMAT_BC3: {
512
513 if (!s3tc_supported || (!s3tc_srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
514
515 if (!image.empty()) {
516 image.decompress();
517 }
518 r_gl_components = 4;
519 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
520
521 if (srgb_supported) {
522 r_gl_format = GL_RGBA;
523 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
524 } else {
525 r_gl_internal_format = GL_RGBA;
526 if (!image.empty())
527 image.srgb_to_linear();
528 }
529 } else {
530 r_gl_internal_format = GL_RGBA;
531 }
532 r_has_alpha_cache = true;
533
534 } else {
535 r_gl_components = 1; //doesn't matter much
536 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV : _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
537 r_has_alpha_cache = true;
538 r_compressed = true;
539 };
540
541 } break;
542 case Image::FORMAT_BC4: {
543
544 if (!latc_supported) {
545
546 if (!image.empty()) {
547 image.decompress();
548 }
549 r_gl_components = 4;
550 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
551
552 if (srgb_supported) {
553 r_gl_format = GL_RGBA;
554 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
555 } else {
556 r_gl_internal_format = GL_RGBA;
557 if (!image.empty())
558 image.srgb_to_linear();
559 }
560 } else {
561 r_gl_internal_format = GL_RGBA;
562 }
563 r_has_alpha_cache = true;
564
565 } else {
566
567 r_gl_internal_format = _EXT_COMPRESSED_LUMINANCE_LATC1_EXT;
568 r_gl_components = 1; //doesn't matter much
569 r_compressed = true;
570 };
571
572 } break;
573 case Image::FORMAT_BC5: {
574
575 if (!latc_supported) {
576
577 if (!image.empty()) {
578 image.decompress();
579 }
580 r_gl_components = 4;
581 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
582
583 if (srgb_supported) {
584 r_gl_format = GL_RGBA;
585 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
586 } else {
587 r_gl_internal_format = GL_RGBA;
588 if (!image.empty())
589 image.srgb_to_linear();
590 }
591 } else {
592 r_gl_internal_format = GL_RGBA;
593 }
594 r_has_alpha_cache = true;
595
596 } else {
597 r_gl_internal_format = _EXT_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
598 r_gl_components = 1; //doesn't matter much
599 r_compressed = true;
600 };
601 } break;
602 case Image::FORMAT_PVRTC2: {
603
604 if (!pvr_supported || (!pvr_srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
605
606 if (!image.empty()) {
607 image.decompress();
608 }
609 r_gl_components = 4;
610 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
611
612 if (srgb_supported) {
613 r_gl_format = GL_RGBA;
614 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
615 } else {
616 r_gl_internal_format = GL_RGBA;
617 if (!image.empty())
618 image.srgb_to_linear();
619 }
620 } else {
621 r_gl_internal_format = GL_RGBA;
622 }
623 r_has_alpha_cache = true;
624
625 } else {
626
627 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
628 r_gl_components = 1; //doesn't matter much
629 r_compressed = true;
630 }
631
632 } break;
633 case Image::FORMAT_PVRTC2_ALPHA: {
634
635 if (!pvr_supported || (!pvr_srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
636
637 if (!image.empty())
638 image.decompress();
639 r_gl_components = 4;
640 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
641
642 if (srgb_supported) {
643 r_gl_format = GL_RGBA;
644 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
645 } else {
646 r_gl_internal_format = GL_RGBA;
647 if (!image.empty())
648 image.srgb_to_linear();
649 }
650 } else {
651 r_gl_internal_format = GL_RGBA;
652 }
653 r_has_alpha_cache = true;
654
655 } else {
656
657 r_gl_internal_format = _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
658 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
659 r_gl_components = 1; //doesn't matter much
660 r_compressed = true;
661 }
662
663 } break;
664 case Image::FORMAT_PVRTC4: {
665
666 if (!pvr_supported || (!pvr_srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
667
668 if (!image.empty())
669 image.decompress();
670 r_gl_components = 4;
671 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
672
673 if (srgb_supported) {
674 r_gl_format = GL_RGBA;
675 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
676 } else {
677 r_gl_internal_format = GL_RGBA;
678 if (!image.empty())
679 image.srgb_to_linear();
680 }
681 } else {
682 r_gl_internal_format = GL_RGBA;
683 }
684 r_has_alpha_cache = true;
685 } else {
686
687 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
688 r_gl_components = 1; //doesn't matter much
689 r_compressed = true;
690 }
691
692 } break;
693 case Image::FORMAT_PVRTC4_ALPHA: {
694
695 if (!pvr_supported || (!pvr_srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)) {
696
697 if (!image.empty())
698 image.decompress();
699 r_gl_components = 4;
700 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
701
702 if (srgb_supported) {
703 r_gl_format = GL_RGBA;
704 r_gl_internal_format = _GL_SRGB_ALPHA_EXT;
705 } else {
706 r_gl_internal_format = GL_RGBA;
707 if (!image.empty())
708 image.srgb_to_linear();
709 }
710 } else {
711 r_gl_internal_format = GL_RGBA;
712 }
713 r_has_alpha_cache = true;
714
715 } else {
716 r_gl_internal_format = (srgb_supported && p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT : _EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
717 r_gl_components = 1; //doesn't matter much
718 r_compressed = true;
719 }
720
721 } break;
722 case Image::FORMAT_ETC: {
723
724 if (!etc_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
725
726 if (!image.empty()) {
727 image.decompress();
728 }
729 r_gl_components = 3;
730 if (p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
731
732 if (srgb_supported) {
733 r_gl_format = GL_RGB;
734 r_gl_internal_format = _GL_SRGB_EXT;
735 } else {
736 r_gl_internal_format = GL_RGB;
737 if (!image.empty())
738 image.srgb_to_linear();
739 }
740 } else {
741 r_gl_internal_format = GL_RGB;
742 }
743 r_gl_internal_format = GL_RGB;
744
745 } else {
746
747 r_gl_internal_format = _EXT_ETC1_RGB8_OES;
748 r_gl_components = 1; //doesn't matter much
749 r_compressed = true;
750 }
751
752 } break;
753 case Image::FORMAT_ATC: {
754
755 if (!atitc_supported) {
756
757 if (!image.empty()) {
758 image.decompress();
759 }
760 r_gl_components = 3;
761 r_gl_internal_format = GL_RGB;
762
763 } else {
764
765 r_gl_internal_format = _EXT_ATC_RGB_AMD;
766 r_gl_components = 1; //doesn't matter much
767 r_compressed = true;
768 }
769
770 } break;
771 case Image::FORMAT_ATC_ALPHA_EXPLICIT: {
772
773 if (!atitc_supported) {
774
775 if (!image.empty()) {
776 image.decompress();
777 }
778 r_gl_components = 4;
779 r_gl_internal_format = GL_RGBA;
780
781 } else {
782
783 r_gl_internal_format = _EXT_ATC_RGBA_EXPLICIT_ALPHA_AMD;
784 r_gl_components = 1; //doesn't matter much
785 r_compressed = true;
786 }
787
788 } break;
789 case Image::FORMAT_ATC_ALPHA_INTERPOLATED: {
790
791 if (!atitc_supported) {
792
793 if (!image.empty()) {
794 image.decompress();
795 }
796 r_gl_components = 4;
797 r_gl_internal_format = GL_RGBA;
798
799 } else {
800
801 r_gl_internal_format = _EXT_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
802 r_gl_components = 1; //doesn't matter much
803 r_compressed = true;
804 }
805
806 } break;
807 case Image::FORMAT_YUV_422:
808 case Image::FORMAT_YUV_444: {
809
810 if (!image.empty())
811 image.convert(Image::FORMAT_RGB);
812 r_gl_internal_format = GL_RGB;
813 r_gl_components = 3;
814
815 } break;
816
817 default: {
818
819 ERR_FAIL_V(Image());
820 }
821 }
822
823 if (r_gl_format == 0) {
824 r_gl_format = r_gl_internal_format;
825 }
826
827 return image;
828 }
829
830 static const GLenum _cube_side_enum[6] = {
831
832 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
833 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
834 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
835 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
836 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
837 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
838
839 };
840
texture_create()841 RID RasterizerGLES2::texture_create() {
842
843 Texture *texture = memnew(Texture);
844 ERR_FAIL_COND_V(!texture, RID());
845 glGenTextures(1, &texture->tex_id);
846 texture->active = false;
847 texture->total_data_size = 0;
848
849 return texture_owner.make_rid(texture);
850 }
851
texture_allocate(RID p_texture,int p_width,int p_height,Image::Format p_format,uint32_t p_flags)852 void RasterizerGLES2::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
853
854 bool has_alpha_cache;
855 int components;
856 GLenum format;
857 GLenum internal_format;
858 bool compressed;
859
860 int po2_width = next_power_of_2(p_width);
861 int po2_height = next_power_of_2(p_height);
862
863 if (p_flags & VS::TEXTURE_FLAG_VIDEO_SURFACE) {
864 p_flags &= ~VS::TEXTURE_FLAG_MIPMAPS; // no mipies for video
865 }
866
867 Texture *texture = texture_owner.get(p_texture);
868 ERR_FAIL_COND(!texture);
869 texture->width = p_width;
870 texture->height = p_height;
871 texture->format = p_format;
872 texture->flags = p_flags;
873 texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
874
875 _get_gl_image_and_format(Image(), texture->format, texture->flags, format, internal_format, components, has_alpha_cache, compressed);
876
877 bool scale_textures = !compressed && !(p_flags & VS::TEXTURE_FLAG_VIDEO_SURFACE) && (!npo2_textures_available || p_flags & VS::TEXTURE_FLAG_MIPMAPS);
878
879 if (scale_textures) {
880 texture->alloc_width = po2_width;
881 texture->alloc_height = po2_height;
882 // print_line("scale because npo2: "+itos(npo2_textures_available)+" mm: "+itos(p_format&VS::TEXTURE_FLAG_MIPMAPS)+" "+itos(p_mipmap_count) );
883 } else {
884
885 texture->alloc_width = texture->width;
886 texture->alloc_height = texture->height;
887 };
888
889 if (!(p_flags & VS::TEXTURE_FLAG_VIDEO_SURFACE) && shrink_textures_x2) {
890 texture->alloc_height = MAX(1, texture->alloc_height / 2);
891 texture->alloc_width = MAX(1, texture->alloc_width / 2);
892 }
893
894 texture->gl_components_cache = components;
895 texture->gl_format_cache = format;
896 texture->gl_internal_format_cache = internal_format;
897 texture->format_has_alpha = has_alpha_cache;
898 texture->compressed = compressed;
899 texture->has_alpha = false; //by default it doesn't have alpha unless something with alpha is blitteds
900 texture->data_size = 0;
901 texture->mipmaps = 0;
902
903 glActiveTexture(GL_TEXTURE0);
904 glBindTexture(texture->target, texture->tex_id);
905
906 if (p_flags & VS::TEXTURE_FLAG_VIDEO_SURFACE) {
907 //prealloc if video
908 glTexImage2D(texture->target, 0, internal_format, p_width, p_height, 0, format, GL_UNSIGNED_BYTE, NULL);
909 }
910
911 texture->active = true;
912 }
913
texture_set_data(RID p_texture,const Image & p_image,VS::CubeMapSide p_cube_side)914 void RasterizerGLES2::texture_set_data(RID p_texture, const Image &p_image, VS::CubeMapSide p_cube_side) {
915
916 Texture *texture = texture_owner.get(p_texture);
917
918 ERR_FAIL_COND(!texture);
919 ERR_FAIL_COND(!texture->active);
920 ERR_FAIL_COND(texture->render_target);
921 ERR_FAIL_COND(texture->format != p_image.get_format());
922 ERR_FAIL_COND(p_image.empty());
923
924 int components;
925 GLenum format;
926 GLenum internal_format;
927 bool alpha;
928 bool compressed;
929
930 if (keep_copies && !(texture->flags & VS::TEXTURE_FLAG_VIDEO_SURFACE) && !(use_reload_hooks && texture->reloader)) {
931 texture->image[p_cube_side] = p_image;
932 }
933
934 Image img = _get_gl_image_and_format(p_image, p_image.get_format(), texture->flags, format, internal_format, components, alpha, compressed);
935
936 if (texture->alloc_width != img.get_width() || texture->alloc_height != img.get_height()) {
937
938 if (texture->alloc_width == img.get_width() / 2 && texture->alloc_height == img.get_height() / 2) {
939
940 img.shrink_x2();
941 } else if (img.get_format() <= Image::FORMAT_INDEXED_ALPHA) {
942
943 img.resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
944 }
945 };
946
947 if (!(texture->flags & VS::TEXTURE_FLAG_VIDEO_SURFACE) && img.detect_alpha() == Image::ALPHA_BLEND) {
948 texture->has_alpha = true;
949 }
950
951 GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_cube_side] : GL_TEXTURE_2D;
952
953 texture->data_size = img.get_data().size();
954 DVector<uint8_t>::Read read = img.get_data().read();
955
956 glActiveTexture(GL_TEXTURE0);
957 glBindTexture(texture->target, texture->tex_id);
958
959 texture->ignore_mipmaps = compressed && img.get_mipmaps() == 0;
960
961 if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps)
962 glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, use_fast_texture_filter ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR);
963 else {
964 if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
965 glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
966 } else {
967 glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
968 }
969 }
970
971 if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
972
973 glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
974
975 } else {
976
977 glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
978 }
979
980 bool force_clamp_to_edge = !(texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (next_power_of_2(texture->alloc_height) != texture->alloc_height || next_power_of_2(texture->alloc_width) != texture->alloc_width);
981
982 if (!force_clamp_to_edge && (texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
983
984 if (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) {
985 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
986 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
987 } else {
988 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
989 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
990 }
991 } else {
992
993 //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
994 glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
995 glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
996 }
997
998 if (use_anisotropic_filter) {
999
1000 if (texture->flags & VS::TEXTURE_FLAG_ANISOTROPIC_FILTER) {
1001
1002 glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_level);
1003 } else {
1004 glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
1005 }
1006 }
1007
1008 int mipmaps = (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && img.get_mipmaps() > 0) ? img.get_mipmaps() + 1 : 1;
1009
1010 int w = img.get_width();
1011 int h = img.get_height();
1012
1013 int tsize = 0;
1014 for (int i = 0; i < mipmaps; i++) {
1015
1016 int size, ofs;
1017 img.get_mipmap_offset_and_size(i, ofs, size);
1018
1019 //print_line("mipmap: "+itos(i)+" size: "+itos(size)+" w: "+itos(mm_w)+", h: "+itos(mm_h));
1020
1021 if (texture->compressed) {
1022 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1023 glCompressedTexImage2D(blit_target, i, format, w, h, 0, size, &read[ofs]);
1024
1025 } else {
1026 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1027 if (texture->flags & VS::TEXTURE_FLAG_VIDEO_SURFACE) {
1028 glTexSubImage2D(blit_target, i, 0, 0, w, h, format, GL_UNSIGNED_BYTE, &read[ofs]);
1029 } else {
1030 glTexImage2D(blit_target, i, internal_format, w, h, 0, format, GL_UNSIGNED_BYTE, &read[ofs]);
1031 }
1032 }
1033 tsize += size;
1034
1035 w = MAX(1, w >> 1);
1036 h = MAX(1, h >> 1);
1037 }
1038
1039 _rinfo.texture_mem -= texture->total_data_size;
1040 texture->total_data_size = tsize;
1041 _rinfo.texture_mem += texture->total_data_size;
1042
1043 //printf("texture: %i x %i - size: %i - total: %i\n",texture->width,texture->height,tsize,_rinfo.texture_mem);
1044
1045 if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && mipmaps == 1 && !texture->ignore_mipmaps) {
1046 //generate mipmaps if they were requested and the image does not contain them
1047 glGenerateMipmap(texture->target);
1048 }
1049
1050 texture->mipmaps = mipmaps;
1051
1052 if (mipmaps > 1) {
1053
1054 //glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmaps-1 ); - assumed to have all, always
1055 }
1056
1057 //texture_set_flags(p_texture,texture->flags);
1058 }
1059
texture_get_data(RID p_texture,VS::CubeMapSide p_cube_side) const1060 Image RasterizerGLES2::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const {
1061
1062 Texture *texture = texture_owner.get(p_texture);
1063
1064 ERR_FAIL_COND_V(!texture, Image());
1065 ERR_FAIL_COND_V(!texture->active, Image());
1066 ERR_FAIL_COND_V(texture->data_size == 0, Image());
1067 ERR_FAIL_COND_V(texture->render_target, Image());
1068
1069 return texture->image[p_cube_side];
1070
1071 #if 0
1072
1073 Texture * texture = texture_owner.get(p_texture);
1074
1075 ERR_FAIL_COND_V(!texture,Image());
1076 ERR_FAIL_COND_V(!texture->active,Image());
1077 ERR_FAIL_COND_V(texture->data_size==0,Image());
1078
1079 DVector<uint8_t> data;
1080 GLenum format,type=GL_UNSIGNED_BYTE;
1081 Image::Format fmt;
1082 int pixelsize=0;
1083 int pixelshift=0;
1084 int minw=1,minh=1;
1085 bool compressed=false;
1086
1087 fmt=texture->format;
1088
1089 switch(texture->format) {
1090
1091 case Image::FORMAT_GRAYSCALE: {
1092
1093 format=GL_LUMINANCE;
1094 type=GL_UNSIGNED_BYTE;
1095 data.resize(texture->alloc_width*texture->alloc_height);
1096 pixelsize=1;
1097
1098 } break;
1099 case Image::FORMAT_INTENSITY: {
1100 return Image();
1101 } break;
1102 case Image::FORMAT_GRAYSCALE_ALPHA: {
1103
1104 format=GL_LUMINANCE_ALPHA;
1105 type=GL_UNSIGNED_BYTE;
1106 pixelsize=2;
1107
1108 } break;
1109 case Image::FORMAT_RGB: {
1110 format=GL_RGB;
1111 type=GL_UNSIGNED_BYTE;
1112 pixelsize=3;
1113 } break;
1114 case Image::FORMAT_RGBA: {
1115
1116 format=GL_RGBA;
1117 type=GL_UNSIGNED_BYTE;
1118 pixelsize=4;
1119 } break;
1120 case Image::FORMAT_INDEXED: {
1121
1122 format=GL_RGB;
1123 type=GL_UNSIGNED_BYTE;
1124 fmt=Image::FORMAT_RGB;
1125 pixelsize=3;
1126 } break;
1127 case Image::FORMAT_INDEXED_ALPHA: {
1128
1129 format=GL_RGBA;
1130 type=GL_UNSIGNED_BYTE;
1131 fmt=Image::FORMAT_RGBA;
1132 pixelsize=4;
1133
1134 } break;
1135 case Image::FORMAT_BC1: {
1136
1137 pixelsize=1; //doesn't matter much
1138 format=GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
1139 compressed=true;
1140 pixelshift=1;
1141 minw=minh=4;
1142
1143 } break;
1144 case Image::FORMAT_BC2: {
1145 pixelsize=1; //doesn't matter much
1146 format=GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
1147 compressed=true;
1148 minw=minh=4;
1149
1150 } break;
1151 case Image::FORMAT_BC3: {
1152
1153 pixelsize=1; //doesn't matter much
1154 format=GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
1155 compressed=true;
1156 minw=minh=4;
1157
1158 } break;
1159 case Image::FORMAT_BC4: {
1160
1161 format=GL_COMPRESSED_RED_RGTC1;
1162 pixelsize=1; //doesn't matter much
1163 compressed=true;
1164 pixelshift=1;
1165 minw=minh=4;
1166
1167 } break;
1168 case Image::FORMAT_BC5: {
1169
1170 format=GL_COMPRESSED_RG_RGTC2;
1171 pixelsize=1; //doesn't matter much
1172 compressed=true;
1173 minw=minh=4;
1174
1175 } break;
1176
1177 default:{}
1178 }
1179
1180 data.resize(texture->data_size);
1181 DVector<uint8_t>::Write wb = data.write();
1182
1183 glActiveTexture(GL_TEXTURE0);
1184 int ofs=0;
1185 glBindTexture(texture->target,texture->tex_id);
1186
1187 int w=texture->alloc_width;
1188 int h=texture->alloc_height;
1189 for(int i=0;i<texture->mipmaps+1;i++) {
1190
1191 if (compressed) {
1192
1193 glPixelStorei(GL_PACK_ALIGNMENT, 4);
1194 glGetCompressedTexImage(texture->target,i,&wb[ofs]);
1195
1196 } else {
1197 glPixelStorei(GL_PACK_ALIGNMENT, 1);
1198 glGetTexImage(texture->target,i,format,type,&wb[ofs]);
1199 }
1200
1201 int size = (w*h*pixelsize)>>pixelshift;
1202 ofs+=size;
1203
1204 w=MAX(minw,w>>1);
1205 h=MAX(minh,h>>1);
1206
1207 }
1208
1209
1210 wb=DVector<uint8_t>::Write();
1211
1212 Image img(texture->alloc_width,texture->alloc_height,texture->mipmaps,fmt,data);
1213
1214 if (texture->format<Image::FORMAT_INDEXED && (texture->alloc_width!=texture->width || texture->alloc_height!=texture->height))
1215 img.resize(texture->width,texture->height);
1216
1217 return img;
1218 #endif
1219 }
1220
texture_set_flags(RID p_texture,uint32_t p_flags)1221 void RasterizerGLES2::texture_set_flags(RID p_texture, uint32_t p_flags) {
1222
1223 Texture *texture = texture_owner.get(p_texture);
1224 ERR_FAIL_COND(!texture);
1225 if (texture->render_target) {
1226
1227 p_flags &= VS::TEXTURE_FLAG_FILTER; //can change only filter
1228 }
1229
1230 bool had_mipmaps = texture->flags & VS::TEXTURE_FLAG_MIPMAPS;
1231
1232 glActiveTexture(GL_TEXTURE0);
1233 glBindTexture(texture->target, texture->tex_id);
1234 uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP;
1235 texture->flags = p_flags | cube; // can't remove a cube from being a cube
1236
1237 bool force_clamp_to_edge = !(p_flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (next_power_of_2(texture->alloc_height) != texture->alloc_height || next_power_of_2(texture->alloc_width) != texture->alloc_width);
1238
1239 if (!force_clamp_to_edge && (texture->flags & VS::TEXTURE_FLAG_REPEAT || texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
1240
1241 if (texture->flags & VS::TEXTURE_FLAG_MIRRORED_REPEAT) {
1242 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
1243 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
1244 } else {
1245 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1246 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1247 }
1248 } else {
1249 //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
1250 glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1251 glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1252 }
1253
1254 if (use_anisotropic_filter) {
1255
1256 if (texture->flags & VS::TEXTURE_FLAG_ANISOTROPIC_FILTER) {
1257
1258 glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_level);
1259 } else {
1260 glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
1261 }
1262 }
1263
1264 if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) {
1265 if (!had_mipmaps && texture->mipmaps == 1) {
1266 glGenerateMipmap(texture->target);
1267 }
1268 glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, use_fast_texture_filter ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR);
1269
1270 } else {
1271 if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
1272 glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1273 } else {
1274 glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1275 }
1276 }
1277
1278 if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
1279
1280 glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
1281
1282 } else {
1283
1284 glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
1285 }
1286 }
texture_get_flags(RID p_texture) const1287 uint32_t RasterizerGLES2::texture_get_flags(RID p_texture) const {
1288
1289 Texture *texture = texture_owner.get(p_texture);
1290
1291 ERR_FAIL_COND_V(!texture, 0);
1292
1293 return texture->flags;
1294 }
texture_get_format(RID p_texture) const1295 Image::Format RasterizerGLES2::texture_get_format(RID p_texture) const {
1296
1297 Texture *texture = texture_owner.get(p_texture);
1298
1299 ERR_FAIL_COND_V(!texture, Image::FORMAT_GRAYSCALE);
1300
1301 return texture->format;
1302 }
texture_get_width(RID p_texture) const1303 uint32_t RasterizerGLES2::texture_get_width(RID p_texture) const {
1304
1305 Texture *texture = texture_owner.get(p_texture);
1306
1307 ERR_FAIL_COND_V(!texture, 0);
1308
1309 return texture->width;
1310 }
texture_get_height(RID p_texture) const1311 uint32_t RasterizerGLES2::texture_get_height(RID p_texture) const {
1312
1313 Texture *texture = texture_owner.get(p_texture);
1314
1315 ERR_FAIL_COND_V(!texture, 0);
1316
1317 return texture->height;
1318 }
1319
texture_has_alpha(RID p_texture) const1320 bool RasterizerGLES2::texture_has_alpha(RID p_texture) const {
1321
1322 Texture *texture = texture_owner.get(p_texture);
1323
1324 ERR_FAIL_COND_V(!texture, 0);
1325
1326 return texture->has_alpha;
1327 }
1328
texture_set_size_override(RID p_texture,int p_width,int p_height)1329 void RasterizerGLES2::texture_set_size_override(RID p_texture, int p_width, int p_height) {
1330
1331 Texture *texture = texture_owner.get(p_texture);
1332
1333 ERR_FAIL_COND(!texture);
1334 ERR_FAIL_COND(texture->render_target);
1335
1336 ERR_FAIL_COND(p_width <= 0 || p_width > 16384);
1337 ERR_FAIL_COND(p_height <= 0 || p_height > 16384);
1338 //real texture size is in alloc width and height
1339 texture->width = p_width;
1340 texture->height = p_height;
1341 }
1342
texture_set_reload_hook(RID p_texture,ObjectID p_owner,const StringName & p_function) const1343 void RasterizerGLES2::texture_set_reload_hook(RID p_texture, ObjectID p_owner, const StringName &p_function) const {
1344
1345 Texture *texture = texture_owner.get(p_texture);
1346
1347 ERR_FAIL_COND(!texture);
1348 ERR_FAIL_COND(texture->render_target);
1349
1350 texture->reloader = p_owner;
1351 texture->reloader_func = p_function;
1352 if (use_reload_hooks && p_owner && keep_copies) {
1353
1354 for (int i = 0; i < 6; i++)
1355 texture->image[i] = Image();
1356 }
1357 }
1358
_texture_get_name(RID p_tex)1359 GLuint RasterizerGLES2::_texture_get_name(RID p_tex) {
1360
1361 Texture *texture = texture_owner.get(p_tex);
1362 ERR_FAIL_COND_V(!texture, 0);
1363
1364 return texture->tex_id;
1365 };
1366
texture_set_path(RID p_texture,const String & p_path)1367 void RasterizerGLES2::texture_set_path(RID p_texture, const String &p_path) {
1368 Texture *texture = texture_owner.get(p_texture);
1369 ERR_FAIL_COND(!texture);
1370
1371 texture->path = p_path;
1372 }
1373
texture_get_path(RID p_texture) const1374 String RasterizerGLES2::texture_get_path(RID p_texture) const {
1375
1376 Texture *texture = texture_owner.get(p_texture);
1377 ERR_FAIL_COND_V(!texture, String());
1378 return texture->path;
1379 }
texture_debug_usage(List<VS::TextureInfo> * r_info)1380 void RasterizerGLES2::texture_debug_usage(List<VS::TextureInfo> *r_info) {
1381
1382 List<RID> textures;
1383 texture_owner.get_owned_list(&textures);
1384
1385 for (List<RID>::Element *E = textures.front(); E; E = E->next()) {
1386
1387 Texture *t = texture_owner.get(E->get());
1388 if (!t)
1389 continue;
1390 VS::TextureInfo tinfo;
1391 tinfo.path = t->path;
1392 tinfo.format = t->format;
1393 tinfo.size.x = t->alloc_width;
1394 tinfo.size.y = t->alloc_height;
1395 tinfo.bytes = t->total_data_size;
1396 r_info->push_back(tinfo);
1397 }
1398 }
1399
texture_set_shrink_all_x2_on_set_data(bool p_enable)1400 void RasterizerGLES2::texture_set_shrink_all_x2_on_set_data(bool p_enable) {
1401
1402 shrink_textures_x2 = p_enable;
1403 }
1404
1405 /* SHADER API */
1406
shader_create(VS::ShaderMode p_mode)1407 RID RasterizerGLES2::shader_create(VS::ShaderMode p_mode) {
1408
1409 Shader *shader = memnew(Shader);
1410 shader->mode = p_mode;
1411 RID rid = shader_owner.make_rid(shader);
1412 shader_set_mode(rid, p_mode);
1413 _shader_make_dirty(shader);
1414
1415 return rid;
1416 }
1417
shader_set_mode(RID p_shader,VS::ShaderMode p_mode)1418 void RasterizerGLES2::shader_set_mode(RID p_shader, VS::ShaderMode p_mode) {
1419
1420 ERR_FAIL_INDEX(p_mode, 3);
1421 Shader *shader = shader_owner.get(p_shader);
1422 ERR_FAIL_COND(!shader);
1423 if (shader->custom_code_id && p_mode == shader->mode)
1424 return;
1425
1426 if (shader->custom_code_id) {
1427
1428 switch (shader->mode) {
1429 case VS::SHADER_MATERIAL: {
1430 material_shader.free_custom_shader(shader->custom_code_id);
1431 } break;
1432 case VS::SHADER_CANVAS_ITEM: {
1433 canvas_shader.free_custom_shader(shader->custom_code_id);
1434 } break;
1435 }
1436
1437 shader->custom_code_id = 0;
1438 }
1439
1440 shader->mode = p_mode;
1441
1442 switch (shader->mode) {
1443 case VS::SHADER_MATERIAL: {
1444 shader->custom_code_id = material_shader.create_custom_shader();
1445 } break;
1446 case VS::SHADER_CANVAS_ITEM: {
1447 shader->custom_code_id = canvas_shader.create_custom_shader();
1448 } break;
1449 }
1450 _shader_make_dirty(shader);
1451 }
shader_get_mode(RID p_shader) const1452 VS::ShaderMode RasterizerGLES2::shader_get_mode(RID p_shader) const {
1453
1454 Shader *shader = shader_owner.get(p_shader);
1455 ERR_FAIL_COND_V(!shader, VS::SHADER_MATERIAL);
1456 return shader->mode;
1457 }
1458
shader_set_code(RID p_shader,const String & p_vertex,const String & p_fragment,const String & p_light,int p_vertex_ofs,int p_fragment_ofs,int p_light_ofs)1459 void RasterizerGLES2::shader_set_code(RID p_shader, const String &p_vertex, const String &p_fragment, const String &p_light, int p_vertex_ofs, int p_fragment_ofs, int p_light_ofs) {
1460
1461 Shader *shader = shader_owner.get(p_shader);
1462 ERR_FAIL_COND(!shader);
1463
1464 #ifdef DEBUG_ENABLED
1465 if (shader->vertex_code == p_vertex && shader->fragment_code == p_fragment && shader->light_code == p_light)
1466 return;
1467 #endif
1468 shader->fragment_code = p_fragment;
1469 shader->vertex_code = p_vertex;
1470 shader->light_code = p_light;
1471 shader->fragment_line = p_fragment_ofs;
1472 shader->vertex_line = p_vertex_ofs;
1473 shader->light_line = p_light_ofs;
1474 _shader_make_dirty(shader);
1475 }
1476
shader_get_vertex_code(RID p_shader) const1477 String RasterizerGLES2::shader_get_vertex_code(RID p_shader) const {
1478
1479 Shader *shader = shader_owner.get(p_shader);
1480 ERR_FAIL_COND_V(!shader, String());
1481 return shader->vertex_code;
1482 }
1483
shader_get_fragment_code(RID p_shader) const1484 String RasterizerGLES2::shader_get_fragment_code(RID p_shader) const {
1485
1486 Shader *shader = shader_owner.get(p_shader);
1487 ERR_FAIL_COND_V(!shader, String());
1488 return shader->fragment_code;
1489 }
1490
shader_get_light_code(RID p_shader) const1491 String RasterizerGLES2::shader_get_light_code(RID p_shader) const {
1492
1493 Shader *shader = shader_owner.get(p_shader);
1494 ERR_FAIL_COND_V(!shader, String());
1495 return shader->light_code;
1496 }
1497
_shader_make_dirty(Shader * p_shader)1498 void RasterizerGLES2::_shader_make_dirty(Shader *p_shader) {
1499
1500 if (p_shader->dirty_list.in_list())
1501 return;
1502
1503 _shader_dirty_list.add(&p_shader->dirty_list);
1504 }
1505
shader_get_param_list(RID p_shader,List<PropertyInfo> * p_param_list) const1506 void RasterizerGLES2::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
1507
1508 Shader *shader = shader_owner.get(p_shader);
1509 ERR_FAIL_COND(!shader);
1510
1511 if (shader->dirty_list.in_list())
1512 _update_shader(shader); // ok should be not anymore dirty
1513
1514 Map<int, StringName> order;
1515
1516 for (Map<StringName, ShaderLanguage::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
1517
1518 order[E->get().order] = E->key();
1519 }
1520
1521 for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
1522
1523 PropertyInfo pi;
1524 ShaderLanguage::Uniform &u = shader->uniforms[E->get()];
1525 pi.name = E->get();
1526 switch (u.type) {
1527
1528 case ShaderLanguage::TYPE_VOID:
1529 case ShaderLanguage::TYPE_BOOL:
1530 case ShaderLanguage::TYPE_FLOAT:
1531 case ShaderLanguage::TYPE_VEC2:
1532 case ShaderLanguage::TYPE_VEC3:
1533 case ShaderLanguage::TYPE_MAT3:
1534 case ShaderLanguage::TYPE_MAT4:
1535 case ShaderLanguage::TYPE_VEC4:
1536 pi.type = u.default_value.get_type();
1537 break;
1538 case ShaderLanguage::TYPE_TEXTURE:
1539 pi.type = Variant::_RID;
1540 pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
1541 pi.hint_string = "Texture";
1542 break;
1543 case ShaderLanguage::TYPE_CUBEMAP:
1544 pi.type = Variant::_RID;
1545 pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
1546 pi.hint_string = "CubeMap";
1547 break;
1548 };
1549
1550 p_param_list->push_back(pi);
1551 }
1552 }
1553
shader_set_default_texture_param(RID p_shader,const StringName & p_name,RID p_texture)1554 void RasterizerGLES2::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) {
1555
1556 Shader *shader = shader_owner.get(p_shader);
1557 ERR_FAIL_COND(!shader);
1558 ERR_FAIL_COND(p_texture.is_valid() && !texture_owner.owns(p_texture));
1559
1560 if (p_texture.is_valid())
1561 shader->default_textures[p_name] = p_texture;
1562 else
1563 shader->default_textures.erase(p_name);
1564
1565 _shader_make_dirty(shader);
1566 }
1567
shader_get_default_texture_param(RID p_shader,const StringName & p_name) const1568 RID RasterizerGLES2::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const {
1569 const Shader *shader = shader_owner.get(p_shader);
1570 ERR_FAIL_COND_V(!shader, RID());
1571
1572 const Map<StringName, RID>::Element *E = shader->default_textures.find(p_name);
1573 if (!E)
1574 return RID();
1575 return E->get();
1576 }
1577
shader_get_default_param(RID p_shader,const StringName & p_name)1578 Variant RasterizerGLES2::shader_get_default_param(RID p_shader, const StringName &p_name) {
1579
1580 Shader *shader = shader_owner.get(p_shader);
1581 ERR_FAIL_COND_V(!shader, Variant());
1582
1583 //update shader params if necesary
1584 //make sure the shader is compiled and everything
1585 //so the actual parameters can be properly retrieved!
1586 if (shader->dirty_list.in_list()) {
1587 _update_shader(shader);
1588 }
1589 if (shader->valid && shader->uniforms.has(p_name))
1590 return shader->uniforms[p_name].default_value;
1591
1592 return Variant();
1593 }
1594
1595 /* COMMON MATERIAL API */
1596
material_create()1597 RID RasterizerGLES2::material_create() {
1598
1599 RID material = material_owner.make_rid(memnew(Material));
1600 return material;
1601 }
1602
material_set_shader(RID p_material,RID p_shader)1603 void RasterizerGLES2::material_set_shader(RID p_material, RID p_shader) {
1604
1605 Material *material = material_owner.get(p_material);
1606 ERR_FAIL_COND(!material);
1607 if (material->shader == p_shader)
1608 return;
1609 material->shader = p_shader;
1610 material->shader_version = 0;
1611 }
1612
material_get_shader(RID p_material) const1613 RID RasterizerGLES2::material_get_shader(RID p_material) const {
1614
1615 Material *material = material_owner.get(p_material);
1616 ERR_FAIL_COND_V(!material, RID());
1617 return material->shader;
1618 }
1619
material_set_param(RID p_material,const StringName & p_param,const Variant & p_value)1620 void RasterizerGLES2::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
1621
1622 Material *material = material_owner.get(p_material);
1623 ERR_FAIL_COND(!material);
1624
1625 Map<StringName, Material::UniformData>::Element *E = material->shader_params.find(p_param);
1626 if (E) {
1627
1628 if (p_value.get_type() == Variant::NIL) {
1629
1630 material->shader_params.erase(E);
1631 material->shader_version = 0; //get default!
1632 } else {
1633 E->get().value = p_value;
1634 E->get().inuse = true;
1635 }
1636 } else {
1637
1638 if (p_value.get_type() == Variant::NIL)
1639 return;
1640
1641 Material::UniformData ud;
1642 ud.index = -1;
1643 ud.value = p_value;
1644 ud.istexture = p_value.get_type() == Variant::_RID; /// cache it being texture
1645 ud.inuse = true;
1646 material->shader_params[p_param] = ud; //may be got at some point, or erased
1647 }
1648 }
material_get_param(RID p_material,const StringName & p_param) const1649 Variant RasterizerGLES2::material_get_param(RID p_material, const StringName &p_param) const {
1650
1651 Material *material = material_owner.get(p_material);
1652 ERR_FAIL_COND_V(!material, Variant());
1653
1654 if (material->shader.is_valid()) {
1655 //update shader params if necesary
1656 //make sure the shader is compiled and everything
1657 //so the actual parameters can be properly retrieved!
1658 material->shader_cache = shader_owner.get(material->shader);
1659 if (!material->shader_cache) {
1660 //invalidate
1661 material->shader = RID();
1662 material->shader_cache = NULL;
1663 } else {
1664
1665 if (material->shader_cache->dirty_list.in_list())
1666 _update_shader(material->shader_cache);
1667 if (material->shader_cache->valid && material->shader_cache->version != material->shader_version) {
1668 //validate
1669 _update_material_shader_params(material);
1670 }
1671 }
1672 }
1673
1674 if (material->shader_params.has(p_param) && material->shader_params[p_param].inuse)
1675 return material->shader_params[p_param].value;
1676 else
1677 return Variant();
1678 }
1679
material_set_flag(RID p_material,VS::MaterialFlag p_flag,bool p_enabled)1680 void RasterizerGLES2::material_set_flag(RID p_material, VS::MaterialFlag p_flag, bool p_enabled) {
1681
1682 Material *material = material_owner.get(p_material);
1683 ERR_FAIL_COND(!material);
1684 ERR_FAIL_INDEX(p_flag, VS::MATERIAL_FLAG_MAX);
1685
1686 material->flags[p_flag] = p_enabled;
1687 }
material_get_flag(RID p_material,VS::MaterialFlag p_flag) const1688 bool RasterizerGLES2::material_get_flag(RID p_material, VS::MaterialFlag p_flag) const {
1689
1690 Material *material = material_owner.get(p_material);
1691 ERR_FAIL_COND_V(!material, false);
1692 ERR_FAIL_INDEX_V(p_flag, VS::MATERIAL_FLAG_MAX, false);
1693 return material->flags[p_flag];
1694 }
1695
material_set_depth_draw_mode(RID p_material,VS::MaterialDepthDrawMode p_mode)1696 void RasterizerGLES2::material_set_depth_draw_mode(RID p_material, VS::MaterialDepthDrawMode p_mode) {
1697
1698 Material *material = material_owner.get(p_material);
1699 ERR_FAIL_COND(!material);
1700 material->depth_draw_mode = p_mode;
1701 }
1702
material_get_depth_draw_mode(RID p_material) const1703 VS::MaterialDepthDrawMode RasterizerGLES2::material_get_depth_draw_mode(RID p_material) const {
1704
1705 Material *material = material_owner.get(p_material);
1706 ERR_FAIL_COND_V(!material, VS::MATERIAL_DEPTH_DRAW_ALWAYS);
1707 return material->depth_draw_mode;
1708 }
1709
material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode)1710 void RasterizerGLES2::material_set_blend_mode(RID p_material, VS::MaterialBlendMode p_mode) {
1711
1712 Material *material = material_owner.get(p_material);
1713 ERR_FAIL_COND(!material);
1714 material->blend_mode = p_mode;
1715 }
material_get_blend_mode(RID p_material) const1716 VS::MaterialBlendMode RasterizerGLES2::material_get_blend_mode(RID p_material) const {
1717
1718 Material *material = material_owner.get(p_material);
1719 ERR_FAIL_COND_V(!material, VS::MATERIAL_BLEND_MODE_ADD);
1720 return material->blend_mode;
1721 }
1722
material_set_line_width(RID p_material,float p_line_width)1723 void RasterizerGLES2::material_set_line_width(RID p_material, float p_line_width) {
1724
1725 Material *material = material_owner.get(p_material);
1726 ERR_FAIL_COND(!material);
1727 material->line_width = p_line_width;
1728 }
material_get_line_width(RID p_material) const1729 float RasterizerGLES2::material_get_line_width(RID p_material) const {
1730
1731 Material *material = material_owner.get(p_material);
1732 ERR_FAIL_COND_V(!material, 0);
1733
1734 return material->line_width;
1735 }
1736
1737 /* MESH API */
1738
mesh_create()1739 RID RasterizerGLES2::mesh_create() {
1740
1741 return mesh_owner.make_rid(memnew(Mesh));
1742 }
1743
mesh_add_surface(RID p_mesh,VS::PrimitiveType p_primitive,const Array & p_arrays,const Array & p_blend_shapes,bool p_alpha_sort)1744 void RasterizerGLES2::mesh_add_surface(RID p_mesh, VS::PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, bool p_alpha_sort) {
1745
1746 Mesh *mesh = mesh_owner.get(p_mesh);
1747 ERR_FAIL_COND(!mesh);
1748
1749 ERR_FAIL_INDEX(p_primitive, VS::PRIMITIVE_MAX);
1750 ERR_FAIL_COND(p_arrays.size() != VS::ARRAY_MAX);
1751
1752 uint32_t format = 0;
1753
1754 // validation
1755 int index_array_len = 0;
1756 int array_len = 0;
1757
1758 for (int i = 0; i < p_arrays.size(); i++) {
1759
1760 if (p_arrays[i].get_type() == Variant::NIL)
1761 continue;
1762
1763 format |= (1 << i);
1764
1765 if (i == VS::ARRAY_VERTEX) {
1766
1767 array_len = Vector3Array(p_arrays[i]).size();
1768 ERR_FAIL_COND(array_len == 0);
1769 } else if (i == VS::ARRAY_INDEX) {
1770
1771 index_array_len = IntArray(p_arrays[i]).size();
1772 }
1773 }
1774
1775 ERR_FAIL_COND((format & VS::ARRAY_FORMAT_VERTEX) == 0); // mandatory
1776
1777 ERR_FAIL_COND(mesh->morph_target_count != p_blend_shapes.size());
1778 if (mesh->morph_target_count) {
1779 //validate format for morphs
1780 for (int i = 0; i < p_blend_shapes.size(); i++) {
1781
1782 uint32_t bsformat = 0;
1783 Array arr = p_blend_shapes[i];
1784 for (int j = 0; j < arr.size(); j++) {
1785
1786 if (arr[j].get_type() != Variant::NIL)
1787 bsformat |= (1 << j);
1788 }
1789
1790 ERR_FAIL_COND((bsformat) != (format & (VS::ARRAY_FORMAT_BONES - 1)));
1791 }
1792 }
1793
1794 Surface *surface = memnew(Surface);
1795 ERR_FAIL_COND(!surface);
1796
1797 bool use_VBO = true; //glGenBuffersARB!=NULL; // TODO detect if it's in there
1798 if ((!use_hw_skeleton_xform && format & VS::ARRAY_FORMAT_WEIGHTS) || mesh->morph_target_count > 0) {
1799
1800 use_VBO = false;
1801 }
1802
1803 // surface->packed=pack_arrays && use_VBO;
1804
1805 int total_elem_size = 0;
1806
1807 for (int i = 0; i < VS::ARRAY_MAX; i++) {
1808
1809 Surface::ArrayData &ad = surface->array[i];
1810 ad.size = 0;
1811 ad.ofs = 0;
1812 int elem_size = 0;
1813 int elem_count = 0;
1814 bool valid_local = true;
1815 GLenum datatype;
1816 bool normalize = false;
1817 bool bind = false;
1818
1819 if (!(format & (1 << i))) // no array
1820 continue;
1821
1822 switch (i) {
1823
1824 case VS::ARRAY_VERTEX: {
1825
1826 if (use_VBO && use_half_float) {
1827 elem_size = 3 * sizeof(int16_t); // vertex
1828 datatype = _GL_HALF_FLOAT_OES;
1829 } else {
1830
1831 elem_size = 3 * sizeof(GLfloat); // vertex
1832 datatype = GL_FLOAT;
1833 }
1834 bind = true;
1835 elem_count = 3;
1836
1837 } break;
1838 case VS::ARRAY_NORMAL: {
1839
1840 if (use_VBO) {
1841 elem_size = 4 * sizeof(int8_t); // vertex
1842 datatype = GL_BYTE;
1843 normalize = true;
1844 } else {
1845 elem_size = 3 * sizeof(GLfloat); // vertex
1846 datatype = GL_FLOAT;
1847 }
1848 bind = true;
1849 elem_count = 3;
1850 } break;
1851 case VS::ARRAY_TANGENT: {
1852 if (use_VBO) {
1853 elem_size = 4 * sizeof(int8_t); // vertex
1854 datatype = GL_BYTE;
1855 normalize = true;
1856 } else {
1857 elem_size = 4 * sizeof(GLfloat); // vertex
1858 datatype = GL_FLOAT;
1859 }
1860 bind = true;
1861 elem_count = 4;
1862
1863 } break;
1864 case VS::ARRAY_COLOR: {
1865
1866 elem_size = 4 * sizeof(uint8_t); /* RGBA */
1867 datatype = GL_UNSIGNED_BYTE;
1868 elem_count = 4;
1869 bind = true;
1870 normalize = true;
1871 } break;
1872 case VS::ARRAY_TEX_UV:
1873 case VS::ARRAY_TEX_UV2: {
1874 if (use_VBO && use_half_float) {
1875 elem_size = 2 * sizeof(int16_t); // vertex
1876 datatype = _GL_HALF_FLOAT_OES;
1877 } else {
1878 elem_size = 2 * sizeof(GLfloat); // vertex
1879 datatype = GL_FLOAT;
1880 }
1881 bind = true;
1882 elem_count = 2;
1883
1884 } break;
1885 case VS::ARRAY_WEIGHTS: {
1886
1887 if (use_VBO) {
1888
1889 elem_size = VS::ARRAY_WEIGHTS_SIZE * sizeof(GLushort);
1890 valid_local = false;
1891 bind = true;
1892 normalize = true;
1893 datatype = GL_UNSIGNED_SHORT;
1894 elem_count = 4;
1895
1896 } else {
1897 elem_size = VS::ARRAY_WEIGHTS_SIZE * sizeof(GLfloat);
1898 valid_local = false;
1899 bind = false;
1900 datatype = GL_FLOAT;
1901 elem_count = 4;
1902 }
1903
1904 } break;
1905 case VS::ARRAY_BONES: {
1906
1907 if (use_VBO) {
1908 elem_size = VS::ARRAY_WEIGHTS_SIZE * sizeof(GLubyte);
1909 valid_local = false;
1910 bind = true;
1911 datatype = GL_UNSIGNED_BYTE;
1912 elem_count = 4;
1913 } else {
1914
1915 elem_size = VS::ARRAY_WEIGHTS_SIZE * sizeof(GLushort);
1916 valid_local = false;
1917 bind = false;
1918 datatype = GL_UNSIGNED_SHORT;
1919 elem_count = 4;
1920 }
1921
1922 } break;
1923 case VS::ARRAY_INDEX: {
1924
1925 if (index_array_len <= 0) {
1926 ERR_PRINT("index_array_len==NO_INDEX_ARRAY");
1927 break;
1928 }
1929 /* determine wether using 16 or 32 bits indices */
1930 if (array_len > (1 << 16)) {
1931
1932 elem_size = 4;
1933 datatype = GL_UNSIGNED_INT;
1934 } else {
1935 elem_size = 2;
1936 datatype = GL_UNSIGNED_SHORT;
1937 }
1938
1939 /*
1940 if (use_VBO) {
1941
1942 glGenBuffers(1,&surface->index_id);
1943 ERR_FAIL_COND(surface->index_id==0);
1944 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,surface->index_id);
1945 glBufferData(GL_ELEMENT_ARRAY_BUFFER,index_array_len*elem_size,NULL,GL_STATIC_DRAW);
1946 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); //unbind
1947 } else {
1948 surface->index_array_local = (uint8_t*)memalloc(index_array_len*elem_size);
1949 };
1950 */
1951 surface->index_array_len = index_array_len; // only way it can exist
1952 ad.ofs = 0;
1953 ad.size = elem_size;
1954
1955 continue;
1956 } break;
1957 default: {
1958 ERR_FAIL();
1959 }
1960 }
1961
1962 ad.ofs = total_elem_size;
1963 ad.size = elem_size;
1964 ad.datatype = datatype;
1965 ad.normalize = normalize;
1966 ad.bind = bind;
1967 ad.count = elem_count;
1968 total_elem_size += elem_size;
1969 if (valid_local) {
1970 surface->local_stride += elem_size;
1971 surface->morph_format |= (1 << i);
1972 }
1973 }
1974
1975 surface->stride = total_elem_size;
1976 surface->array_len = array_len;
1977 surface->format = format;
1978 surface->primitive = p_primitive;
1979 surface->morph_target_count = mesh->morph_target_count;
1980 surface->configured_format = 0;
1981 surface->mesh = mesh;
1982 if (keep_copies) {
1983 surface->data = p_arrays;
1984 surface->morph_data = p_blend_shapes;
1985 }
1986
1987 uint8_t *array_ptr = NULL;
1988 uint8_t *index_array_ptr = NULL;
1989 DVector<uint8_t> array_pre_vbo;
1990 DVector<uint8_t>::Write vaw;
1991 DVector<uint8_t> index_array_pre_vbo;
1992 DVector<uint8_t>::Write iaw;
1993
1994 /* create pointers */
1995 if (use_VBO) {
1996
1997 array_pre_vbo.resize(surface->array_len * surface->stride);
1998 vaw = array_pre_vbo.write();
1999 array_ptr = vaw.ptr();
2000
2001 if (surface->index_array_len) {
2002
2003 index_array_pre_vbo.resize(surface->index_array_len * surface->array[VS::ARRAY_INDEX].size);
2004 iaw = index_array_pre_vbo.write();
2005 index_array_ptr = iaw.ptr();
2006 }
2007
2008 _surface_set_arrays(surface, array_ptr, index_array_ptr, p_arrays, true);
2009
2010 } else {
2011
2012 surface->array_local = (uint8_t *)memalloc(surface->array_len * surface->stride);
2013 array_ptr = (uint8_t *)surface->array_local;
2014 if (surface->index_array_len) {
2015 surface->index_array_local = (uint8_t *)memalloc(index_array_len * surface->array[VS::ARRAY_INDEX].size);
2016 index_array_ptr = (uint8_t *)surface->index_array_local;
2017 }
2018
2019 _surface_set_arrays(surface, array_ptr, index_array_ptr, p_arrays, true);
2020
2021 if (mesh->morph_target_count) {
2022
2023 surface->morph_targets_local = memnew_arr(Surface::MorphTarget, mesh->morph_target_count);
2024 for (int i = 0; i < mesh->morph_target_count; i++) {
2025
2026 surface->morph_targets_local[i].array = memnew_arr(uint8_t, surface->local_stride * surface->array_len);
2027 surface->morph_targets_local[i].configured_format = surface->morph_format;
2028 _surface_set_arrays(surface, surface->morph_targets_local[i].array, NULL, p_blend_shapes[i], false);
2029 }
2030 }
2031 }
2032
2033 /* create buffers!! */
2034 if (use_VBO) {
2035 glGenBuffers(1, &surface->vertex_id);
2036 ERR_FAIL_COND(surface->vertex_id == 0);
2037 glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
2038 glBufferData(GL_ARRAY_BUFFER, surface->array_len * surface->stride, array_ptr, GL_STATIC_DRAW);
2039 glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
2040 if (surface->index_array_len) {
2041
2042 glGenBuffers(1, &surface->index_id);
2043 ERR_FAIL_COND(surface->index_id == 0);
2044 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
2045 glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_array_len * surface->array[VS::ARRAY_INDEX].size, index_array_ptr, GL_STATIC_DRAW);
2046 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
2047 }
2048 }
2049
2050 mesh->surfaces.push_back(surface);
2051 }
2052
_surface_set_arrays(Surface * p_surface,uint8_t * p_mem,uint8_t * p_index_mem,const Array & p_arrays,bool p_main)2053 Error RasterizerGLES2::_surface_set_arrays(Surface *p_surface, uint8_t *p_mem, uint8_t *p_index_mem, const Array &p_arrays, bool p_main) {
2054
2055 uint32_t stride = p_main ? p_surface->stride : p_surface->local_stride;
2056
2057 for (int ai = 0; ai < VS::ARRAY_MAX; ai++) {
2058 if (ai >= p_arrays.size())
2059 break;
2060 if (p_arrays[ai].get_type() == Variant::NIL)
2061 continue;
2062 Surface::ArrayData &a = p_surface->array[ai];
2063
2064 switch (ai) {
2065
2066 case VS::ARRAY_VERTEX: {
2067
2068 ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER);
2069
2070 DVector<Vector3> array = p_arrays[ai];
2071 ERR_FAIL_COND_V(array.size() != p_surface->array_len, ERR_INVALID_PARAMETER);
2072
2073 DVector<Vector3>::Read read = array.read();
2074 const Vector3 *src = read.ptr();
2075
2076 // setting vertices means regenerating the AABB
2077 AABB aabb;
2078
2079 float scale = 1;
2080
2081 if (p_surface->array[VS::ARRAY_VERTEX].datatype == _GL_HALF_FLOAT_OES) {
2082
2083 for (int i = 0; i < p_surface->array_len; i++) {
2084
2085 uint16_t vector[3] = { make_half_float(src[i].x), make_half_float(src[i].y), make_half_float(src[i].z) };
2086
2087 copymem(&p_mem[a.ofs + i * stride], vector, a.size);
2088
2089 if (i == 0) {
2090
2091 aabb = AABB(src[i], Vector3());
2092 } else {
2093
2094 aabb.expand_to(src[i]);
2095 }
2096 }
2097
2098 } else {
2099 for (int i = 0; i < p_surface->array_len; i++) {
2100
2101 GLfloat vector[3] = { src[i].x, src[i].y, src[i].z };
2102
2103 copymem(&p_mem[a.ofs + i * stride], vector, a.size);
2104
2105 if (i == 0) {
2106
2107 aabb = AABB(src[i], Vector3());
2108 } else {
2109
2110 aabb.expand_to(src[i]);
2111 }
2112 }
2113 }
2114
2115 if (p_main) {
2116 p_surface->aabb = aabb;
2117 p_surface->vertex_scale = scale;
2118 }
2119
2120 } break;
2121 case VS::ARRAY_NORMAL: {
2122
2123 ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER);
2124
2125 DVector<Vector3> array = p_arrays[ai];
2126 ERR_FAIL_COND_V(array.size() != p_surface->array_len, ERR_INVALID_PARAMETER);
2127
2128 DVector<Vector3>::Read read = array.read();
2129 const Vector3 *src = read.ptr();
2130
2131 // setting vertices means regenerating the AABB
2132
2133 if (p_surface->array[VS::ARRAY_NORMAL].datatype == GL_BYTE) {
2134
2135 for (int i = 0; i < p_surface->array_len; i++) {
2136
2137 GLbyte vector[4] = {
2138 (GLbyte)CLAMP(src[i].x * 127, -128, 127),
2139 (GLbyte)CLAMP(src[i].y * 127, -128, 127),
2140 (GLbyte)CLAMP(src[i].z * 127, -128, 127),
2141 0,
2142 };
2143
2144 copymem(&p_mem[a.ofs + i * stride], vector, a.size);
2145 }
2146
2147 } else {
2148 for (int i = 0; i < p_surface->array_len; i++) {
2149
2150 GLfloat vector[3] = { src[i].x, src[i].y, src[i].z };
2151 copymem(&p_mem[a.ofs + i * stride], vector, a.size);
2152 }
2153 }
2154
2155 } break;
2156 case VS::ARRAY_TANGENT: {
2157
2158 ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER);
2159
2160 DVector<real_t> array = p_arrays[ai];
2161
2162 ERR_FAIL_COND_V(array.size() != p_surface->array_len * 4, ERR_INVALID_PARAMETER);
2163
2164 DVector<real_t>::Read read = array.read();
2165 const real_t *src = read.ptr();
2166
2167 if (p_surface->array[VS::ARRAY_TANGENT].datatype == GL_BYTE) {
2168
2169 for (int i = 0; i < p_surface->array_len; i++) {
2170
2171 GLbyte xyzw[4] = {
2172 (GLbyte)CLAMP(src[i * 4 + 0] * 127, -128, 127),
2173 (GLbyte)CLAMP(src[i * 4 + 1] * 127, -128, 127),
2174 (GLbyte)CLAMP(src[i * 4 + 2] * 127, -128, 127),
2175 (GLbyte)CLAMP(src[i * 4 + 3] * 127, -128, 127)
2176 };
2177
2178 copymem(&p_mem[a.ofs + i * stride], xyzw, a.size);
2179 }
2180
2181 } else {
2182 for (int i = 0; i < p_surface->array_len; i++) {
2183
2184 GLfloat xyzw[4] = {
2185 src[i * 4 + 0],
2186 src[i * 4 + 1],
2187 src[i * 4 + 2],
2188 src[i * 4 + 3]
2189 };
2190
2191 copymem(&p_mem[a.ofs + i * stride], xyzw, a.size);
2192 }
2193 }
2194
2195 } break;
2196 case VS::ARRAY_COLOR: {
2197
2198 ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::COLOR_ARRAY, ERR_INVALID_PARAMETER);
2199
2200 DVector<Color> array = p_arrays[ai];
2201
2202 ERR_FAIL_COND_V(array.size() != p_surface->array_len, ERR_INVALID_PARAMETER);
2203
2204 DVector<Color>::Read read = array.read();
2205 const Color *src = read.ptr();
2206 bool alpha = false;
2207
2208 for (int i = 0; i < p_surface->array_len; i++) {
2209
2210 if (src[i].a < 0.98) // tolerate alpha a bit, for crappy exporters
2211 alpha = true;
2212
2213 uint8_t colors[4];
2214
2215 for (int j = 0; j < 4; j++) {
2216
2217 colors[j] = CLAMP(int((src[i][j]) * 255.0), 0, 255);
2218 }
2219
2220 copymem(&p_mem[a.ofs + i * stride], colors, a.size);
2221 }
2222
2223 if (p_main)
2224 p_surface->has_alpha = alpha;
2225
2226 } break;
2227 case VS::ARRAY_TEX_UV:
2228 case VS::ARRAY_TEX_UV2: {
2229
2230 ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::VECTOR3_ARRAY && p_arrays[ai].get_type() != Variant::VECTOR2_ARRAY, ERR_INVALID_PARAMETER);
2231
2232 DVector<Vector2> array = p_arrays[ai];
2233
2234 ERR_FAIL_COND_V(array.size() != p_surface->array_len, ERR_INVALID_PARAMETER);
2235
2236 DVector<Vector2>::Read read = array.read();
2237
2238 const Vector2 *src = read.ptr();
2239 float scale = 1.0;
2240
2241 if (p_surface->array[ai].datatype == _GL_HALF_FLOAT_OES) {
2242
2243 for (int i = 0; i < p_surface->array_len; i++) {
2244
2245 uint16_t uv[2] = { make_half_float(src[i].x), make_half_float(src[i].y) };
2246 copymem(&p_mem[a.ofs + i * stride], uv, a.size);
2247 }
2248
2249 } else {
2250 for (int i = 0; i < p_surface->array_len; i++) {
2251
2252 GLfloat uv[2] = { src[i].x, src[i].y };
2253
2254 copymem(&p_mem[a.ofs + i * stride], uv, a.size);
2255 }
2256 }
2257
2258 if (p_main) {
2259
2260 if (ai == VS::ARRAY_TEX_UV) {
2261
2262 p_surface->uv_scale = scale;
2263 }
2264 if (ai == VS::ARRAY_TEX_UV2) {
2265
2266 p_surface->uv2_scale = scale;
2267 }
2268 }
2269
2270 } break;
2271 case VS::ARRAY_WEIGHTS: {
2272
2273 ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER);
2274
2275 DVector<real_t> array = p_arrays[ai];
2276
2277 ERR_FAIL_COND_V(array.size() != p_surface->array_len * VS::ARRAY_WEIGHTS_SIZE, ERR_INVALID_PARAMETER);
2278
2279 DVector<real_t>::Read read = array.read();
2280
2281 const real_t *src = read.ptr();
2282
2283 if (p_surface->array[VS::ARRAY_WEIGHTS].datatype == GL_UNSIGNED_SHORT) {
2284
2285 for (int i = 0; i < p_surface->array_len; i++) {
2286
2287 GLushort data[VS::ARRAY_WEIGHTS_SIZE];
2288 for (int j = 0; j < VS::ARRAY_WEIGHTS_SIZE; j++) {
2289 data[j] = CLAMP(src[i * VS::ARRAY_WEIGHTS_SIZE + j] * 65535, 0, 65535);
2290 }
2291
2292 copymem(&p_mem[a.ofs + i * stride], data, a.size);
2293 }
2294 } else {
2295
2296 for (int i = 0; i < p_surface->array_len; i++) {
2297
2298 GLfloat data[VS::ARRAY_WEIGHTS_SIZE];
2299 for (int j = 0; j < VS::ARRAY_WEIGHTS_SIZE; j++) {
2300 data[j] = src[i * VS::ARRAY_WEIGHTS_SIZE + j];
2301 }
2302
2303 copymem(&p_mem[a.ofs + i * stride], data, a.size);
2304 }
2305 }
2306
2307 } break;
2308 case VS::ARRAY_BONES: {
2309
2310 ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER);
2311
2312 DVector<int> array = p_arrays[ai];
2313
2314 ERR_FAIL_COND_V(array.size() != p_surface->array_len * VS::ARRAY_WEIGHTS_SIZE, ERR_INVALID_PARAMETER);
2315
2316 DVector<int>::Read read = array.read();
2317
2318 const int *src = read.ptr();
2319
2320 p_surface->max_bone = 0;
2321
2322 if (p_surface->array[VS::ARRAY_BONES].datatype == GL_UNSIGNED_BYTE) {
2323
2324 for (int i = 0; i < p_surface->array_len; i++) {
2325
2326 GLubyte data[VS::ARRAY_WEIGHTS_SIZE];
2327 for (int j = 0; j < VS::ARRAY_WEIGHTS_SIZE; j++) {
2328 data[j] = CLAMP(src[i * VS::ARRAY_WEIGHTS_SIZE + j], 0, 255);
2329 p_surface->max_bone = MAX(data[j], p_surface->max_bone);
2330 }
2331
2332 copymem(&p_mem[a.ofs + i * stride], data, a.size);
2333 }
2334
2335 } else {
2336 for (int i = 0; i < p_surface->array_len; i++) {
2337
2338 GLushort data[VS::ARRAY_WEIGHTS_SIZE];
2339 for (int j = 0; j < VS::ARRAY_WEIGHTS_SIZE; j++) {
2340 data[j] = src[i * VS::ARRAY_WEIGHTS_SIZE + j];
2341 p_surface->max_bone = MAX(data[j], p_surface->max_bone);
2342 }
2343
2344 copymem(&p_mem[a.ofs + i * stride], data, a.size);
2345 }
2346 }
2347
2348 } break;
2349 case VS::ARRAY_INDEX: {
2350
2351 ERR_FAIL_COND_V(p_surface->index_array_len <= 0, ERR_INVALID_DATA);
2352 ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::INT_ARRAY, ERR_INVALID_PARAMETER);
2353
2354 DVector<int> indices = p_arrays[ai];
2355 ERR_FAIL_COND_V(indices.size() == 0, ERR_INVALID_PARAMETER);
2356 ERR_FAIL_COND_V(indices.size() != p_surface->index_array_len, ERR_INVALID_PARAMETER);
2357
2358 /* determine wether using 16 or 32 bits indices */
2359
2360 DVector<int>::Read read = indices.read();
2361 const int *src = read.ptr();
2362
2363 for (int i = 0; i < p_surface->index_array_len; i++) {
2364
2365 if (a.size == 2) {
2366 uint16_t v = src[i];
2367
2368 copymem(&p_index_mem[i * a.size], &v, a.size);
2369 } else {
2370 uint32_t v = src[i];
2371
2372 copymem(&p_index_mem[i * a.size], &v, a.size);
2373 }
2374 }
2375
2376 } break;
2377
2378 default: { ERR_FAIL_V(ERR_INVALID_PARAMETER); }
2379 }
2380
2381 p_surface->configured_format |= (1 << ai);
2382 }
2383
2384 if (p_surface->format & VS::ARRAY_FORMAT_BONES) {
2385 //create AABBs for each detected bone
2386 int total_bones = p_surface->max_bone + 1;
2387 if (p_main) {
2388 p_surface->skeleton_bone_aabb.resize(total_bones);
2389 p_surface->skeleton_bone_used.resize(total_bones);
2390 for (int i = 0; i < total_bones; i++)
2391 p_surface->skeleton_bone_used[i] = false;
2392 }
2393 DVector<Vector3> vertices = p_arrays[VS::ARRAY_VERTEX];
2394 DVector<int> bones = p_arrays[VS::ARRAY_BONES];
2395 DVector<float> weights = p_arrays[VS::ARRAY_WEIGHTS];
2396
2397 bool any_valid = false;
2398
2399 if (vertices.size() && bones.size() == vertices.size() * 4 && weights.size() == bones.size()) {
2400 //print_line("MAKING SKELETHONG");
2401 int vs = vertices.size();
2402 DVector<Vector3>::Read rv = vertices.read();
2403 DVector<int>::Read rb = bones.read();
2404 DVector<float>::Read rw = weights.read();
2405
2406 Vector<bool> first;
2407 first.resize(total_bones);
2408 for (int i = 0; i < total_bones; i++) {
2409 first[i] = p_main;
2410 }
2411 AABB *bptr = p_surface->skeleton_bone_aabb.ptr();
2412 bool *fptr = first.ptr();
2413 bool *usedptr = p_surface->skeleton_bone_used.ptr();
2414
2415 for (int i = 0; i < vs; i++) {
2416
2417 Vector3 v = rv[i];
2418 for (int j = 0; j < 4; j++) {
2419
2420 int idx = rb[i * 4 + j];
2421 float w = rw[i * 4 + j];
2422 if (w == 0)
2423 continue; //break;
2424 ERR_FAIL_INDEX_V(idx, total_bones, ERR_INVALID_DATA);
2425
2426 if (fptr[idx]) {
2427 bptr[idx].pos = v;
2428 fptr[idx] = false;
2429 any_valid = true;
2430 } else {
2431 bptr[idx].expand_to(v);
2432 }
2433 usedptr[idx] = true;
2434 }
2435 }
2436 }
2437
2438 if (p_main && !any_valid) {
2439
2440 p_surface->skeleton_bone_aabb.clear();
2441 p_surface->skeleton_bone_used.clear();
2442 }
2443 }
2444
2445 return OK;
2446 }
2447
mesh_add_custom_surface(RID p_mesh,const Variant & p_dat)2448 void RasterizerGLES2::mesh_add_custom_surface(RID p_mesh, const Variant &p_dat) {
2449
2450 ERR_EXPLAIN("OpenGL Rasterizer does not support custom surfaces. Running on wrong platform?");
2451 ERR_FAIL();
2452 }
2453
mesh_get_surface_arrays(RID p_mesh,int p_surface) const2454 Array RasterizerGLES2::mesh_get_surface_arrays(RID p_mesh, int p_surface) const {
2455
2456 Mesh *mesh = mesh_owner.get(p_mesh);
2457 ERR_FAIL_COND_V(!mesh, Array());
2458 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Array());
2459 Surface *surface = mesh->surfaces[p_surface];
2460 ERR_FAIL_COND_V(!surface, Array());
2461
2462 return surface->data;
2463 }
mesh_get_surface_morph_arrays(RID p_mesh,int p_surface) const2464 Array RasterizerGLES2::mesh_get_surface_morph_arrays(RID p_mesh, int p_surface) const {
2465
2466 Mesh *mesh = mesh_owner.get(p_mesh);
2467 ERR_FAIL_COND_V(!mesh, Array());
2468 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Array());
2469 Surface *surface = mesh->surfaces[p_surface];
2470 ERR_FAIL_COND_V(!surface, Array());
2471
2472 return surface->morph_data;
2473 }
2474
mesh_set_morph_target_count(RID p_mesh,int p_amount)2475 void RasterizerGLES2::mesh_set_morph_target_count(RID p_mesh, int p_amount) {
2476
2477 Mesh *mesh = mesh_owner.get(p_mesh);
2478 ERR_FAIL_COND(!mesh);
2479 ERR_FAIL_COND(mesh->surfaces.size() != 0);
2480
2481 mesh->morph_target_count = p_amount;
2482 }
2483
mesh_get_morph_target_count(RID p_mesh) const2484 int RasterizerGLES2::mesh_get_morph_target_count(RID p_mesh) const {
2485
2486 Mesh *mesh = mesh_owner.get(p_mesh);
2487 ERR_FAIL_COND_V(!mesh, -1);
2488
2489 return mesh->morph_target_count;
2490 }
2491
mesh_set_morph_target_mode(RID p_mesh,VS::MorphTargetMode p_mode)2492 void RasterizerGLES2::mesh_set_morph_target_mode(RID p_mesh, VS::MorphTargetMode p_mode) {
2493
2494 ERR_FAIL_INDEX(p_mode, 2);
2495 Mesh *mesh = mesh_owner.get(p_mesh);
2496 ERR_FAIL_COND(!mesh);
2497
2498 mesh->morph_target_mode = p_mode;
2499 }
2500
mesh_get_morph_target_mode(RID p_mesh) const2501 VS::MorphTargetMode RasterizerGLES2::mesh_get_morph_target_mode(RID p_mesh) const {
2502
2503 Mesh *mesh = mesh_owner.get(p_mesh);
2504 ERR_FAIL_COND_V(!mesh, VS::MORPH_MODE_NORMALIZED);
2505
2506 return mesh->morph_target_mode;
2507 }
2508
mesh_surface_set_material(RID p_mesh,int p_surface,RID p_material,bool p_owned)2509 void RasterizerGLES2::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material, bool p_owned) {
2510
2511 Mesh *mesh = mesh_owner.get(p_mesh);
2512 ERR_FAIL_COND(!mesh);
2513 ERR_FAIL_INDEX(p_surface, mesh->surfaces.size());
2514 Surface *surface = mesh->surfaces[p_surface];
2515 ERR_FAIL_COND(!surface);
2516
2517 if (surface->material_owned && surface->material.is_valid())
2518 free(surface->material);
2519
2520 surface->material_owned = p_owned;
2521
2522 surface->material = p_material;
2523 }
2524
mesh_surface_get_material(RID p_mesh,int p_surface) const2525 RID RasterizerGLES2::mesh_surface_get_material(RID p_mesh, int p_surface) const {
2526
2527 Mesh *mesh = mesh_owner.get(p_mesh);
2528 ERR_FAIL_COND_V(!mesh, RID());
2529 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), RID());
2530 Surface *surface = mesh->surfaces[p_surface];
2531 ERR_FAIL_COND_V(!surface, RID());
2532
2533 return surface->material;
2534 }
2535
mesh_surface_get_array_len(RID p_mesh,int p_surface) const2536 int RasterizerGLES2::mesh_surface_get_array_len(RID p_mesh, int p_surface) const {
2537
2538 Mesh *mesh = mesh_owner.get(p_mesh);
2539 ERR_FAIL_COND_V(!mesh, -1);
2540 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1);
2541 Surface *surface = mesh->surfaces[p_surface];
2542 ERR_FAIL_COND_V(!surface, -1);
2543
2544 return surface->array_len;
2545 }
mesh_surface_get_array_index_len(RID p_mesh,int p_surface) const2546 int RasterizerGLES2::mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const {
2547
2548 Mesh *mesh = mesh_owner.get(p_mesh);
2549 ERR_FAIL_COND_V(!mesh, -1);
2550 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1);
2551 Surface *surface = mesh->surfaces[p_surface];
2552 ERR_FAIL_COND_V(!surface, -1);
2553
2554 return surface->index_array_len;
2555 }
mesh_surface_get_format(RID p_mesh,int p_surface) const2556 uint32_t RasterizerGLES2::mesh_surface_get_format(RID p_mesh, int p_surface) const {
2557
2558 Mesh *mesh = mesh_owner.get(p_mesh);
2559 ERR_FAIL_COND_V(!mesh, 0);
2560 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), 0);
2561 Surface *surface = mesh->surfaces[p_surface];
2562 ERR_FAIL_COND_V(!surface, 0);
2563
2564 return surface->format;
2565 }
mesh_surface_get_primitive_type(RID p_mesh,int p_surface) const2566 VS::PrimitiveType RasterizerGLES2::mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const {
2567
2568 Mesh *mesh = mesh_owner.get(p_mesh);
2569 ERR_FAIL_COND_V(!mesh, VS::PRIMITIVE_POINTS);
2570 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), VS::PRIMITIVE_POINTS);
2571 Surface *surface = mesh->surfaces[p_surface];
2572 ERR_FAIL_COND_V(!surface, VS::PRIMITIVE_POINTS);
2573
2574 return surface->primitive;
2575 }
2576
mesh_remove_surface(RID p_mesh,int p_index)2577 void RasterizerGLES2::mesh_remove_surface(RID p_mesh, int p_index) {
2578
2579 Mesh *mesh = mesh_owner.get(p_mesh);
2580 ERR_FAIL_COND(!mesh);
2581 ERR_FAIL_INDEX(p_index, mesh->surfaces.size());
2582 Surface *surface = mesh->surfaces[p_index];
2583 ERR_FAIL_COND(!surface);
2584
2585 if (surface->vertex_id)
2586 glDeleteBuffers(1, &surface->vertex_id);
2587 if (surface->index_id)
2588 glDeleteBuffers(1, &surface->index_id);
2589
2590 if (mesh->morph_target_count) {
2591 for (int i = 0; i < mesh->morph_target_count; i++)
2592 memfree(surface->morph_targets_local[i].array);
2593 memfree(surface->morph_targets_local);
2594 }
2595
2596 memdelete(mesh->surfaces[p_index]);
2597 mesh->surfaces.remove(p_index);
2598 }
mesh_get_surface_count(RID p_mesh) const2599 int RasterizerGLES2::mesh_get_surface_count(RID p_mesh) const {
2600
2601 Mesh *mesh = mesh_owner.get(p_mesh);
2602 ERR_FAIL_COND_V(!mesh, -1);
2603
2604 return mesh->surfaces.size();
2605 }
2606
mesh_get_aabb(RID p_mesh,RID p_skeleton) const2607 AABB RasterizerGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
2608
2609 Mesh *mesh = mesh_owner.get(p_mesh);
2610 ERR_FAIL_COND_V(!mesh, AABB());
2611
2612 if (mesh->custom_aabb != AABB())
2613 return mesh->custom_aabb;
2614
2615 Skeleton *sk = NULL;
2616 if (p_skeleton.is_valid())
2617 sk = skeleton_owner.get(p_skeleton);
2618
2619 AABB aabb;
2620 if (sk && sk->bones.size() != 0) {
2621
2622 for (int i = 0; i < mesh->surfaces.size(); i++) {
2623
2624 AABB laabb;
2625 if (mesh->surfaces[i]->format & VS::ARRAY_FORMAT_BONES && mesh->surfaces[i]->skeleton_bone_aabb.size()) {
2626
2627 int bs = mesh->surfaces[i]->skeleton_bone_aabb.size();
2628 const AABB *skbones = mesh->surfaces[i]->skeleton_bone_aabb.ptr();
2629 const bool *skused = mesh->surfaces[i]->skeleton_bone_used.ptr();
2630
2631 int sbs = sk->bones.size();
2632 ERR_CONTINUE(bs > sbs);
2633 Skeleton::Bone *skb = sk->bones.ptr();
2634
2635 bool first = true;
2636 for (int j = 0; j < bs; j++) {
2637
2638 if (!skused[j])
2639 continue;
2640 AABB baabb = skb[j].transform_aabb(skbones[j]);
2641 if (first) {
2642 laabb = baabb;
2643 first = false;
2644 } else {
2645 laabb.merge_with(baabb);
2646 }
2647 }
2648
2649 } else {
2650
2651 laabb = mesh->surfaces[i]->aabb;
2652 }
2653
2654 if (i == 0)
2655 aabb = laabb;
2656 else
2657 aabb.merge_with(laabb);
2658 }
2659 } else {
2660
2661 for (int i = 0; i < mesh->surfaces.size(); i++) {
2662
2663 if (i == 0)
2664 aabb = mesh->surfaces[i]->aabb;
2665 else
2666 aabb.merge_with(mesh->surfaces[i]->aabb);
2667 }
2668 }
2669
2670 return aabb;
2671 }
2672
mesh_set_custom_aabb(RID p_mesh,const AABB & p_aabb)2673 void RasterizerGLES2::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
2674
2675 Mesh *mesh = mesh_owner.get(p_mesh);
2676 ERR_FAIL_COND(!mesh);
2677
2678 mesh->custom_aabb = p_aabb;
2679 }
2680
mesh_get_custom_aabb(RID p_mesh) const2681 AABB RasterizerGLES2::mesh_get_custom_aabb(RID p_mesh) const {
2682
2683 const Mesh *mesh = mesh_owner.get(p_mesh);
2684 ERR_FAIL_COND_V(!mesh, AABB());
2685
2686 return mesh->custom_aabb;
2687 }
2688 /* MULTIMESH API */
2689
multimesh_create()2690 RID RasterizerGLES2::multimesh_create() {
2691
2692 return multimesh_owner.make_rid(memnew(MultiMesh));
2693 }
2694
multimesh_set_instance_count(RID p_multimesh,int p_count)2695 void RasterizerGLES2::multimesh_set_instance_count(RID p_multimesh, int p_count) {
2696
2697 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2698 ERR_FAIL_COND(!multimesh);
2699
2700 //multimesh->elements.clear(); // make sure to delete everything, so it "fails" in all implementations
2701
2702 if (use_texture_instancing) {
2703
2704 if (next_power_of_2(p_count) != next_power_of_2(multimesh->elements.size())) {
2705 if (multimesh->tex_id) {
2706 glDeleteTextures(1, &multimesh->tex_id);
2707 multimesh->tex_id = 0;
2708 }
2709
2710 if (p_count) {
2711
2712 uint32_t po2 = next_power_of_2(p_count);
2713 if (po2 & 0xAAAAAAAA) {
2714 //half width
2715
2716 multimesh->tw = Math::sqrt(po2 * 2);
2717 multimesh->th = multimesh->tw / 2;
2718 } else {
2719
2720 multimesh->tw = Math::sqrt(po2);
2721 multimesh->th = multimesh->tw;
2722 }
2723 multimesh->tw *= 4;
2724 if (multimesh->th == 0)
2725 multimesh->th = 1;
2726
2727 glGenTextures(1, &multimesh->tex_id);
2728 glActiveTexture(GL_TEXTURE0);
2729 glBindTexture(GL_TEXTURE_2D, multimesh->tex_id);
2730
2731 #ifdef GLEW_ENABLED
2732 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, multimesh->tw, multimesh->th, 0, GL_RGBA, GL_FLOAT, NULL);
2733 #else
2734 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, multimesh->tw, multimesh->th, 0, GL_RGBA, GL_FLOAT, NULL);
2735 #endif
2736 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2737 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2738 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2739 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2740 //multimesh->pixel_size=1.0/ps;
2741
2742 glBindTexture(GL_TEXTURE_2D, 0);
2743 }
2744 }
2745
2746 if (!multimesh->dirty_list.in_list()) {
2747 _multimesh_dirty_list.add(&multimesh->dirty_list);
2748 }
2749 }
2750
2751 multimesh->elements.resize(p_count);
2752 }
multimesh_get_instance_count(RID p_multimesh) const2753 int RasterizerGLES2::multimesh_get_instance_count(RID p_multimesh) const {
2754
2755 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2756 ERR_FAIL_COND_V(!multimesh, -1);
2757
2758 return multimesh->elements.size();
2759 }
2760
multimesh_set_mesh(RID p_multimesh,RID p_mesh)2761 void RasterizerGLES2::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
2762
2763 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2764 ERR_FAIL_COND(!multimesh);
2765
2766 multimesh->mesh = p_mesh;
2767 }
multimesh_set_aabb(RID p_multimesh,const AABB & p_aabb)2768 void RasterizerGLES2::multimesh_set_aabb(RID p_multimesh, const AABB &p_aabb) {
2769
2770 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2771 ERR_FAIL_COND(!multimesh);
2772 multimesh->aabb = p_aabb;
2773 }
multimesh_instance_set_transform(RID p_multimesh,int p_index,const Transform & p_transform)2774 void RasterizerGLES2::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {
2775
2776 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2777 ERR_FAIL_COND(!multimesh);
2778 ERR_FAIL_INDEX(p_index, multimesh->elements.size());
2779 MultiMesh::Element &e = multimesh->elements[p_index];
2780
2781 e.matrix[0] = p_transform.basis.elements[0][0];
2782 e.matrix[1] = p_transform.basis.elements[1][0];
2783 e.matrix[2] = p_transform.basis.elements[2][0];
2784 e.matrix[3] = 0;
2785 e.matrix[4] = p_transform.basis.elements[0][1];
2786 e.matrix[5] = p_transform.basis.elements[1][1];
2787 e.matrix[6] = p_transform.basis.elements[2][1];
2788 e.matrix[7] = 0;
2789 e.matrix[8] = p_transform.basis.elements[0][2];
2790 e.matrix[9] = p_transform.basis.elements[1][2];
2791 e.matrix[10] = p_transform.basis.elements[2][2];
2792 e.matrix[11] = 0;
2793 e.matrix[12] = p_transform.origin.x;
2794 e.matrix[13] = p_transform.origin.y;
2795 e.matrix[14] = p_transform.origin.z;
2796 e.matrix[15] = 1;
2797
2798 if (!multimesh->dirty_list.in_list()) {
2799 _multimesh_dirty_list.add(&multimesh->dirty_list);
2800 }
2801 }
multimesh_instance_set_color(RID p_multimesh,int p_index,const Color & p_color)2802 void RasterizerGLES2::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
2803
2804 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2805 ERR_FAIL_COND(!multimesh)
2806 ERR_FAIL_INDEX(p_index, multimesh->elements.size());
2807 MultiMesh::Element &e = multimesh->elements[p_index];
2808 e.color[0] = CLAMP(p_color.r * 255, 0, 255);
2809 e.color[1] = CLAMP(p_color.g * 255, 0, 255);
2810 e.color[2] = CLAMP(p_color.b * 255, 0, 255);
2811 e.color[3] = CLAMP(p_color.a * 255, 0, 255);
2812
2813 if (!multimesh->dirty_list.in_list()) {
2814 _multimesh_dirty_list.add(&multimesh->dirty_list);
2815 }
2816 }
2817
multimesh_get_mesh(RID p_multimesh) const2818 RID RasterizerGLES2::multimesh_get_mesh(RID p_multimesh) const {
2819
2820 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2821 ERR_FAIL_COND_V(!multimesh, RID());
2822
2823 return multimesh->mesh;
2824 }
multimesh_get_aabb(RID p_multimesh) const2825 AABB RasterizerGLES2::multimesh_get_aabb(RID p_multimesh) const {
2826
2827 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2828 ERR_FAIL_COND_V(!multimesh, AABB());
2829
2830 return multimesh->aabb;
2831 }
2832
multimesh_instance_get_transform(RID p_multimesh,int p_index) const2833 Transform RasterizerGLES2::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
2834
2835 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2836 ERR_FAIL_COND_V(!multimesh, Transform());
2837
2838 ERR_FAIL_INDEX_V(p_index, multimesh->elements.size(), Transform());
2839 MultiMesh::Element &e = multimesh->elements[p_index];
2840
2841 Transform tr;
2842
2843 tr.basis.elements[0][0] = e.matrix[0];
2844 tr.basis.elements[1][0] = e.matrix[1];
2845 tr.basis.elements[2][0] = e.matrix[2];
2846 tr.basis.elements[0][1] = e.matrix[4];
2847 tr.basis.elements[1][1] = e.matrix[5];
2848 tr.basis.elements[2][1] = e.matrix[6];
2849 tr.basis.elements[0][2] = e.matrix[8];
2850 tr.basis.elements[1][2] = e.matrix[9];
2851 tr.basis.elements[2][2] = e.matrix[10];
2852 tr.origin.x = e.matrix[12];
2853 tr.origin.y = e.matrix[13];
2854 tr.origin.z = e.matrix[14];
2855
2856 return tr;
2857 }
multimesh_instance_get_color(RID p_multimesh,int p_index) const2858 Color RasterizerGLES2::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
2859
2860 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2861 ERR_FAIL_COND_V(!multimesh, Color());
2862 ERR_FAIL_INDEX_V(p_index, multimesh->elements.size(), Color());
2863 MultiMesh::Element &e = multimesh->elements[p_index];
2864 Color c;
2865 c.r = e.color[0] / 255.0;
2866 c.g = e.color[1] / 255.0;
2867 c.b = e.color[2] / 255.0;
2868 c.a = e.color[3] / 255.0;
2869
2870 return c;
2871 }
2872
multimesh_set_visible_instances(RID p_multimesh,int p_visible)2873 void RasterizerGLES2::multimesh_set_visible_instances(RID p_multimesh, int p_visible) {
2874
2875 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2876 ERR_FAIL_COND(!multimesh);
2877 multimesh->visible = p_visible;
2878 }
2879
multimesh_get_visible_instances(RID p_multimesh) const2880 int RasterizerGLES2::multimesh_get_visible_instances(RID p_multimesh) const {
2881
2882 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
2883 ERR_FAIL_COND_V(!multimesh, -1);
2884 return multimesh->visible;
2885 }
2886
2887 /* IMMEDIATE API */
2888
immediate_create()2889 RID RasterizerGLES2::immediate_create() {
2890
2891 Immediate *im = memnew(Immediate);
2892 return immediate_owner.make_rid(im);
2893 }
2894
immediate_begin(RID p_immediate,VS::PrimitiveType p_rimitive,RID p_texture)2895 void RasterizerGLES2::immediate_begin(RID p_immediate, VS::PrimitiveType p_rimitive, RID p_texture) {
2896
2897 Immediate *im = immediate_owner.get(p_immediate);
2898 ERR_FAIL_COND(!im);
2899 ERR_FAIL_COND(im->building);
2900
2901 Immediate::Chunk ic;
2902 ic.texture = p_texture;
2903 ic.primitive = p_rimitive;
2904 im->chunks.push_back(ic);
2905 im->mask = 0;
2906 im->building = true;
2907 }
immediate_vertex(RID p_immediate,const Vector3 & p_vertex)2908 void RasterizerGLES2::immediate_vertex(RID p_immediate, const Vector3 &p_vertex) {
2909
2910 Immediate *im = immediate_owner.get(p_immediate);
2911 ERR_FAIL_COND(!im);
2912 ERR_FAIL_COND(!im->building);
2913
2914 Immediate::Chunk *c = &im->chunks.back()->get();
2915
2916 if (c->vertices.empty() && im->chunks.size() == 1) {
2917
2918 im->aabb.pos = p_vertex;
2919 im->aabb.size = Vector3();
2920 } else {
2921 im->aabb.expand_to(p_vertex);
2922 }
2923
2924 if (im->mask & VS::ARRAY_FORMAT_NORMAL)
2925 c->normals.push_back(chunk_normal);
2926 if (im->mask & VS::ARRAY_FORMAT_TANGENT)
2927 c->tangents.push_back(chunk_tangent);
2928 if (im->mask & VS::ARRAY_FORMAT_COLOR)
2929 c->colors.push_back(chunk_color);
2930 if (im->mask & VS::ARRAY_FORMAT_TEX_UV)
2931 c->uvs.push_back(chunk_uv);
2932 if (im->mask & VS::ARRAY_FORMAT_TEX_UV2)
2933 c->uvs2.push_back(chunk_uv2);
2934 im->mask |= VS::ARRAY_FORMAT_VERTEX;
2935 c->vertices.push_back(p_vertex);
2936 }
2937
immediate_normal(RID p_immediate,const Vector3 & p_normal)2938 void RasterizerGLES2::immediate_normal(RID p_immediate, const Vector3 &p_normal) {
2939
2940 Immediate *im = immediate_owner.get(p_immediate);
2941 ERR_FAIL_COND(!im);
2942 ERR_FAIL_COND(!im->building);
2943
2944 im->mask |= VS::ARRAY_FORMAT_NORMAL;
2945 chunk_normal = p_normal;
2946 }
immediate_tangent(RID p_immediate,const Plane & p_tangent)2947 void RasterizerGLES2::immediate_tangent(RID p_immediate, const Plane &p_tangent) {
2948
2949 Immediate *im = immediate_owner.get(p_immediate);
2950 ERR_FAIL_COND(!im);
2951 ERR_FAIL_COND(!im->building);
2952
2953 im->mask |= VS::ARRAY_FORMAT_TANGENT;
2954 chunk_tangent = p_tangent;
2955 }
immediate_color(RID p_immediate,const Color & p_color)2956 void RasterizerGLES2::immediate_color(RID p_immediate, const Color &p_color) {
2957
2958 Immediate *im = immediate_owner.get(p_immediate);
2959 ERR_FAIL_COND(!im);
2960 ERR_FAIL_COND(!im->building);
2961
2962 im->mask |= VS::ARRAY_FORMAT_COLOR;
2963 chunk_color = p_color;
2964 }
immediate_uv(RID p_immediate,const Vector2 & tex_uv)2965 void RasterizerGLES2::immediate_uv(RID p_immediate, const Vector2 &tex_uv) {
2966
2967 Immediate *im = immediate_owner.get(p_immediate);
2968 ERR_FAIL_COND(!im);
2969 ERR_FAIL_COND(!im->building);
2970
2971 im->mask |= VS::ARRAY_FORMAT_TEX_UV;
2972 chunk_uv = tex_uv;
2973 }
immediate_uv2(RID p_immediate,const Vector2 & tex_uv)2974 void RasterizerGLES2::immediate_uv2(RID p_immediate, const Vector2 &tex_uv) {
2975
2976 Immediate *im = immediate_owner.get(p_immediate);
2977 ERR_FAIL_COND(!im);
2978 ERR_FAIL_COND(!im->building);
2979
2980 im->mask |= VS::ARRAY_FORMAT_TEX_UV2;
2981 chunk_uv2 = tex_uv;
2982 }
2983
immediate_end(RID p_immediate)2984 void RasterizerGLES2::immediate_end(RID p_immediate) {
2985
2986 Immediate *im = immediate_owner.get(p_immediate);
2987 ERR_FAIL_COND(!im);
2988 ERR_FAIL_COND(!im->building);
2989
2990 im->building = false;
2991 }
immediate_clear(RID p_immediate)2992 void RasterizerGLES2::immediate_clear(RID p_immediate) {
2993
2994 Immediate *im = immediate_owner.get(p_immediate);
2995 ERR_FAIL_COND(!im);
2996 ERR_FAIL_COND(im->building);
2997
2998 im->chunks.clear();
2999 }
3000
immediate_get_aabb(RID p_immediate) const3001 AABB RasterizerGLES2::immediate_get_aabb(RID p_immediate) const {
3002
3003 Immediate *im = immediate_owner.get(p_immediate);
3004 ERR_FAIL_COND_V(!im, AABB());
3005 return im->aabb;
3006 }
3007
immediate_set_material(RID p_immediate,RID p_material)3008 void RasterizerGLES2::immediate_set_material(RID p_immediate, RID p_material) {
3009
3010 Immediate *im = immediate_owner.get(p_immediate);
3011 ERR_FAIL_COND(!im);
3012 im->material = p_material;
3013 }
3014
immediate_get_material(RID p_immediate) const3015 RID RasterizerGLES2::immediate_get_material(RID p_immediate) const {
3016
3017 const Immediate *im = immediate_owner.get(p_immediate);
3018 ERR_FAIL_COND_V(!im, RID());
3019 return im->material;
3020 }
3021
3022 /* PARTICLES API */
3023
particles_create()3024 RID RasterizerGLES2::particles_create() {
3025
3026 Particles *particles = memnew(Particles);
3027 ERR_FAIL_COND_V(!particles, RID());
3028 return particles_owner.make_rid(particles);
3029 }
3030
particles_set_amount(RID p_particles,int p_amount)3031 void RasterizerGLES2::particles_set_amount(RID p_particles, int p_amount) {
3032
3033 ERR_FAIL_COND(p_amount < 1);
3034 Particles *particles = particles_owner.get(p_particles);
3035 ERR_FAIL_COND(!particles);
3036 particles->data.amount = p_amount;
3037 }
3038
particles_get_amount(RID p_particles) const3039 int RasterizerGLES2::particles_get_amount(RID p_particles) const {
3040
3041 Particles *particles = particles_owner.get(p_particles);
3042 ERR_FAIL_COND_V(!particles, -1);
3043 return particles->data.amount;
3044 }
3045
particles_set_emitting(RID p_particles,bool p_emitting)3046 void RasterizerGLES2::particles_set_emitting(RID p_particles, bool p_emitting) {
3047
3048 Particles *particles = particles_owner.get(p_particles);
3049 ERR_FAIL_COND(!particles);
3050 particles->data.emitting = p_emitting;
3051 }
particles_is_emitting(RID p_particles) const3052 bool RasterizerGLES2::particles_is_emitting(RID p_particles) const {
3053
3054 const Particles *particles = particles_owner.get(p_particles);
3055 ERR_FAIL_COND_V(!particles, false);
3056 return particles->data.emitting;
3057 }
3058
particles_set_visibility_aabb(RID p_particles,const AABB & p_visibility)3059 void RasterizerGLES2::particles_set_visibility_aabb(RID p_particles, const AABB &p_visibility) {
3060
3061 Particles *particles = particles_owner.get(p_particles);
3062 ERR_FAIL_COND(!particles);
3063 particles->data.visibility_aabb = p_visibility;
3064 }
3065
particles_set_emission_half_extents(RID p_particles,const Vector3 & p_half_extents)3066 void RasterizerGLES2::particles_set_emission_half_extents(RID p_particles, const Vector3 &p_half_extents) {
3067
3068 Particles *particles = particles_owner.get(p_particles);
3069 ERR_FAIL_COND(!particles);
3070
3071 particles->data.emission_half_extents = p_half_extents;
3072 }
particles_get_emission_half_extents(RID p_particles) const3073 Vector3 RasterizerGLES2::particles_get_emission_half_extents(RID p_particles) const {
3074
3075 Particles *particles = particles_owner.get(p_particles);
3076 ERR_FAIL_COND_V(!particles, Vector3());
3077
3078 return particles->data.emission_half_extents;
3079 }
3080
particles_set_emission_base_velocity(RID p_particles,const Vector3 & p_base_velocity)3081 void RasterizerGLES2::particles_set_emission_base_velocity(RID p_particles, const Vector3 &p_base_velocity) {
3082
3083 Particles *particles = particles_owner.get(p_particles);
3084 ERR_FAIL_COND(!particles);
3085
3086 particles->data.emission_base_velocity = p_base_velocity;
3087 }
3088
particles_get_emission_base_velocity(RID p_particles) const3089 Vector3 RasterizerGLES2::particles_get_emission_base_velocity(RID p_particles) const {
3090
3091 Particles *particles = particles_owner.get(p_particles);
3092 ERR_FAIL_COND_V(!particles, Vector3());
3093
3094 return particles->data.emission_base_velocity;
3095 }
3096
particles_set_emission_points(RID p_particles,const DVector<Vector3> & p_points)3097 void RasterizerGLES2::particles_set_emission_points(RID p_particles, const DVector<Vector3> &p_points) {
3098
3099 Particles *particles = particles_owner.get(p_particles);
3100 ERR_FAIL_COND(!particles);
3101
3102 particles->data.emission_points = p_points;
3103 }
3104
particles_get_emission_points(RID p_particles) const3105 DVector<Vector3> RasterizerGLES2::particles_get_emission_points(RID p_particles) const {
3106
3107 Particles *particles = particles_owner.get(p_particles);
3108 ERR_FAIL_COND_V(!particles, DVector<Vector3>());
3109
3110 return particles->data.emission_points;
3111 }
3112
particles_set_gravity_normal(RID p_particles,const Vector3 & p_normal)3113 void RasterizerGLES2::particles_set_gravity_normal(RID p_particles, const Vector3 &p_normal) {
3114
3115 Particles *particles = particles_owner.get(p_particles);
3116 ERR_FAIL_COND(!particles);
3117
3118 particles->data.gravity_normal = p_normal;
3119 }
particles_get_gravity_normal(RID p_particles) const3120 Vector3 RasterizerGLES2::particles_get_gravity_normal(RID p_particles) const {
3121
3122 Particles *particles = particles_owner.get(p_particles);
3123 ERR_FAIL_COND_V(!particles, Vector3());
3124
3125 return particles->data.gravity_normal;
3126 }
3127
particles_get_visibility_aabb(RID p_particles) const3128 AABB RasterizerGLES2::particles_get_visibility_aabb(RID p_particles) const {
3129
3130 const Particles *particles = particles_owner.get(p_particles);
3131 ERR_FAIL_COND_V(!particles, AABB());
3132 return particles->data.visibility_aabb;
3133 }
3134
particles_set_variable(RID p_particles,VS::ParticleVariable p_variable,float p_value)3135 void RasterizerGLES2::particles_set_variable(RID p_particles, VS::ParticleVariable p_variable, float p_value) {
3136
3137 ERR_FAIL_INDEX(p_variable, VS::PARTICLE_VAR_MAX);
3138
3139 Particles *particles = particles_owner.get(p_particles);
3140 ERR_FAIL_COND(!particles);
3141 particles->data.particle_vars[p_variable] = p_value;
3142 }
particles_get_variable(RID p_particles,VS::ParticleVariable p_variable) const3143 float RasterizerGLES2::particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const {
3144
3145 const Particles *particles = particles_owner.get(p_particles);
3146 ERR_FAIL_COND_V(!particles, -1);
3147 return particles->data.particle_vars[p_variable];
3148 }
3149
particles_set_randomness(RID p_particles,VS::ParticleVariable p_variable,float p_randomness)3150 void RasterizerGLES2::particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable, float p_randomness) {
3151
3152 Particles *particles = particles_owner.get(p_particles);
3153 ERR_FAIL_COND(!particles);
3154 particles->data.particle_randomness[p_variable] = p_randomness;
3155 }
particles_get_randomness(RID p_particles,VS::ParticleVariable p_variable) const3156 float RasterizerGLES2::particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const {
3157
3158 const Particles *particles = particles_owner.get(p_particles);
3159 ERR_FAIL_COND_V(!particles, -1);
3160 return particles->data.particle_randomness[p_variable];
3161 }
3162
particles_set_color_phases(RID p_particles,int p_phases)3163 void RasterizerGLES2::particles_set_color_phases(RID p_particles, int p_phases) {
3164
3165 Particles *particles = particles_owner.get(p_particles);
3166 ERR_FAIL_COND(!particles);
3167 ERR_FAIL_COND(p_phases < 0 || p_phases > VS::MAX_PARTICLE_COLOR_PHASES);
3168 particles->data.color_phase_count = p_phases;
3169 }
particles_get_color_phases(RID p_particles) const3170 int RasterizerGLES2::particles_get_color_phases(RID p_particles) const {
3171
3172 Particles *particles = particles_owner.get(p_particles);
3173 ERR_FAIL_COND_V(!particles, -1);
3174 return particles->data.color_phase_count;
3175 }
3176
particles_set_color_phase_pos(RID p_particles,int p_phase,float p_pos)3177 void RasterizerGLES2::particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos) {
3178
3179 ERR_FAIL_INDEX(p_phase, VS::MAX_PARTICLE_COLOR_PHASES);
3180 if (p_pos < 0.0)
3181 p_pos = 0.0;
3182 if (p_pos > 1.0)
3183 p_pos = 1.0;
3184
3185 Particles *particles = particles_owner.get(p_particles);
3186 ERR_FAIL_COND(!particles);
3187 particles->data.color_phases[p_phase].pos = p_pos;
3188 }
particles_get_color_phase_pos(RID p_particles,int p_phase) const3189 float RasterizerGLES2::particles_get_color_phase_pos(RID p_particles, int p_phase) const {
3190
3191 ERR_FAIL_INDEX_V(p_phase, VS::MAX_PARTICLE_COLOR_PHASES, -1.0);
3192
3193 const Particles *particles = particles_owner.get(p_particles);
3194 ERR_FAIL_COND_V(!particles, -1);
3195 return particles->data.color_phases[p_phase].pos;
3196 }
3197
particles_set_color_phase_color(RID p_particles,int p_phase,const Color & p_color)3198 void RasterizerGLES2::particles_set_color_phase_color(RID p_particles, int p_phase, const Color &p_color) {
3199
3200 ERR_FAIL_INDEX(p_phase, VS::MAX_PARTICLE_COLOR_PHASES);
3201 Particles *particles = particles_owner.get(p_particles);
3202 ERR_FAIL_COND(!particles);
3203 particles->data.color_phases[p_phase].color = p_color;
3204
3205 //update alpha
3206 particles->has_alpha = false;
3207 for (int i = 0; i < VS::MAX_PARTICLE_COLOR_PHASES; i++) {
3208 if (particles->data.color_phases[i].color.a < 0.99)
3209 particles->has_alpha = true;
3210 }
3211 }
3212
particles_get_color_phase_color(RID p_particles,int p_phase) const3213 Color RasterizerGLES2::particles_get_color_phase_color(RID p_particles, int p_phase) const {
3214
3215 ERR_FAIL_INDEX_V(p_phase, VS::MAX_PARTICLE_COLOR_PHASES, Color());
3216
3217 const Particles *particles = particles_owner.get(p_particles);
3218 ERR_FAIL_COND_V(!particles, Color());
3219 return particles->data.color_phases[p_phase].color;
3220 }
3221
particles_set_attractors(RID p_particles,int p_attractors)3222 void RasterizerGLES2::particles_set_attractors(RID p_particles, int p_attractors) {
3223
3224 Particles *particles = particles_owner.get(p_particles);
3225 ERR_FAIL_COND(!particles);
3226 ERR_FAIL_COND(p_attractors < 0 || p_attractors > VisualServer::MAX_PARTICLE_ATTRACTORS);
3227 particles->data.attractor_count = p_attractors;
3228 }
particles_get_attractors(RID p_particles) const3229 int RasterizerGLES2::particles_get_attractors(RID p_particles) const {
3230
3231 Particles *particles = particles_owner.get(p_particles);
3232 ERR_FAIL_COND_V(!particles, -1);
3233 return particles->data.attractor_count;
3234 }
3235
particles_set_attractor_pos(RID p_particles,int p_attractor,const Vector3 & p_pos)3236 void RasterizerGLES2::particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3 &p_pos) {
3237
3238 Particles *particles = particles_owner.get(p_particles);
3239 ERR_FAIL_COND(!particles);
3240 ERR_FAIL_INDEX(p_attractor, particles->data.attractor_count);
3241 particles->data.attractors[p_attractor].pos = p_pos;
3242 }
particles_get_attractor_pos(RID p_particles,int p_attractor) const3243 Vector3 RasterizerGLES2::particles_get_attractor_pos(RID p_particles, int p_attractor) const {
3244
3245 Particles *particles = particles_owner.get(p_particles);
3246 ERR_FAIL_COND_V(!particles, Vector3());
3247 ERR_FAIL_INDEX_V(p_attractor, particles->data.attractor_count, Vector3());
3248 return particles->data.attractors[p_attractor].pos;
3249 }
3250
particles_set_attractor_strength(RID p_particles,int p_attractor,float p_force)3251 void RasterizerGLES2::particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force) {
3252
3253 Particles *particles = particles_owner.get(p_particles);
3254 ERR_FAIL_COND(!particles);
3255 ERR_FAIL_INDEX(p_attractor, particles->data.attractor_count);
3256 particles->data.attractors[p_attractor].force = p_force;
3257 }
3258
particles_get_attractor_strength(RID p_particles,int p_attractor) const3259 float RasterizerGLES2::particles_get_attractor_strength(RID p_particles, int p_attractor) const {
3260
3261 Particles *particles = particles_owner.get(p_particles);
3262 ERR_FAIL_COND_V(!particles, 0);
3263 ERR_FAIL_INDEX_V(p_attractor, particles->data.attractor_count, 0);
3264 return particles->data.attractors[p_attractor].force;
3265 }
3266
particles_set_material(RID p_particles,RID p_material,bool p_owned)3267 void RasterizerGLES2::particles_set_material(RID p_particles, RID p_material, bool p_owned) {
3268
3269 Particles *particles = particles_owner.get(p_particles);
3270 ERR_FAIL_COND(!particles);
3271 if (particles->material_owned && particles->material.is_valid())
3272 free(particles->material);
3273
3274 particles->material_owned = p_owned;
3275
3276 particles->material = p_material;
3277 }
particles_get_material(RID p_particles) const3278 RID RasterizerGLES2::particles_get_material(RID p_particles) const {
3279
3280 const Particles *particles = particles_owner.get(p_particles);
3281 ERR_FAIL_COND_V(!particles, RID());
3282 return particles->material;
3283 }
3284
particles_set_use_local_coordinates(RID p_particles,bool p_enable)3285 void RasterizerGLES2::particles_set_use_local_coordinates(RID p_particles, bool p_enable) {
3286
3287 Particles *particles = particles_owner.get(p_particles);
3288 ERR_FAIL_COND(!particles);
3289 particles->data.local_coordinates = p_enable;
3290 }
3291
particles_is_using_local_coordinates(RID p_particles) const3292 bool RasterizerGLES2::particles_is_using_local_coordinates(RID p_particles) const {
3293
3294 const Particles *particles = particles_owner.get(p_particles);
3295 ERR_FAIL_COND_V(!particles, false);
3296 return particles->data.local_coordinates;
3297 }
particles_has_height_from_velocity(RID p_particles) const3298 bool RasterizerGLES2::particles_has_height_from_velocity(RID p_particles) const {
3299
3300 const Particles *particles = particles_owner.get(p_particles);
3301 ERR_FAIL_COND_V(!particles, false);
3302 return particles->data.height_from_velocity;
3303 }
3304
particles_set_height_from_velocity(RID p_particles,bool p_enable)3305 void RasterizerGLES2::particles_set_height_from_velocity(RID p_particles, bool p_enable) {
3306
3307 Particles *particles = particles_owner.get(p_particles);
3308 ERR_FAIL_COND(!particles);
3309 particles->data.height_from_velocity = p_enable;
3310 }
3311
particles_get_aabb(RID p_particles) const3312 AABB RasterizerGLES2::particles_get_aabb(RID p_particles) const {
3313
3314 const Particles *particles = particles_owner.get(p_particles);
3315 ERR_FAIL_COND_V(!particles, AABB());
3316 return particles->data.visibility_aabb;
3317 }
3318
3319 /* SKELETON API */
3320
skeleton_create()3321 RID RasterizerGLES2::skeleton_create() {
3322
3323 Skeleton *skeleton = memnew(Skeleton);
3324 ERR_FAIL_COND_V(!skeleton, RID());
3325 return skeleton_owner.make_rid(skeleton);
3326 }
skeleton_resize(RID p_skeleton,int p_bones)3327 void RasterizerGLES2::skeleton_resize(RID p_skeleton, int p_bones) {
3328
3329 Skeleton *skeleton = skeleton_owner.get(p_skeleton);
3330 ERR_FAIL_COND(!skeleton);
3331 if (p_bones == skeleton->bones.size()) {
3332 return;
3333 };
3334 if (use_hw_skeleton_xform) {
3335
3336 if (next_power_of_2(p_bones) != next_power_of_2(skeleton->bones.size())) {
3337 if (skeleton->tex_id) {
3338 glDeleteTextures(1, &skeleton->tex_id);
3339 skeleton->tex_id = 0;
3340 }
3341
3342 if (p_bones) {
3343
3344 glGenTextures(1, &skeleton->tex_id);
3345 glActiveTexture(GL_TEXTURE0);
3346 glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
3347 int ps = next_power_of_2(p_bones * 3);
3348 #ifdef GLEW_ENABLED
3349 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, ps, 1, 0, GL_RGBA, GL_FLOAT, skel_default.ptr());
3350 #else
3351 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ps, 1, 0, GL_RGBA, GL_FLOAT, skel_default.ptr());
3352 #endif
3353 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3354 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3355 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3356 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3357 skeleton->pixel_size = 1.0 / ps;
3358
3359 glBindTexture(GL_TEXTURE_2D, 0);
3360 }
3361 }
3362
3363 if (!skeleton->dirty_list.in_list()) {
3364 _skeleton_dirty_list.add(&skeleton->dirty_list);
3365 }
3366 }
3367 skeleton->bones.resize(p_bones);
3368 }
skeleton_get_bone_count(RID p_skeleton) const3369 int RasterizerGLES2::skeleton_get_bone_count(RID p_skeleton) const {
3370
3371 Skeleton *skeleton = skeleton_owner.get(p_skeleton);
3372 ERR_FAIL_COND_V(!skeleton, -1);
3373 return skeleton->bones.size();
3374 }
skeleton_bone_set_transform(RID p_skeleton,int p_bone,const Transform & p_transform)3375 void RasterizerGLES2::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {
3376
3377 Skeleton *skeleton = skeleton_owner.get(p_skeleton);
3378 ERR_FAIL_COND(!skeleton);
3379 ERR_FAIL_INDEX(p_bone, skeleton->bones.size());
3380
3381 Skeleton::Bone &b = skeleton->bones[p_bone];
3382
3383 b.mtx[0][0] = p_transform.basis[0][0];
3384 b.mtx[0][1] = p_transform.basis[1][0];
3385 b.mtx[0][2] = p_transform.basis[2][0];
3386 b.mtx[1][0] = p_transform.basis[0][1];
3387 b.mtx[1][1] = p_transform.basis[1][1];
3388 b.mtx[1][2] = p_transform.basis[2][1];
3389 b.mtx[2][0] = p_transform.basis[0][2];
3390 b.mtx[2][1] = p_transform.basis[1][2];
3391 b.mtx[2][2] = p_transform.basis[2][2];
3392 b.mtx[3][0] = p_transform.origin[0];
3393 b.mtx[3][1] = p_transform.origin[1];
3394 b.mtx[3][2] = p_transform.origin[2];
3395
3396 if (skeleton->tex_id) {
3397 if (!skeleton->dirty_list.in_list()) {
3398 _skeleton_dirty_list.add(&skeleton->dirty_list);
3399 }
3400 }
3401 }
3402
skeleton_bone_get_transform(RID p_skeleton,int p_bone)3403 Transform RasterizerGLES2::skeleton_bone_get_transform(RID p_skeleton, int p_bone) {
3404
3405 Skeleton *skeleton = skeleton_owner.get(p_skeleton);
3406 ERR_FAIL_COND_V(!skeleton, Transform());
3407 ERR_FAIL_INDEX_V(p_bone, skeleton->bones.size(), Transform());
3408
3409 const Skeleton::Bone &b = skeleton->bones[p_bone];
3410
3411 Transform t;
3412 t.basis[0][0] = b.mtx[0][0];
3413 t.basis[1][0] = b.mtx[0][1];
3414 t.basis[2][0] = b.mtx[0][2];
3415 t.basis[0][1] = b.mtx[1][0];
3416 t.basis[1][1] = b.mtx[1][1];
3417 t.basis[2][1] = b.mtx[1][2];
3418 t.basis[0][2] = b.mtx[2][0];
3419 t.basis[1][2] = b.mtx[2][1];
3420 t.basis[2][2] = b.mtx[2][2];
3421 t.origin[0] = b.mtx[3][0];
3422 t.origin[1] = b.mtx[3][1];
3423 t.origin[2] = b.mtx[3][2];
3424
3425 return t;
3426 }
3427
3428 /* LIGHT API */
3429
light_create(VS::LightType p_type)3430 RID RasterizerGLES2::light_create(VS::LightType p_type) {
3431
3432 Light *light = memnew(Light);
3433 light->type = p_type;
3434 return light_owner.make_rid(light);
3435 }
3436
light_get_type(RID p_light) const3437 VS::LightType RasterizerGLES2::light_get_type(RID p_light) const {
3438
3439 Light *light = light_owner.get(p_light);
3440 ERR_FAIL_COND_V(!light, VS::LIGHT_OMNI);
3441 return light->type;
3442 }
3443
light_set_color(RID p_light,VS::LightColor p_type,const Color & p_color)3444 void RasterizerGLES2::light_set_color(RID p_light, VS::LightColor p_type, const Color &p_color) {
3445
3446 Light *light = light_owner.get(p_light);
3447 ERR_FAIL_COND(!light);
3448 ERR_FAIL_INDEX(p_type, 3);
3449 light->colors[p_type] = p_color;
3450 }
light_get_color(RID p_light,VS::LightColor p_type) const3451 Color RasterizerGLES2::light_get_color(RID p_light, VS::LightColor p_type) const {
3452
3453 Light *light = light_owner.get(p_light);
3454 ERR_FAIL_COND_V(!light, Color());
3455 ERR_FAIL_INDEX_V(p_type, 3, Color());
3456 return light->colors[p_type];
3457 }
3458
light_set_shadow(RID p_light,bool p_enabled)3459 void RasterizerGLES2::light_set_shadow(RID p_light, bool p_enabled) {
3460
3461 Light *light = light_owner.get(p_light);
3462 ERR_FAIL_COND(!light);
3463 light->shadow_enabled = p_enabled;
3464 }
3465
light_has_shadow(RID p_light) const3466 bool RasterizerGLES2::light_has_shadow(RID p_light) const {
3467
3468 Light *light = light_owner.get(p_light);
3469 ERR_FAIL_COND_V(!light, false);
3470 return light->shadow_enabled;
3471 }
3472
light_set_volumetric(RID p_light,bool p_enabled)3473 void RasterizerGLES2::light_set_volumetric(RID p_light, bool p_enabled) {
3474
3475 Light *light = light_owner.get(p_light);
3476 ERR_FAIL_COND(!light);
3477 light->volumetric_enabled = p_enabled;
3478 }
light_is_volumetric(RID p_light) const3479 bool RasterizerGLES2::light_is_volumetric(RID p_light) const {
3480
3481 Light *light = light_owner.get(p_light);
3482 ERR_FAIL_COND_V(!light, false);
3483 return light->volumetric_enabled;
3484 }
3485
light_set_projector(RID p_light,RID p_texture)3486 void RasterizerGLES2::light_set_projector(RID p_light, RID p_texture) {
3487
3488 Light *light = light_owner.get(p_light);
3489 ERR_FAIL_COND(!light);
3490 light->projector = p_texture;
3491 }
light_get_projector(RID p_light) const3492 RID RasterizerGLES2::light_get_projector(RID p_light) const {
3493
3494 Light *light = light_owner.get(p_light);
3495 ERR_FAIL_COND_V(!light, RID());
3496 return light->projector;
3497 }
3498
light_set_var(RID p_light,VS::LightParam p_var,float p_value)3499 void RasterizerGLES2::light_set_var(RID p_light, VS::LightParam p_var, float p_value) {
3500
3501 Light *light = light_owner.get(p_light);
3502 ERR_FAIL_COND(!light);
3503 ERR_FAIL_INDEX(p_var, VS::LIGHT_PARAM_MAX);
3504
3505 light->vars[p_var] = p_value;
3506 }
light_get_var(RID p_light,VS::LightParam p_var) const3507 float RasterizerGLES2::light_get_var(RID p_light, VS::LightParam p_var) const {
3508
3509 Light *light = light_owner.get(p_light);
3510 ERR_FAIL_COND_V(!light, 0);
3511
3512 ERR_FAIL_INDEX_V(p_var, VS::LIGHT_PARAM_MAX, 0);
3513
3514 return light->vars[p_var];
3515 }
3516
light_set_operator(RID p_light,VS::LightOp p_op)3517 void RasterizerGLES2::light_set_operator(RID p_light, VS::LightOp p_op){
3518
3519 };
3520
light_get_operator(RID p_light) const3521 VS::LightOp RasterizerGLES2::light_get_operator(RID p_light) const {
3522
3523 return VS::LightOp();
3524 };
3525
light_omni_set_shadow_mode(RID p_light,VS::LightOmniShadowMode p_mode)3526 void RasterizerGLES2::light_omni_set_shadow_mode(RID p_light, VS::LightOmniShadowMode p_mode) {
3527
3528 Light *light = light_owner.get(p_light);
3529 ERR_FAIL_COND(!light);
3530
3531 light->omni_shadow_mode = p_mode;
3532 }
light_omni_get_shadow_mode(RID p_light) const3533 VS::LightOmniShadowMode RasterizerGLES2::light_omni_get_shadow_mode(RID p_light) const {
3534
3535 const Light *light = light_owner.get(p_light);
3536 ERR_FAIL_COND_V(!light, VS::LIGHT_OMNI_SHADOW_DEFAULT);
3537
3538 return light->omni_shadow_mode;
3539 }
3540
light_directional_set_shadow_mode(RID p_light,VS::LightDirectionalShadowMode p_mode)3541 void RasterizerGLES2::light_directional_set_shadow_mode(RID p_light, VS::LightDirectionalShadowMode p_mode) {
3542
3543 Light *light = light_owner.get(p_light);
3544 ERR_FAIL_COND(!light);
3545
3546 light->directional_shadow_mode = p_mode;
3547 }
3548
light_directional_get_shadow_mode(RID p_light) const3549 VS::LightDirectionalShadowMode RasterizerGLES2::light_directional_get_shadow_mode(RID p_light) const {
3550
3551 const Light *light = light_owner.get(p_light);
3552 ERR_FAIL_COND_V(!light, VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
3553
3554 return light->directional_shadow_mode;
3555 }
3556
light_directional_set_shadow_param(RID p_light,VS::LightDirectionalShadowParam p_param,float p_value)3557 void RasterizerGLES2::light_directional_set_shadow_param(RID p_light, VS::LightDirectionalShadowParam p_param, float p_value) {
3558
3559 Light *light = light_owner.get(p_light);
3560 ERR_FAIL_COND(!light);
3561
3562 light->directional_shadow_param[p_param] = p_value;
3563 }
3564
light_directional_get_shadow_param(RID p_light,VS::LightDirectionalShadowParam p_param) const3565 float RasterizerGLES2::light_directional_get_shadow_param(RID p_light, VS::LightDirectionalShadowParam p_param) const {
3566
3567 const Light *light = light_owner.get(p_light);
3568 ERR_FAIL_COND_V(!light, 0);
3569 return light->directional_shadow_param[p_param];
3570 }
3571
light_get_aabb(RID p_light) const3572 AABB RasterizerGLES2::light_get_aabb(RID p_light) const {
3573
3574 Light *light = light_owner.get(p_light);
3575 ERR_FAIL_COND_V(!light, AABB());
3576
3577 switch (light->type) {
3578
3579 case VS::LIGHT_SPOT: {
3580
3581 float len = light->vars[VS::LIGHT_PARAM_RADIUS];
3582 float size = Math::tan(Math::deg2rad(light->vars[VS::LIGHT_PARAM_SPOT_ANGLE])) * len;
3583 return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
3584 } break;
3585 case VS::LIGHT_OMNI: {
3586
3587 float r = light->vars[VS::LIGHT_PARAM_RADIUS];
3588 return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
3589 } break;
3590 case VS::LIGHT_DIRECTIONAL: {
3591
3592 return AABB();
3593 } break;
3594 default: {}
3595 }
3596
3597 ERR_FAIL_V(AABB());
3598 }
3599
light_instance_create(RID p_light)3600 RID RasterizerGLES2::light_instance_create(RID p_light) {
3601
3602 Light *light = light_owner.get(p_light);
3603 ERR_FAIL_COND_V(!light, RID());
3604
3605 LightInstance *light_instance = memnew(LightInstance);
3606
3607 light_instance->light = p_light;
3608 light_instance->base = light;
3609 light_instance->last_pass = 0;
3610
3611 return light_instance_owner.make_rid(light_instance);
3612 }
light_instance_set_transform(RID p_light_instance,const Transform & p_transform)3613 void RasterizerGLES2::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {
3614
3615 LightInstance *lighti = light_instance_owner.get(p_light_instance);
3616 ERR_FAIL_COND(!lighti);
3617 lighti->transform = p_transform;
3618 }
3619
light_instance_get_shadow_type(RID p_light_instance,bool p_far) const3620 Rasterizer::ShadowType RasterizerGLES2::light_instance_get_shadow_type(RID p_light_instance, bool p_far) const {
3621
3622 LightInstance *lighti = light_instance_owner.get(p_light_instance);
3623 ERR_FAIL_COND_V(!lighti, Rasterizer::SHADOW_NONE);
3624
3625 switch (lighti->base->type) {
3626
3627 case VS::LIGHT_DIRECTIONAL: {
3628 switch (lighti->base->directional_shadow_mode) {
3629 case VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: {
3630 return SHADOW_ORTHOGONAL;
3631 } break;
3632 case VS::LIGHT_DIRECTIONAL_SHADOW_PERSPECTIVE: {
3633 return SHADOW_PSM;
3634 } break;
3635 case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
3636 case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: {
3637 return SHADOW_PSSM;
3638 } break;
3639 }
3640
3641 } break;
3642 case VS::LIGHT_OMNI: return SHADOW_DUAL_PARABOLOID; break;
3643 case VS::LIGHT_SPOT: return SHADOW_SIMPLE; break;
3644 }
3645
3646 return Rasterizer::SHADOW_NONE;
3647 }
3648
light_instance_get_shadow_passes(RID p_light_instance) const3649 int RasterizerGLES2::light_instance_get_shadow_passes(RID p_light_instance) const {
3650
3651 LightInstance *lighti = light_instance_owner.get(p_light_instance);
3652 ERR_FAIL_COND_V(!lighti, 0);
3653
3654 if (lighti->base->type == VS::LIGHT_DIRECTIONAL && lighti->base->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
3655
3656 return 4; // dp4
3657 } else if (lighti->base->type == VS::LIGHT_OMNI || (lighti->base->type == VS::LIGHT_DIRECTIONAL && lighti->base->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS)) {
3658 return 2; // dp
3659 } else
3660 return 1;
3661 }
3662
light_instance_get_pssm_shadow_overlap(RID p_light_instance) const3663 bool RasterizerGLES2::light_instance_get_pssm_shadow_overlap(RID p_light_instance) const {
3664
3665 return shadow_filter >= SHADOW_FILTER_ESM;
3666 }
3667
light_instance_set_shadow_transform(RID p_light_instance,int p_index,const CameraMatrix & p_camera,const Transform & p_transform,float p_split_near,float p_split_far)3668 void RasterizerGLES2::light_instance_set_shadow_transform(RID p_light_instance, int p_index, const CameraMatrix &p_camera, const Transform &p_transform, float p_split_near, float p_split_far) {
3669
3670 LightInstance *lighti = light_instance_owner.get(p_light_instance);
3671 ERR_FAIL_COND(!lighti);
3672
3673 ERR_FAIL_COND(lighti->base->type != VS::LIGHT_DIRECTIONAL);
3674 // ERR_FAIL_INDEX(p_index,1);
3675
3676 lighti->custom_projection[p_index] = p_camera;
3677 lighti->custom_transform[p_index] = p_transform;
3678 lighti->shadow_split[p_index] = 1.0 / p_split_far;
3679 #if 0
3680 if (p_index==0) {
3681 lighti->custom_projection=p_camera;
3682 lighti->custom_transform=p_transform;
3683 //Plane p(0,0,-p_split_far,1);
3684 //p=camera_projection.xform4(p);
3685 //lighti->shadow_split=p.normal.z/p.d;
3686 lighti->shadow_split=1.0/p_split_far;
3687
3688 //lighti->shadow_split=-p_split_far;
3689 } else {
3690
3691 lighti->custom_projection2=p_camera;
3692 lighti->custom_transform2=p_transform;
3693 lighti->shadow_split2=p_split_far;
3694
3695 }
3696 #endif
3697 }
3698
light_instance_get_shadow_size(RID p_light_instance,int p_index) const3699 int RasterizerGLES2::light_instance_get_shadow_size(RID p_light_instance, int p_index) const {
3700
3701 LightInstance *lighti = light_instance_owner.get(p_light_instance);
3702 ERR_FAIL_COND_V(!lighti, 1);
3703 ERR_FAIL_COND_V(!lighti->near_shadow_buffer, 256);
3704 return lighti->near_shadow_buffer->size / 2;
3705 }
3706
shadow_clear_near()3707 void RasterizerGLES2::shadow_clear_near() {
3708
3709 for (int i = 0; i < near_shadow_buffers.size(); i++) {
3710
3711 if (near_shadow_buffers[i].owner)
3712 near_shadow_buffers[i].owner->clear_near_shadow_buffers();
3713 }
3714 }
3715
shadow_allocate_near(RID p_light)3716 bool RasterizerGLES2::shadow_allocate_near(RID p_light) {
3717
3718 if (!use_shadow_mapping || !use_framebuffers)
3719 return false;
3720
3721 LightInstance *li = light_instance_owner.get(p_light);
3722 ERR_FAIL_COND_V(!li, false);
3723 ERR_FAIL_COND_V(li->near_shadow_buffer, false);
3724
3725 int skip = 0;
3726 if (framebuffer.active) {
3727
3728 int sc = framebuffer.scale;
3729 while (sc > 1) {
3730 sc /= 2;
3731 skip++;
3732 }
3733 }
3734
3735 for (int i = 0; i < near_shadow_buffers.size(); i++) {
3736
3737 if (skip > 0) {
3738 skip--;
3739 continue;
3740 }
3741
3742 if (near_shadow_buffers[i].owner != NULL)
3743 continue;
3744
3745 near_shadow_buffers[i].owner = li;
3746 li->near_shadow_buffer = &near_shadow_buffers[i];
3747 return true;
3748 }
3749
3750 return false;
3751 }
3752
shadow_allocate_far(RID p_light)3753 bool RasterizerGLES2::shadow_allocate_far(RID p_light) {
3754
3755 return false;
3756 }
3757
3758 /* PARTICLES INSTANCE */
3759
particles_instance_create(RID p_particles)3760 RID RasterizerGLES2::particles_instance_create(RID p_particles) {
3761
3762 ERR_FAIL_COND_V(!particles_owner.owns(p_particles), RID());
3763 ParticlesInstance *particles_instance = memnew(ParticlesInstance);
3764 ERR_FAIL_COND_V(!particles_instance, RID());
3765 particles_instance->particles = p_particles;
3766 return particles_instance_owner.make_rid(particles_instance);
3767 }
3768
particles_instance_set_transform(RID p_particles_instance,const Transform & p_transform)3769 void RasterizerGLES2::particles_instance_set_transform(RID p_particles_instance, const Transform &p_transform) {
3770
3771 ParticlesInstance *particles_instance = particles_instance_owner.get(p_particles_instance);
3772 ERR_FAIL_COND(!particles_instance);
3773 particles_instance->transform = p_transform;
3774 }
3775
viewport_data_create()3776 RID RasterizerGLES2::viewport_data_create() {
3777
3778 ViewportData *vd = memnew(ViewportData);
3779
3780 glActiveTexture(GL_TEXTURE0);
3781 glGenFramebuffers(1, &vd->lum_fbo);
3782 glBindFramebuffer(GL_FRAMEBUFFER, vd->lum_fbo);
3783
3784 GLuint format_luminance = use_fp16_fb ? _GL_RG_EXT : GL_RGBA;
3785 GLuint format_luminance_type = use_fp16_fb ? (full_float_fb_supported ? GL_FLOAT : _GL_HALF_FLOAT_OES) : GL_UNSIGNED_BYTE;
3786 GLuint format_luminance_components = use_fp16_fb ? _GL_RG_EXT : GL_RGBA;
3787
3788 glGenTextures(1, &vd->lum_color);
3789 glBindTexture(GL_TEXTURE_2D, vd->lum_color);
3790 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3791 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3792 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3793 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3794 //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0,
3795 // GL_RGBA, GL_UNSIGNED_BYTE, NULL);
3796 glTexImage2D(GL_TEXTURE_2D, 0, format_luminance, 1, 1, 0,
3797 format_luminance_components, format_luminance_type, NULL);
3798
3799 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
3800 GL_TEXTURE_2D, vd->lum_color, 0);
3801
3802 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
3803
3804 glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
3805 DEBUG_TEST_ERROR("Viewport Data Init");
3806 if (status != GL_FRAMEBUFFER_COMPLETE) {
3807 WARN_PRINT("Can't create framebuffer for vd");
3808 }
3809
3810 return viewport_data_owner.make_rid(vd);
3811 }
3812
render_target_create()3813 RID RasterizerGLES2::render_target_create() {
3814
3815 RenderTarget *rt = memnew(RenderTarget);
3816 rt->fbo = 0;
3817 rt->width = 0;
3818 rt->height = 0;
3819 rt->last_pass = 0;
3820
3821 Texture *texture = memnew(Texture);
3822 texture->active = false;
3823 texture->total_data_size = 0;
3824 texture->render_target = rt;
3825 texture->ignore_mipmaps = true;
3826 rt->texture_ptr = texture;
3827 rt->texture = texture_owner.make_rid(texture);
3828 rt->texture_ptr->active = false;
3829 return render_target_owner.make_rid(rt);
3830 }
render_target_set_size(RID p_render_target,int p_width,int p_height)3831 void RasterizerGLES2::render_target_set_size(RID p_render_target, int p_width, int p_height) {
3832
3833 RenderTarget *rt = render_target_owner.get(p_render_target);
3834
3835 if (p_width == rt->width && p_height == rt->height)
3836 return;
3837
3838 if (rt->width != 0 && rt->height != 0) {
3839
3840 glDeleteFramebuffers(1, &rt->fbo);
3841 glDeleteRenderbuffers(1, &rt->depth);
3842 glDeleteTextures(1, &rt->color);
3843
3844 rt->fbo = 0;
3845 rt->depth = 0;
3846 rt->color = 0;
3847 rt->width = 0;
3848 rt->height = 0;
3849 rt->texture_ptr->tex_id = 0;
3850 rt->texture_ptr->active = false;
3851 }
3852
3853 if (p_width == 0 || p_height == 0)
3854 return;
3855
3856 rt->width = p_width;
3857 rt->height = p_height;
3858
3859 //fbo
3860 glGenFramebuffers(1, &rt->fbo);
3861 glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
3862
3863 //depth
3864 if (!low_memory_2d) {
3865 glGenRenderbuffers(1, &rt->depth);
3866 glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
3867
3868 glRenderbufferStorage(GL_RENDERBUFFER, use_depth24 ? _DEPTH_COMPONENT24_OES : GL_DEPTH_COMPONENT16, rt->width, rt->height);
3869
3870 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
3871 }
3872
3873 //color
3874 glGenTextures(1, &rt->color);
3875 glBindTexture(GL_TEXTURE_2D, rt->color);
3876 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
3877
3878 if (rt->texture_ptr->flags & VS::TEXTURE_FLAG_FILTER) {
3879
3880 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3881 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3882 } else {
3883
3884 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3885 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3886 }
3887 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
3888 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
3889 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
3890
3891 rt->texture_ptr->tex_id = rt->color;
3892 rt->texture_ptr->active = true;
3893 rt->texture_ptr->width = p_width;
3894 rt->texture_ptr->height = p_height;
3895
3896 #
3897 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
3898
3899 if (status != GL_FRAMEBUFFER_COMPLETE) {
3900
3901 glDeleteRenderbuffers(1, &rt->fbo);
3902 glDeleteTextures(1, &rt->depth);
3903 glDeleteTextures(1, &rt->color);
3904 rt->fbo = 0;
3905 rt->width = 0;
3906 rt->height = 0;
3907 rt->color = 0;
3908 rt->depth = 0;
3909 rt->texture_ptr->tex_id = 0;
3910 rt->texture_ptr->active = false;
3911 WARN_PRINT("Could not create framebuffer!!");
3912 }
3913
3914 glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
3915 }
3916
render_target_get_texture(RID p_render_target) const3917 RID RasterizerGLES2::render_target_get_texture(RID p_render_target) const {
3918
3919 const RenderTarget *rt = render_target_owner.get(p_render_target);
3920 ERR_FAIL_COND_V(!rt, RID());
3921 return rt->texture;
3922 }
render_target_renedered_in_frame(RID p_render_target)3923 bool RasterizerGLES2::render_target_renedered_in_frame(RID p_render_target) {
3924
3925 RenderTarget *rt = render_target_owner.get(p_render_target);
3926 ERR_FAIL_COND_V(!rt, false);
3927 return rt->last_pass == frame;
3928 }
3929
3930 /* RENDER API */
3931 /* all calls (inside begin/end shadow) are always warranted to be in the following order: */
3932
begin_frame()3933 void RasterizerGLES2::begin_frame() {
3934
3935 _update_framebuffer();
3936
3937 glDepthFunc(GL_LEQUAL);
3938 glFrontFace(GL_CW);
3939
3940 //fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting");
3941 #ifdef TOOLS_ENABLED
3942 canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("display/use_2d_pixel_snap", false));
3943 shadow_filter = ShadowFilterTechnique(int(Globals::get_singleton()->get("rasterizer/shadow_filter")));
3944 #endif
3945
3946 canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_PCF5, shadow_filter == SHADOW_FILTER_PCF5);
3947 canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_PCF13, shadow_filter == SHADOW_FILTER_PCF13);
3948 canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_ESM, shadow_filter == SHADOW_FILTER_ESM);
3949
3950 window_size = Size2(OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height);
3951
3952 double time = (OS::get_singleton()->get_ticks_usec() / 1000); // get msec
3953 time /= 1000.0; // make secs
3954 if (frame != 0) {
3955 time_delta = time_scale * (time - last_time);
3956 } else {
3957 time_delta = 0.0f;
3958 }
3959 scaled_time += time_delta;
3960 last_time = time;
3961 frame++;
3962
3963 _rinfo.vertex_count = 0;
3964 _rinfo.object_count = 0;
3965 _rinfo.mat_change_count = 0;
3966 _rinfo.shader_change_count = 0;
3967 _rinfo.ci_draw_commands = 0;
3968 _rinfo.surface_count = 0;
3969 _rinfo.draw_calls = 0;
3970
3971 _update_fixed_materials();
3972 while (_shader_dirty_list.first()) {
3973
3974 _update_shader(_shader_dirty_list.first()->self());
3975 }
3976
3977 while (_skeleton_dirty_list.first()) {
3978
3979 Skeleton *s = _skeleton_dirty_list.first()->self();
3980
3981 float *sk_float = (float *)skinned_buffer;
3982 for (int i = 0; i < s->bones.size(); i++) {
3983
3984 float *m = &sk_float[i * 12];
3985 const Skeleton::Bone &b = s->bones[i];
3986 m[0] = b.mtx[0][0];
3987 m[1] = b.mtx[1][0];
3988 m[2] = b.mtx[2][0];
3989 m[3] = b.mtx[3][0];
3990
3991 m[4] = b.mtx[0][1];
3992 m[5] = b.mtx[1][1];
3993 m[6] = b.mtx[2][1];
3994 m[7] = b.mtx[3][1];
3995
3996 m[8] = b.mtx[0][2];
3997 m[9] = b.mtx[1][2];
3998 m[10] = b.mtx[2][2];
3999 m[11] = b.mtx[3][2];
4000 }
4001
4002 glActiveTexture(GL_TEXTURE0);
4003 glBindTexture(GL_TEXTURE_2D, s->tex_id);
4004 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, next_power_of_2(s->bones.size() * 3), 1, GL_RGBA, GL_FLOAT, sk_float);
4005 _skeleton_dirty_list.remove(_skeleton_dirty_list.first());
4006 }
4007
4008 while (_multimesh_dirty_list.first()) {
4009
4010 MultiMesh *s = _multimesh_dirty_list.first()->self();
4011
4012 float *sk_float = (float *)skinned_buffer;
4013 for (int i = 0; i < s->elements.size(); i++) {
4014
4015 float *m = &sk_float[i * 16];
4016 const float *im = s->elements[i].matrix;
4017 for (int j = 0; j < 16; j++) {
4018 m[j] = im[j];
4019 }
4020 }
4021
4022 glActiveTexture(GL_TEXTURE0);
4023 glBindTexture(GL_TEXTURE_2D, s->tex_id);
4024 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, s->tw, s->th, GL_RGBA, GL_FLOAT, sk_float);
4025 _multimesh_dirty_list.remove(_multimesh_dirty_list.first());
4026 }
4027
4028 draw_next_frame = false;
4029 // material_shader.set_uniform_default(MaterialShaderGLES2::SCREENZ_SCALE, Math::fmod(time, 3600.0));
4030 /* nehe ?*/
4031
4032 // glClearColor(0,0,1,1);
4033 // glClear(GL_COLOR_BUFFER_BIT); //should not clear if anything else cleared..
4034 }
4035
capture_viewport(Image * r_capture)4036 void RasterizerGLES2::capture_viewport(Image *r_capture) {
4037 #if 0
4038 DVector<uint8_t> pixels;
4039 pixels.resize(viewport.width*viewport.height*3);
4040 DVector<uint8_t>::Write w = pixels.write();
4041 #ifdef GLEW_ENABLED
4042 glReadBuffer(GL_COLOR_ATTACHMENT0);
4043 #endif
4044 glPixelStorei(GL_PACK_ALIGNMENT, 1);
4045 if (current_rt)
4046 glReadPixels( 0, 0, viewport.width, viewport.height,GL_RGB,GL_UNSIGNED_BYTE,w.ptr() );
4047 else
4048 glReadPixels( viewport.x, window_size.height-(viewport.height+viewport.y), viewport.width,viewport.height,GL_RGB,GL_UNSIGNED_BYTE,w.ptr());
4049
4050 glPixelStorei(GL_PACK_ALIGNMENT, 4);
4051
4052 w=DVector<uint8_t>::Write();
4053
4054 r_capture->create(viewport.width,viewport.height,0,Image::FORMAT_RGB,pixels);
4055 #else
4056
4057 DVector<uint8_t> pixels;
4058 pixels.resize(viewport.width * viewport.height * 4);
4059 DVector<uint8_t>::Write w = pixels.write();
4060 glPixelStorei(GL_PACK_ALIGNMENT, 4);
4061
4062 // uint64_t time = OS::get_singleton()->get_ticks_usec();
4063
4064 if (current_rt) {
4065 #ifdef GLEW_ENABLED
4066 glReadBuffer(GL_COLOR_ATTACHMENT0);
4067 #endif
4068 glReadPixels(0, 0, viewport.width, viewport.height, GL_RGBA, GL_UNSIGNED_BYTE, w.ptr());
4069 } else {
4070 // back?
4071 glReadPixels(viewport.x, window_size.height - (viewport.height + viewport.y), viewport.width, viewport.height, GL_RGBA, GL_UNSIGNED_BYTE, w.ptr());
4072 }
4073
4074 bool flip = current_rt == NULL;
4075
4076 if (flip) {
4077 uint32_t *imgptr = (uint32_t *)w.ptr();
4078 for (int y = 0; y < (viewport.height / 2); y++) {
4079
4080 uint32_t *ptr1 = &imgptr[y * viewport.width];
4081 uint32_t *ptr2 = &imgptr[(viewport.height - y - 1) * viewport.width];
4082
4083 for (int x = 0; x < viewport.width; x++) {
4084
4085 uint32_t tmp = ptr1[x];
4086 ptr1[x] = ptr2[x];
4087 ptr2[x] = tmp;
4088 }
4089 }
4090 }
4091
4092 w = DVector<uint8_t>::Write();
4093 r_capture->create(viewport.width, viewport.height, 0, Image::FORMAT_RGBA, pixels);
4094 //r_capture->flip_y();
4095
4096 #endif
4097 }
4098
clear_viewport(const Color & p_color)4099 void RasterizerGLES2::clear_viewport(const Color &p_color) {
4100
4101 if (current_rt || using_canvas_bg) {
4102
4103 glScissor(0, 0, viewport.width, viewport.height);
4104 } else {
4105 glScissor(viewport.x, window_size.height - (viewport.height + viewport.y), viewport.width, viewport.height);
4106 }
4107
4108 glEnable(GL_SCISSOR_TEST);
4109 glClearColor(p_color.r, p_color.g, p_color.b, p_color.a);
4110 glClear(GL_COLOR_BUFFER_BIT); //should not clear if anything else cleared..
4111 glDisable(GL_SCISSOR_TEST);
4112 };
4113
set_render_target(RID p_render_target,bool p_transparent_bg,bool p_vflip)4114 void RasterizerGLES2::set_render_target(RID p_render_target, bool p_transparent_bg, bool p_vflip) {
4115
4116 if (!p_render_target.is_valid()) {
4117 glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
4118 current_rt = NULL;
4119 current_rt_vflip = false;
4120
4121 } else {
4122 RenderTarget *rt = render_target_owner.get(p_render_target);
4123 ERR_FAIL_COND(!rt);
4124 ERR_FAIL_COND(rt->fbo == 0);
4125 glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
4126 current_rt = rt;
4127 current_rt_transparent = p_transparent_bg;
4128 current_rt_vflip = !p_vflip;
4129 }
4130 }
4131
set_viewport(const VS::ViewportRect & p_viewport)4132 void RasterizerGLES2::set_viewport(const VS::ViewportRect &p_viewport) {
4133
4134 viewport = p_viewport;
4135 //viewport.width/=2;
4136 //viewport.height/=2;
4137 //print_line("viewport: "+itos(p_viewport.x)+","+itos(p_viewport.y)+","+itos(p_viewport.width)+","+itos(p_viewport.height));
4138
4139 if (current_rt) {
4140
4141 glViewport(0, 0, viewport.width, viewport.height);
4142 } else {
4143 glViewport(viewport.x, window_size.height - (viewport.height + viewport.y), viewport.width, viewport.height);
4144 }
4145 }
4146
begin_scene(RID p_viewport_data,RID p_env,VS::ScenarioDebugMode p_debug)4147 void RasterizerGLES2::begin_scene(RID p_viewport_data, RID p_env, VS::ScenarioDebugMode p_debug) {
4148
4149 current_debug = p_debug;
4150 opaque_render_list.clear();
4151 alpha_render_list.clear();
4152 light_instance_count = 0;
4153 current_env = p_env.is_valid() ? environment_owner.get(p_env) : NULL;
4154 scene_pass++;
4155 last_light_id = 0;
4156 directional_light_count = 0;
4157 lights_use_shadow = false;
4158 texscreen_used = false;
4159 current_vd = viewport_data_owner.get(p_viewport_data);
4160 if (current_debug == VS::SCENARIO_DEBUG_WIREFRAME) {
4161 #ifdef GLEW_ENABLED
4162 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
4163 #endif
4164 }
4165
4166 //set state
4167
4168 glCullFace(GL_FRONT);
4169 cull_front = true;
4170 };
4171
begin_shadow_map(RID p_light_instance,int p_shadow_pass)4172 void RasterizerGLES2::begin_shadow_map(RID p_light_instance, int p_shadow_pass) {
4173
4174 ERR_FAIL_COND(shadow);
4175 shadow = light_instance_owner.get(p_light_instance);
4176 shadow_pass = p_shadow_pass;
4177 ERR_FAIL_COND(!shadow);
4178
4179 opaque_render_list.clear();
4180 alpha_render_list.clear();
4181 // pre_zpass_render_list.clear();
4182 light_instance_count = 0;
4183
4184 glCullFace(GL_FRONT);
4185 cull_front = true;
4186 }
4187
set_camera(const Transform & p_world,const CameraMatrix & p_projection,bool p_ortho_hint)4188 void RasterizerGLES2::set_camera(const Transform &p_world, const CameraMatrix &p_projection, bool p_ortho_hint) {
4189
4190 camera_transform = p_world;
4191 if (current_rt && current_rt_vflip) {
4192 camera_transform.basis.set_axis(1, -camera_transform.basis.get_axis(1));
4193 }
4194 camera_transform_inverse = camera_transform.inverse();
4195 camera_projection = p_projection;
4196 camera_plane = Plane(camera_transform.origin, -camera_transform.basis.get_axis(2));
4197 camera_z_near = camera_projection.get_z_near();
4198 camera_z_far = camera_projection.get_z_far();
4199 camera_projection.get_viewport_size(camera_vp_size.x, camera_vp_size.y);
4200 camera_ortho = p_ortho_hint;
4201 }
4202
add_light(RID p_light_instance)4203 void RasterizerGLES2::add_light(RID p_light_instance) {
4204
4205 #define LIGHT_FADE_TRESHOLD 0.05
4206
4207 ERR_FAIL_COND(light_instance_count >= MAX_SCENE_LIGHTS);
4208
4209 LightInstance *li = light_instance_owner.get(p_light_instance);
4210 ERR_FAIL_COND(!li);
4211
4212 switch (li->base->type) {
4213
4214 case VS::LIGHT_DIRECTIONAL: {
4215
4216 ERR_FAIL_COND(directional_light_count >= RenderList::MAX_LIGHTS);
4217 directional_lights[directional_light_count++] = li;
4218
4219 if (li->base->shadow_enabled) {
4220 CameraMatrix bias;
4221 bias.set_light_bias();
4222
4223 int passes = light_instance_get_shadow_passes(p_light_instance);
4224
4225 for (int i = 0; i < passes; i++) {
4226 Transform modelview = Transform(camera_transform_inverse * li->custom_transform[i]).inverse();
4227 li->shadow_projection[i] = bias * li->custom_projection[i] * modelview;
4228 }
4229
4230 lights_use_shadow = true;
4231 }
4232 } break;
4233 case VS::LIGHT_OMNI: {
4234
4235 if (li->base->shadow_enabled) {
4236 li->shadow_projection[0] = Transform(camera_transform_inverse * li->transform).inverse();
4237 lights_use_shadow = true;
4238 }
4239 } break;
4240 case VS::LIGHT_SPOT: {
4241
4242 if (li->base->shadow_enabled) {
4243 CameraMatrix bias;
4244 bias.set_light_bias();
4245 Transform modelview = Transform(camera_transform_inverse * li->transform).inverse();
4246 li->shadow_projection[0] = bias * li->projection * modelview;
4247 lights_use_shadow = true;
4248 }
4249 } break;
4250 }
4251
4252 /* make light hash */
4253
4254 // actually, not really a hash, but helps to sort the lights
4255 // and avoid recompiling redudant shader versions
4256
4257 li->last_pass = scene_pass;
4258 li->sort_key = light_instance_count;
4259
4260 light_instances[light_instance_count++] = li;
4261 }
4262
_update_shader(Shader * p_shader) const4263 void RasterizerGLES2::_update_shader(Shader *p_shader) const {
4264
4265 _shader_dirty_list.remove(&p_shader->dirty_list);
4266
4267 p_shader->valid = false;
4268
4269 p_shader->uniforms.clear();
4270 Vector<StringName> uniform_names;
4271
4272 String vertex_code;
4273 String vertex_globals;
4274 ShaderCompilerGLES2::Flags vertex_flags;
4275 ShaderCompilerGLES2::Flags fragment_flags;
4276 ShaderCompilerGLES2::Flags light_flags;
4277
4278 if (p_shader->mode == VS::SHADER_MATERIAL) {
4279 Error err = shader_precompiler.compile(p_shader->vertex_code, ShaderLanguage::SHADER_MATERIAL_VERTEX, vertex_code, vertex_globals, vertex_flags, &p_shader->uniforms);
4280 if (err) {
4281 return; //invalid
4282 }
4283 } else if (p_shader->mode == VS::SHADER_CANVAS_ITEM) {
4284
4285 Error err = shader_precompiler.compile(p_shader->vertex_code, ShaderLanguage::SHADER_CANVAS_ITEM_VERTEX, vertex_code, vertex_globals, vertex_flags, &p_shader->uniforms);
4286 if (err) {
4287 return; //invalid
4288 }
4289 }
4290
4291 //print_line("compiled vertex: "+vertex_code);
4292 //print_line("compiled vertex globals: "+vertex_globals);
4293
4294 //print_line("UCV: "+itos(p_shader->uniforms.size()));
4295 String fragment_code;
4296 String fragment_globals;
4297
4298 if (p_shader->mode == VS::SHADER_MATERIAL) {
4299 Error err = shader_precompiler.compile(p_shader->fragment_code, ShaderLanguage::SHADER_MATERIAL_FRAGMENT, fragment_code, fragment_globals, fragment_flags, &p_shader->uniforms);
4300 if (err) {
4301 return; //invalid
4302 }
4303 } else if (p_shader->mode == VS::SHADER_CANVAS_ITEM) {
4304 Error err = shader_precompiler.compile(p_shader->fragment_code, ShaderLanguage::SHADER_CANVAS_ITEM_FRAGMENT, fragment_code, fragment_globals, fragment_flags, &p_shader->uniforms);
4305 if (err) {
4306 return; //invalid
4307 }
4308 }
4309
4310 String light_code;
4311 String light_globals;
4312
4313 if (p_shader->mode == VS::SHADER_MATERIAL) {
4314
4315 Error err = shader_precompiler.compile(p_shader->light_code, (ShaderLanguage::SHADER_MATERIAL_LIGHT), light_code, light_globals, light_flags, &p_shader->uniforms);
4316 if (err) {
4317 return; //invalid
4318 }
4319 } else if (p_shader->mode == VS::SHADER_CANVAS_ITEM) {
4320 Error err = shader_precompiler.compile(p_shader->light_code, (ShaderLanguage::SHADER_CANVAS_ITEM_LIGHT), light_code, light_globals, light_flags, &p_shader->uniforms);
4321 if (err) {
4322 return; //invalid
4323 }
4324 }
4325
4326 //light and fragment are both fragment so put their globals together
4327
4328 Vector<String> light_globals_lines = light_globals.split("\n");
4329 String *line = light_globals_lines.ptr();
4330 for (int i = 0; i < light_globals_lines.size(); i++, line++) {
4331 //avoid redefinition of uniforms if the same is used both at fragment and light
4332 if (line->begins_with("uniform ") && line->is_subsequence_of(fragment_globals)) {
4333 continue;
4334 }
4335 fragment_globals += *line;
4336 }
4337
4338 //print_line("compiled fragment: "+fragment_code);
4339 // ("compiled fragment globals: "+fragment_globals);
4340
4341 //print_line("UCF: "+itos(p_shader->uniforms.size()));
4342
4343 int first_tex_index = 0xFFFFF;
4344 p_shader->first_texture = StringName();
4345
4346 for (Map<StringName, ShaderLanguage::Uniform>::Element *E = p_shader->uniforms.front(); E; E = E->next()) {
4347
4348 uniform_names.push_back("_" + String(E->key()));
4349 if (E->get().type == ShaderLanguage::TYPE_TEXTURE && E->get().order < first_tex_index) {
4350 p_shader->first_texture = E->key();
4351 first_tex_index = E->get().order;
4352 }
4353 }
4354
4355 bool uses_time = false;
4356
4357 if (p_shader->mode == VS::SHADER_MATERIAL) {
4358 //print_line("setting code to id.. "+itos(p_shader->custom_code_id));
4359 Vector<const char *> enablers;
4360 if (fragment_flags.use_color_interp || vertex_flags.use_color_interp)
4361 enablers.push_back("#define ENABLE_COLOR_INTERP\n");
4362 if (fragment_flags.use_uv_interp || vertex_flags.use_uv_interp)
4363 enablers.push_back("#define ENABLE_UV_INTERP\n");
4364 if (fragment_flags.use_uv2_interp || vertex_flags.use_uv2_interp)
4365 enablers.push_back("#define ENABLE_UV2_INTERP\n");
4366 if (fragment_flags.use_tangent_interp || vertex_flags.use_tangent_interp || fragment_flags.uses_normalmap)
4367 enablers.push_back("#define ENABLE_TANGENT_INTERP\n");
4368 if (fragment_flags.use_var1_interp || vertex_flags.use_var1_interp)
4369 enablers.push_back("#define ENABLE_VAR1_INTERP\n");
4370 if (fragment_flags.use_var2_interp || vertex_flags.use_var2_interp)
4371 enablers.push_back("#define ENABLE_VAR2_INTERP\n");
4372 if (fragment_flags.uses_texscreen) {
4373 enablers.push_back("#define ENABLE_TEXSCREEN\n");
4374 }
4375 if (fragment_flags.uses_screen_uv) {
4376 enablers.push_back("#define ENABLE_SCREEN_UV\n");
4377 }
4378 if (fragment_flags.uses_discard) {
4379 enablers.push_back("#define ENABLE_DISCARD\n");
4380 }
4381 if (fragment_flags.uses_normalmap) {
4382 enablers.push_back("#define ENABLE_NORMALMAP\n");
4383 }
4384 if (light_flags.uses_light) {
4385 enablers.push_back("#define USE_LIGHT_SHADER_CODE\n");
4386 }
4387 if (light_flags.uses_shadow_color) {
4388 enablers.push_back("#define USE_OUTPUT_SHADOW_COLOR\n");
4389 }
4390 if (light_flags.uses_time || fragment_flags.uses_time || vertex_flags.uses_time) {
4391 enablers.push_back("#define USE_TIME\n");
4392 uses_time = true;
4393 }
4394 if (vertex_flags.vertex_code_writes_position) {
4395 enablers.push_back("#define VERTEX_SHADER_WRITE_POSITION\n");
4396 }
4397
4398 material_shader.set_custom_shader_code(p_shader->custom_code_id, vertex_code, vertex_globals, fragment_code, light_code, fragment_globals, uniform_names, enablers);
4399 } else if (p_shader->mode == VS::SHADER_CANVAS_ITEM) {
4400
4401 Vector<const char *> enablers;
4402
4403 if (light_flags.uses_time || fragment_flags.uses_time || vertex_flags.uses_time) {
4404 enablers.push_back("#define USE_TIME\n");
4405 uses_time = true;
4406 }
4407 if (fragment_flags.uses_normal) {
4408 enablers.push_back("#define NORMAL_USED\n");
4409 }
4410 if (fragment_flags.uses_normalmap) {
4411 enablers.push_back("#define USE_NORMALMAP\n");
4412 }
4413
4414 if (light_flags.uses_light) {
4415 enablers.push_back("#define USE_LIGHT_SHADER_CODE\n");
4416 }
4417 if (fragment_flags.use_var1_interp || vertex_flags.use_var1_interp)
4418 enablers.push_back("#define ENABLE_VAR1_INTERP\n");
4419 if (fragment_flags.use_var2_interp || vertex_flags.use_var2_interp)
4420 enablers.push_back("#define ENABLE_VAR2_INTERP\n");
4421 if (fragment_flags.uses_texscreen) {
4422 enablers.push_back("#define ENABLE_TEXSCREEN\n");
4423 }
4424 if (fragment_flags.uses_screen_uv) {
4425 enablers.push_back("#define ENABLE_SCREEN_UV\n");
4426 }
4427 if (fragment_flags.uses_texpixel_size) {
4428 enablers.push_back("#define USE_TEXPIXEL_SIZE\n");
4429 }
4430 if (light_flags.uses_shadow_color) {
4431 enablers.push_back("#define USE_OUTPUT_SHADOW_COLOR\n");
4432 }
4433
4434 if (vertex_flags.uses_worldvec) {
4435 enablers.push_back("#define USE_WORLD_VEC\n");
4436 }
4437 canvas_shader.set_custom_shader_code(p_shader->custom_code_id, vertex_code, vertex_globals, fragment_code, light_code, fragment_globals, uniform_names, enablers);
4438
4439 //postprocess_shader.set_custom_shader_code(p_shader->custom_code_id,vertex_code, vertex_globals,fragment_code, fragment_globals,uniform_names);
4440 }
4441
4442 p_shader->valid = true;
4443 p_shader->has_alpha = fragment_flags.uses_alpha || fragment_flags.uses_texscreen;
4444 p_shader->writes_vertex = vertex_flags.vertex_code_writes_vertex;
4445 p_shader->uses_discard = fragment_flags.uses_discard;
4446 p_shader->has_texscreen = fragment_flags.uses_texscreen;
4447 p_shader->has_screen_uv = fragment_flags.uses_screen_uv;
4448 p_shader->can_zpass = !fragment_flags.uses_discard && !vertex_flags.vertex_code_writes_vertex;
4449 p_shader->uses_normal = fragment_flags.uses_normal || light_flags.uses_normal;
4450 p_shader->uses_time = uses_time;
4451 p_shader->uses_texpixel_size = fragment_flags.uses_texpixel_size;
4452 p_shader->version++;
4453 }
4454
_add_geometry(const Geometry * p_geometry,const InstanceData * p_instance,const Geometry * p_geometry_cmp,const GeometryOwner * p_owner,int p_material)4455 void RasterizerGLES2::_add_geometry(const Geometry *p_geometry, const InstanceData *p_instance, const Geometry *p_geometry_cmp, const GeometryOwner *p_owner, int p_material) {
4456
4457 Material *m = NULL;
4458 RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : (p_material >= 0 ? p_instance->materials[p_material] : p_geometry->material);
4459
4460 #ifdef DEBUG_ENABLED
4461 if (current_debug == VS::SCENARIO_DEBUG_OVERDRAW) {
4462 m_src = overdraw_material;
4463 }
4464
4465 #endif
4466
4467 if (m_src)
4468 m = material_owner.get(m_src);
4469
4470 if (!m) {
4471 m = material_owner.get(default_material);
4472 }
4473
4474 ERR_FAIL_COND(!m);
4475
4476 if (m->last_pass != frame) {
4477
4478 if (m->shader.is_valid()) {
4479
4480 m->shader_cache = shader_owner.get(m->shader);
4481 if (m->shader_cache) {
4482
4483 if (!m->shader_cache->valid) {
4484 m->shader_cache = NULL;
4485 } else {
4486 if (m->shader_cache->has_texscreen)
4487 texscreen_used = true;
4488 }
4489 } else {
4490 m->shader = RID();
4491 }
4492
4493 } else {
4494 m->shader_cache = NULL;
4495 }
4496
4497 m->last_pass = frame;
4498 }
4499
4500 RenderList *render_list = NULL;
4501
4502 bool has_base_alpha = (m->shader_cache && m->shader_cache->has_alpha);
4503 bool has_blend_alpha = m->blend_mode != VS::MATERIAL_BLEND_MODE_MIX || m->flags[VS::MATERIAL_FLAG_ONTOP];
4504 bool has_alpha = has_base_alpha || has_blend_alpha;
4505
4506 if (shadow) {
4507
4508 if (has_blend_alpha || (has_base_alpha && m->depth_draw_mode != VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA))
4509 return; //bye
4510
4511 if (!m->shader_cache || (!m->shader_cache->writes_vertex && !m->shader_cache->uses_discard && m->depth_draw_mode != VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA)) {
4512 //shader does not use discard and does not write a vertex position, use generic material
4513 if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)
4514 m = shadow_mat_double_sided_ptr;
4515 else
4516 m = shadow_mat_ptr;
4517 if (m->last_pass != frame) {
4518
4519 if (m->shader.is_valid()) {
4520
4521 m->shader_cache = shader_owner.get(m->shader);
4522 if (m->shader_cache) {
4523
4524 if (!m->shader_cache->valid)
4525 m->shader_cache = NULL;
4526 } else {
4527 m->shader = RID();
4528 }
4529
4530 } else {
4531 m->shader_cache = NULL;
4532 }
4533
4534 m->last_pass = frame;
4535 }
4536 }
4537
4538 render_list = &opaque_render_list;
4539 /* notyet
4540 if (!m->shader_cache || m->shader_cache->can_zpass)
4541 render_list = &alpha_render_list;
4542 } else {
4543 render_list = &opaque_render_list;
4544 }*/
4545
4546 } else {
4547 if (has_alpha) {
4548 render_list = &alpha_render_list;
4549 } else {
4550 render_list = &opaque_render_list;
4551 }
4552 }
4553
4554 RenderList::Element *e = render_list->add_element();
4555
4556 if (!e)
4557 return;
4558
4559 e->geometry = p_geometry;
4560 e->geometry_cmp = p_geometry_cmp;
4561 e->material = m;
4562 e->instance = p_instance;
4563 if (camera_ortho) {
4564 e->depth = camera_plane.distance_to(p_instance->transform.origin);
4565 } else {
4566 e->depth = camera_transform.origin.distance_to(p_instance->transform.origin);
4567 }
4568 e->owner = p_owner;
4569 e->light_type = 0;
4570 e->additive = false;
4571 e->additive_ptr = &e->additive;
4572 e->sort_flags = 0;
4573
4574 if (p_instance->skeleton.is_valid()) {
4575 e->skeleton = skeleton_owner.get(p_instance->skeleton);
4576 if (!e->skeleton)
4577 const_cast<InstanceData *>(p_instance)->skeleton = RID();
4578 else
4579 e->sort_flags |= RenderList::SORT_FLAG_SKELETON;
4580 } else {
4581 e->skeleton = NULL;
4582 }
4583
4584 if (e->geometry->type == Geometry::GEOMETRY_MULTISURFACE)
4585 e->sort_flags |= RenderList::SORT_FLAG_INSTANCING;
4586
4587 e->mirror = p_instance->mirror;
4588 if (m->flags[VS::MATERIAL_FLAG_INVERT_FACES])
4589 e->mirror = !e->mirror;
4590
4591 //e->light_type=0xFF; // no lights!
4592 e->light_type = 3; //light type 3 is no light?
4593 e->light = 0xFFFF;
4594
4595 if (!shadow && !has_blend_alpha && has_alpha && m->depth_draw_mode == VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA) {
4596
4597 //if nothing exists, add this element as opaque too
4598 RenderList::Element *oe = opaque_render_list.add_element();
4599
4600 if (!oe)
4601 return;
4602
4603 memcpy(oe, e, sizeof(RenderList::Element));
4604 oe->additive_ptr = &oe->additive;
4605 }
4606
4607 if (shadow || m->flags[VS::MATERIAL_FLAG_UNSHADED] || current_debug == VS::SCENARIO_DEBUG_SHADELESS) {
4608
4609 e->light_type = 0x7F; //unshaded is zero
4610 } else {
4611
4612 bool duplicate = false;
4613
4614 for (int i = 0; i < directional_light_count; i++) {
4615 uint16_t sort_key = directional_lights[i]->sort_key;
4616 uint8_t light_type = VS::LIGHT_DIRECTIONAL;
4617 if (directional_lights[i]->base->shadow_enabled) {
4618 light_type |= 0x8;
4619 if (directional_lights[i]->base->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS)
4620 light_type |= 0x10;
4621 else if (directional_lights[i]->base->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS)
4622 light_type |= 0x30;
4623 }
4624
4625 RenderList::Element *ec;
4626 if (duplicate) {
4627
4628 ec = render_list->add_element();
4629 if (ec)
4630 memcpy(ec, e, sizeof(RenderList::Element));
4631 } else {
4632
4633 ec = e;
4634 duplicate = true;
4635 }
4636
4637 if (ec) {
4638 ec->light_type = light_type;
4639 ec->light = sort_key;
4640 ec->additive_ptr = &e->additive;
4641 }
4642 }
4643
4644 const RID *liptr = p_instance->light_instances.ptr();
4645 int ilc = p_instance->light_instances.size();
4646
4647 for (int i = 0; i < ilc; i++) {
4648
4649 LightInstance *li = light_instance_owner.get(liptr[i]);
4650 if (!li || li->last_pass != scene_pass) //lit by light not in visible scene
4651 continue;
4652 uint8_t light_type = li->base->type | 0x40; //penalty to ensure directionals always go first
4653 if (li->base->shadow_enabled) {
4654 light_type |= 0x8;
4655 }
4656 uint16_t sort_key = li->sort_key;
4657
4658 RenderList::Element *ec;
4659 if (duplicate) {
4660
4661 ec = render_list->add_element();
4662 if (ec)
4663 memcpy(ec, e, sizeof(RenderList::Element));
4664 } else {
4665 duplicate = true;
4666 ec = e;
4667 }
4668
4669 if (ec) {
4670 ec->light_type = light_type;
4671 ec->light = sort_key;
4672 ec->additive_ptr = &e->additive;
4673 }
4674 }
4675 }
4676
4677 DEBUG_TEST_ERROR("Add Geometry");
4678 }
4679
add_mesh(const RID & p_mesh,const InstanceData * p_data)4680 void RasterizerGLES2::add_mesh(const RID &p_mesh, const InstanceData *p_data) {
4681
4682 Mesh *mesh = mesh_owner.get(p_mesh);
4683 ERR_FAIL_COND(!mesh);
4684
4685 int ssize = mesh->surfaces.size();
4686
4687 for (int i = 0; i < ssize; i++) {
4688
4689 int mat_idx = p_data->materials[i].is_valid() ? i : -1;
4690 Surface *s = mesh->surfaces[i];
4691 _add_geometry(s, p_data, s, NULL, mat_idx);
4692 }
4693
4694 mesh->last_pass = frame;
4695 }
4696
add_multimesh(const RID & p_multimesh,const InstanceData * p_data)4697 void RasterizerGLES2::add_multimesh(const RID &p_multimesh, const InstanceData *p_data) {
4698
4699 MultiMesh *multimesh = multimesh_owner.get(p_multimesh);
4700 ERR_FAIL_COND(!multimesh);
4701
4702 if (!multimesh->mesh.is_valid())
4703 return;
4704 if (multimesh->elements.empty())
4705 return;
4706
4707 Mesh *mesh = mesh_owner.get(multimesh->mesh);
4708 ERR_FAIL_COND(!mesh);
4709
4710 int surf_count = mesh->surfaces.size();
4711 if (multimesh->last_pass != scene_pass) {
4712
4713 multimesh->cache_surfaces.resize(surf_count);
4714 for (int i = 0; i < surf_count; i++) {
4715
4716 multimesh->cache_surfaces[i].material = mesh->surfaces[i]->material;
4717 multimesh->cache_surfaces[i].has_alpha = mesh->surfaces[i]->has_alpha;
4718 multimesh->cache_surfaces[i].surface = mesh->surfaces[i];
4719 }
4720
4721 multimesh->last_pass = scene_pass;
4722 }
4723
4724 for (int i = 0; i < surf_count; i++) {
4725
4726 _add_geometry(&multimesh->cache_surfaces[i], p_data, multimesh->cache_surfaces[i].surface, multimesh);
4727 }
4728 }
4729
add_immediate(const RID & p_immediate,const InstanceData * p_data)4730 void RasterizerGLES2::add_immediate(const RID &p_immediate, const InstanceData *p_data) {
4731
4732 Immediate *immediate = immediate_owner.get(p_immediate);
4733 ERR_FAIL_COND(!immediate);
4734
4735 _add_geometry(immediate, p_data, immediate, NULL);
4736 }
4737
add_particles(const RID & p_particle_instance,const InstanceData * p_data)4738 void RasterizerGLES2::add_particles(const RID &p_particle_instance, const InstanceData *p_data) {
4739
4740 //print_line("adding particles");
4741 ParticlesInstance *particles_instance = particles_instance_owner.get(p_particle_instance);
4742 ERR_FAIL_COND(!particles_instance);
4743 Particles *p = particles_owner.get(particles_instance->particles);
4744 ERR_FAIL_COND(!p);
4745
4746 _add_geometry(p, p_data, p, particles_instance);
4747 draw_next_frame = true;
4748 }
4749
_convert_color(const Color & p_color)4750 Color RasterizerGLES2::_convert_color(const Color &p_color) {
4751
4752 if (current_env && current_env->fx_enabled[VS::ENV_FX_SRGB])
4753 return p_color.to_linear();
4754 else
4755 return p_color;
4756 }
4757
_set_cull(bool p_front,bool p_reverse_cull)4758 void RasterizerGLES2::_set_cull(bool p_front, bool p_reverse_cull) {
4759
4760 bool front = p_front;
4761 if (p_reverse_cull)
4762 front = !front;
4763
4764 if (front != cull_front) {
4765
4766 glCullFace(front ? GL_FRONT : GL_BACK);
4767 cull_front = front;
4768 }
4769 }
4770
_update_material_shader_params(Material * p_material) const4771 _FORCE_INLINE_ void RasterizerGLES2::_update_material_shader_params(Material *p_material) const {
4772
4773 Map<StringName, Material::UniformData> old_mparams = p_material->shader_params;
4774 Map<StringName, Material::UniformData> &mparams = p_material->shader_params;
4775 mparams.clear();
4776 int idx = 0;
4777 for (Map<StringName, ShaderLanguage::Uniform>::Element *E = p_material->shader_cache->uniforms.front(); E; E = E->next()) {
4778
4779 Material::UniformData ud;
4780
4781 bool keep = true; //keep material value
4782
4783 Map<StringName, Material::UniformData>::Element *OLD = old_mparams.find(E->key());
4784 bool has_old = OLD;
4785 bool old_inuse = has_old && old_mparams[E->key()].inuse;
4786
4787 ud.istexture = (E->get().type == ShaderLanguage::TYPE_TEXTURE || E->get().type == ShaderLanguage::TYPE_CUBEMAP);
4788
4789 if (!has_old || !old_inuse) {
4790 keep = false;
4791 } else if (OLD->get().value.get_type() != E->value().default_value.get_type()) {
4792
4793 if (OLD->get().value.get_type() == Variant::INT && E->get().type == ShaderLanguage::TYPE_FLOAT) {
4794 //handle common mistake using shaders (feeding ints instead of float)
4795 OLD->get().value = float(OLD->get().value);
4796 keep = true;
4797 } else if (!ud.istexture && E->value().default_value.get_type() != Variant::NIL) {
4798
4799 keep = false;
4800 }
4801 //type changed between old and new
4802 /* if (old_mparams[E->key()].value.get_type()==Variant::OBJECT) {
4803 if (E->value().default_value.get_type()!=Variant::_RID) //hackfor textures
4804 keep=false;
4805 } else if (!old_mparams[E->key()].value.is_num() || !E->value().default_value.get_type())
4806 keep=false;*/
4807
4808 //value is invalid because type differs and default is not null
4809 ;
4810 }
4811
4812 if (keep) {
4813 ud.value = old_mparams[E->key()].value;
4814
4815 //print_line("KEEP: "+String(E->key()));
4816 } else {
4817 if (ud.istexture && p_material->shader_cache->default_textures.has(E->key()))
4818 ud.value = p_material->shader_cache->default_textures[E->key()];
4819 else
4820 ud.value = E->value().default_value;
4821 old_inuse = false; //if reverted to default, obviously did not work
4822
4823 //print_line("NEW: "+String(E->key())+" because: hasold-"+itos(old_mparams.has(E->key())));
4824 //if (old_mparams.has(E->key()))
4825 // print_line(" told "+Variant::get_type_name(old_mparams[E->key()].value.get_type())+" tnew "+Variant::get_type_name(E->value().default_value.get_type()));
4826 }
4827
4828 ud.index = idx++;
4829 ud.inuse = old_inuse;
4830 mparams[E->key()] = ud;
4831 }
4832
4833 p_material->shader_version = p_material->shader_cache->version;
4834 }
4835
_setup_material(const Geometry * p_geometry,const Material * p_material,bool p_no_const_light,bool p_opaque_pass)4836 bool RasterizerGLES2::_setup_material(const Geometry *p_geometry, const Material *p_material, bool p_no_const_light, bool p_opaque_pass) {
4837
4838 if (p_material->flags[VS::MATERIAL_FLAG_DOUBLE_SIDED]) {
4839 glDisable(GL_CULL_FACE);
4840 } else {
4841 glEnable(GL_CULL_FACE);
4842 }
4843
4844 //glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
4845
4846 /*
4847 if (p_material->flags[VS::MATERIAL_FLAG_WIREFRAME])
4848 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
4849 else
4850 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
4851 */
4852
4853 if (p_material->line_width)
4854 glLineWidth(p_material->line_width);
4855
4856 //all goes to false by default
4857 material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PASS, shadow != NULL);
4858 material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF, shadow_filter == SHADOW_FILTER_PCF5 || shadow_filter == SHADOW_FILTER_PCF13);
4859 material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF_HQ, shadow_filter == SHADOW_FILTER_PCF13);
4860 material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_ESM, shadow_filter == SHADOW_FILTER_ESM);
4861 material_shader.set_conditional(MaterialShaderGLES2::USE_LIGHTMAP_ON_UV2, p_material->flags[VS::MATERIAL_FLAG_LIGHTMAP_ON_UV2]);
4862 material_shader.set_conditional(MaterialShaderGLES2::USE_COLOR_ATTRIB_SRGB_TO_LINEAR, p_material->flags[VS::MATERIAL_FLAG_COLOR_ARRAY_SRGB] && current_env && current_env->fx_enabled[VS::ENV_FX_SRGB]);
4863
4864 if (p_opaque_pass && p_material->depth_draw_mode == VS::MATERIAL_DEPTH_DRAW_OPAQUE_PRE_PASS_ALPHA && p_material->shader_cache && p_material->shader_cache->has_alpha) {
4865
4866 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_CLIP_ALPHA, true);
4867 } else {
4868 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_CLIP_ALPHA, false);
4869 }
4870
4871 if (!shadow) {
4872
4873 bool depth_test = !p_material->flags[VS::MATERIAL_FLAG_ONTOP];
4874 bool depth_write = p_material->depth_draw_mode != VS::MATERIAL_DEPTH_DRAW_NEVER && (p_opaque_pass || p_material->depth_draw_mode == VS::MATERIAL_DEPTH_DRAW_ALWAYS);
4875 //bool depth_write=!p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW] && (p_opaque_pass || !p_material->hints[VS::MATERIAL_HINT_NO_DEPTH_DRAW_FOR_ALPHA]);
4876
4877 if (current_depth_mask != depth_write) {
4878 current_depth_mask = depth_write;
4879 glDepthMask(depth_write);
4880 }
4881
4882 if (current_depth_test != depth_test) {
4883
4884 current_depth_test = depth_test;
4885 if (depth_test)
4886 glEnable(GL_DEPTH_TEST);
4887 else
4888 glDisable(GL_DEPTH_TEST);
4889 }
4890
4891 material_shader.set_conditional(MaterialShaderGLES2::USE_FOG, current_env && current_env->fx_enabled[VS::ENV_FX_FOG]);
4892 //glDepthMask( true );
4893 }
4894
4895 DEBUG_TEST_ERROR("Pre Shader Bind");
4896
4897 bool rebind = false;
4898
4899 if (p_material->shader_cache && p_material->shader_cache->valid) {
4900
4901 // // reduce amount of conditional compilations
4902 // for(int i=0;i<_tex_version_count;i++)
4903 // material_shader.set_conditional((MaterialShaderGLES2::Conditionals)_tex_version[i],false);
4904
4905 // material_shader.set_custom_shader(p_material->shader_cache->custom_code_id);
4906
4907 if (p_material->shader_version != p_material->shader_cache->version) {
4908 //shader changed somehow, must update uniforms
4909
4910 _update_material_shader_params((Material *)p_material);
4911 }
4912 material_shader.set_custom_shader(p_material->shader_cache->custom_code_id);
4913 rebind = material_shader.bind();
4914
4915 DEBUG_TEST_ERROR("Shader Bind");
4916
4917 //set uniforms!
4918 int texcoord = 0;
4919 for (Map<StringName, Material::UniformData>::Element *E = p_material->shader_params.front(); E; E = E->next()) {
4920
4921 if (E->get().index < 0)
4922 continue;
4923 // print_line(String(E->key())+": "+E->get().value);
4924 if (E->get().istexture) {
4925 //clearly a texture..
4926 RID rid = E->get().value;
4927 int loc = material_shader.get_custom_uniform_location(E->get().index); //should be automatic..
4928
4929 Texture *t = NULL;
4930 if (rid.is_valid()) {
4931
4932 t = texture_owner.get(rid);
4933 if (!t) {
4934 E->get().value = RID(); //nullify, invalid texture
4935 rid = RID();
4936 }
4937 }
4938
4939 glActiveTexture(GL_TEXTURE0 + texcoord);
4940 glUniform1i(loc, texcoord); //TODO - this could happen automatically on compile...
4941 if (t) {
4942 if (t->render_target)
4943 t->render_target->last_pass = frame;
4944 if (E->key() == p_material->shader_cache->first_texture) {
4945 tc0_idx = texcoord;
4946 tc0_id_cache = t->tex_id;
4947 }
4948 glBindTexture(t->target, t->tex_id);
4949 } else
4950 glBindTexture(GL_TEXTURE_2D, white_tex); //no texture
4951 texcoord++;
4952
4953 } else if (E->get().value.get_type() == Variant::COLOR) {
4954 Color c = E->get().value;
4955 material_shader.set_custom_uniform(E->get().index, _convert_color(c));
4956 } else {
4957 material_shader.set_custom_uniform(E->get().index, E->get().value);
4958 }
4959 }
4960
4961 if (p_material->shader_cache->has_texscreen && framebuffer.active) {
4962 material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_SCREEN_MULT, Vector2(float(viewport.width) / framebuffer.width, float(viewport.height) / framebuffer.height));
4963 material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_SCREEN_CLAMP, Color(0, 0, float(viewport.width) / framebuffer.width, float(viewport.height) / framebuffer.height));
4964 material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_TEX, texcoord);
4965 glActiveTexture(GL_TEXTURE0 + texcoord);
4966 glBindTexture(GL_TEXTURE_2D, framebuffer.sample_color);
4967 }
4968 if (p_material->shader_cache->has_screen_uv) {
4969 material_shader.set_uniform(MaterialShaderGLES2::SCREEN_UV_MULT, Vector2(1.0 / viewport.width, 1.0 / viewport.height));
4970 }
4971 DEBUG_TEST_ERROR("Material arameters");
4972
4973 if (p_material->shader_cache->uses_time) {
4974 material_shader.set_uniform(MaterialShaderGLES2::TIME, Math::fmod(scaled_time, shader_time_rollback));
4975 draw_next_frame = true;
4976 }
4977 //if uses TIME - draw_next_frame=true
4978
4979 } else {
4980
4981 material_shader.set_custom_shader(0);
4982 rebind = material_shader.bind();
4983
4984 DEBUG_TEST_ERROR("Shader bind2");
4985 }
4986
4987 if (shadow) {
4988
4989 float zofs = shadow->base->vars[VS::LIGHT_PARAM_SHADOW_Z_OFFSET];
4990 float zslope = shadow->base->vars[VS::LIGHT_PARAM_SHADOW_Z_SLOPE_SCALE];
4991 if (shadow_pass >= 1 && shadow->base->type == VS::LIGHT_DIRECTIONAL) {
4992 float m = Math::pow(shadow->base->directional_shadow_param[VS::LIGHT_DIRECTIONAL_SHADOW_PARAM_PSSM_ZOFFSET_SCALE], shadow_pass);
4993 zofs *= m;
4994 zslope *= m;
4995 }
4996 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_Z_OFFSET, zofs);
4997 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_Z_SLOPE_SCALE, zslope);
4998 if (shadow->base->type == VS::LIGHT_OMNI)
4999 material_shader.set_uniform(MaterialShaderGLES2::DUAL_PARABOLOID, shadow->dp);
5000 DEBUG_TEST_ERROR("Shadow uniforms");
5001 }
5002
5003 if (current_env && current_env->fx_enabled[VS::ENV_FX_FOG]) {
5004
5005 Color col_begin = current_env->fx_param[VS::ENV_FX_PARAM_FOG_BEGIN_COLOR];
5006 Color col_end = current_env->fx_param[VS::ENV_FX_PARAM_FOG_END_COLOR];
5007 col_begin = _convert_color(col_begin);
5008 col_end = _convert_color(col_end);
5009 float from = current_env->fx_param[VS::ENV_FX_PARAM_FOG_BEGIN];
5010 float zf = camera_z_far;
5011 float curve = current_env->fx_param[VS::ENV_FX_PARAM_FOG_ATTENUATION];
5012 material_shader.set_uniform(MaterialShaderGLES2::FOG_PARAMS, Vector3(from, zf, curve));
5013 material_shader.set_uniform(MaterialShaderGLES2::FOG_COLOR_BEGIN, Vector3(col_begin.r, col_begin.g, col_begin.b));
5014 material_shader.set_uniform(MaterialShaderGLES2::FOG_COLOR_END, Vector3(col_end.r, col_end.g, col_end.b));
5015 }
5016
5017 //material_shader.set_uniform(MaterialShaderGLES2::TIME,Math::fmod(scaled_time,300.0));
5018 //if uses TIME - draw_next_frame=true
5019
5020 return rebind;
5021 }
5022
_setup_light(uint16_t p_light)5023 void RasterizerGLES2::_setup_light(uint16_t p_light) {
5024
5025 if (shadow)
5026 return;
5027
5028 if (p_light == 0xFFFF)
5029 return;
5030
5031 enum {
5032 VL_LIGHT_POS,
5033 VL_LIGHT_DIR,
5034 VL_LIGHT_ATTENUATION,
5035 VL_LIGHT_SPOT_ATTENUATION,
5036 VL_LIGHT_DIFFUSE,
5037 VL_LIGHT_SPECULAR,
5038 VL_LIGHT_MAX
5039 };
5040
5041 static const MaterialShaderGLES2::Uniforms light_uniforms[VL_LIGHT_MAX] = {
5042 MaterialShaderGLES2::LIGHT_POS,
5043 MaterialShaderGLES2::LIGHT_DIRECTION,
5044 MaterialShaderGLES2::LIGHT_ATTENUATION,
5045 MaterialShaderGLES2::LIGHT_SPOT_ATTENUATION,
5046 MaterialShaderGLES2::LIGHT_DIFFUSE,
5047 MaterialShaderGLES2::LIGHT_SPECULAR,
5048 };
5049
5050 GLfloat light_data[VL_LIGHT_MAX][3];
5051 memset(light_data, 0, (VL_LIGHT_MAX)*3 * sizeof(GLfloat));
5052
5053 LightInstance *li = light_instances[p_light];
5054 Light *l = li->base;
5055
5056 Color col_diffuse = _convert_color(l->colors[VS::LIGHT_COLOR_DIFFUSE]);
5057 Color col_specular = _convert_color(l->colors[VS::LIGHT_COLOR_SPECULAR]);
5058
5059 for (int j = 0; j < 3; j++) {
5060 light_data[VL_LIGHT_DIFFUSE][j] = col_diffuse[j];
5061 light_data[VL_LIGHT_SPECULAR][j] = col_specular[j];
5062 }
5063
5064 if (l->type != VS::LIGHT_OMNI) {
5065
5066 Vector3 dir = -li->transform.get_basis().get_axis(2);
5067 dir = camera_transform_inverse.basis.xform(dir).normalized();
5068 for (int j = 0; j < 3; j++)
5069 light_data[VL_LIGHT_DIR][j] = dir[j];
5070 }
5071
5072 if (l->type != VS::LIGHT_DIRECTIONAL) {
5073
5074 Vector3 pos = li->transform.get_origin();
5075 pos = camera_transform_inverse.xform(pos);
5076 for (int j = 0; j < 3; j++)
5077 light_data[VL_LIGHT_POS][j] = pos[j];
5078 }
5079
5080 if (li->near_shadow_buffer) {
5081
5082 glActiveTexture(GL_TEXTURE0 + max_texture_units - 1);
5083 //if (read_depth_supported) {
5084
5085 glBindTexture(GL_TEXTURE_2D, li->near_shadow_buffer->depth);
5086 //} else {
5087
5088 //}
5089
5090 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX, li->shadow_projection[0]);
5091 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXEL_SIZE, Vector2(1.0, 1.0) / li->near_shadow_buffer->size);
5092 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXTURE, max_texture_units - 1);
5093 if (shadow_filter == SHADOW_FILTER_ESM)
5094 material_shader.set_uniform(MaterialShaderGLES2::ESM_MULTIPLIER, float(li->base->vars[VS::LIGHT_PARAM_SHADOW_ESM_MULTIPLIER]));
5095
5096 if (li->base->type == VS::LIGHT_DIRECTIONAL) {
5097
5098 if (li->base->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
5099
5100 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX2, li->shadow_projection[1]);
5101 material_shader.set_uniform(MaterialShaderGLES2::LIGHT_PSSM_SPLIT, Vector3(li->shadow_split[0], li->shadow_split[1], li->shadow_split[2]));
5102 } else if (li->base->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
5103
5104 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX2, li->shadow_projection[1]);
5105 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX3, li->shadow_projection[2]);
5106 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX4, li->shadow_projection[3]);
5107 material_shader.set_uniform(MaterialShaderGLES2::LIGHT_PSSM_SPLIT, Vector3(li->shadow_split[0], li->shadow_split[1], li->shadow_split[2]));
5108 }
5109 //print_line("shadow split: "+rtos(li->shadow_split));
5110 }
5111
5112 material_shader.set_uniform(MaterialShaderGLES2::SHADOW_DARKENING, li->base->vars[VS::LIGHT_PARAM_SHADOW_DARKENING]);
5113 //matrix
5114 }
5115
5116 light_data[VL_LIGHT_ATTENUATION][0] = l->vars[VS::LIGHT_PARAM_ENERGY];
5117
5118 if (l->type == VS::LIGHT_DIRECTIONAL) {
5119 light_data[VL_LIGHT_ATTENUATION][1] = l->directional_shadow_param[VS::LIGHT_DIRECTIONAL_SHADOW_PARAM_MAX_DISTANCE];
5120 } else {
5121 light_data[VL_LIGHT_ATTENUATION][1] = l->vars[VS::LIGHT_PARAM_RADIUS];
5122 }
5123
5124 light_data[VL_LIGHT_ATTENUATION][2] = l->vars[VS::LIGHT_PARAM_ATTENUATION];
5125
5126 light_data[VL_LIGHT_SPOT_ATTENUATION][0] = Math::cos(Math::deg2rad(l->vars[VS::LIGHT_PARAM_SPOT_ANGLE]));
5127 light_data[VL_LIGHT_SPOT_ATTENUATION][1] = l->vars[VS::LIGHT_PARAM_SPOT_ATTENUATION];
5128
5129 //int uf = material_shader.get_uniform(MaterialShaderGLES2::LIGHT_PARAMS);
5130 for (int i = 0; i < VL_LIGHT_MAX; i++) {
5131 glUniform3f(material_shader.get_uniform(light_uniforms[i]), light_data[i][0], light_data[i][1], light_data[i][2]);
5132 }
5133 }
5134
5135 template <bool USE_NORMAL, bool USE_TANGENT, bool INPLACE>
_skeleton_xform(const uint8_t * p_src_array,int p_src_stride,uint8_t * p_dst_array,int p_dst_stride,int p_elements,const uint8_t * p_src_bones,const uint8_t * p_src_weights,const Skeleton::Bone * p_bone_xforms)5136 void RasterizerGLES2::_skeleton_xform(const uint8_t *p_src_array, int p_src_stride, uint8_t *p_dst_array, int p_dst_stride, int p_elements, const uint8_t *p_src_bones, const uint8_t *p_src_weights, const Skeleton::Bone *p_bone_xforms) {
5137
5138 uint32_t basesize = 3;
5139 if (USE_NORMAL)
5140 basesize += 3;
5141 if (USE_TANGENT)
5142 basesize += 4;
5143
5144 uint32_t extra = (p_dst_stride - basesize * 4);
5145 const int dstvec_size = 3 + (USE_NORMAL ? 3 : 0) + (USE_TANGENT ? 4 : 0);
5146 float dstcopy[dstvec_size];
5147
5148 for (int i = 0; i < p_elements; i++) {
5149
5150 uint32_t ss = p_src_stride * i;
5151 uint32_t ds = p_dst_stride * i;
5152 const uint16_t *bi = (const uint16_t *)&p_src_bones[ss];
5153 const float *bw = (const float *)&p_src_weights[ss];
5154 const float *src_vec = (const float *)&p_src_array[ss];
5155 float *dst_vec;
5156 if (INPLACE)
5157 dst_vec = dstcopy;
5158 else
5159 dst_vec = (float *)&p_dst_array[ds];
5160
5161 dst_vec[0] = 0.0;
5162 dst_vec[1] = 0.0;
5163 dst_vec[2] = 0.0;
5164 //conditionals simply removed by optimizer
5165 if (USE_NORMAL) {
5166
5167 dst_vec[3] = 0.0;
5168 dst_vec[4] = 0.0;
5169 dst_vec[5] = 0.0;
5170
5171 if (USE_TANGENT) {
5172
5173 dst_vec[6] = 0.0;
5174 dst_vec[7] = 0.0;
5175 dst_vec[8] = 0.0;
5176 dst_vec[9] = src_vec[9];
5177 }
5178 } else {
5179
5180 if (USE_TANGENT) {
5181
5182 dst_vec[3] = 0.0;
5183 dst_vec[4] = 0.0;
5184 dst_vec[5] = 0.0;
5185 dst_vec[6] = src_vec[6];
5186 }
5187 }
5188
5189 #define _XFORM_BONE(m_idx) \
5190 if (bw[m_idx] == 0) \
5191 goto end; \
5192 p_bone_xforms[bi[m_idx]].transform_add_mul3(&src_vec[0], &dst_vec[0], bw[m_idx]); \
5193 if (USE_NORMAL) { \
5194 p_bone_xforms[bi[m_idx]].transform3_add_mul3(&src_vec[3], &dst_vec[3], bw[m_idx]); \
5195 if (USE_TANGENT) { \
5196 p_bone_xforms[bi[m_idx]].transform3_add_mul3(&src_vec[6], &dst_vec[6], bw[m_idx]); \
5197 } \
5198 } else { \
5199 if (USE_TANGENT) { \
5200 p_bone_xforms[bi[m_idx]].transform3_add_mul3(&src_vec[3], &dst_vec[3], bw[m_idx]); \
5201 } \
5202 }
5203
5204 _XFORM_BONE(0);
5205 _XFORM_BONE(1);
5206 _XFORM_BONE(2);
5207 _XFORM_BONE(3);
5208
5209 end:
5210
5211 if (INPLACE) {
5212
5213 const uint8_t *esp = (const uint8_t *)dstcopy;
5214 uint8_t *edp = (uint8_t *)&p_dst_array[ds];
5215
5216 for (uint32_t j = 0; j < dstvec_size * 4; j++) {
5217
5218 edp[j] = esp[j];
5219 }
5220
5221 } else {
5222 //copy extra stuff
5223 const uint8_t *esp = (const uint8_t *)&src_vec[basesize];
5224 uint8_t *edp = (uint8_t *)&dst_vec[basesize];
5225
5226 for (uint32_t j = 0; j < extra; j++) {
5227
5228 edp[j] = esp[j];
5229 }
5230 }
5231 }
5232 }
5233
_setup_geometry(const Geometry * p_geometry,const Material * p_material,const Skeleton * p_skeleton,const float * p_morphs)5234 Error RasterizerGLES2::_setup_geometry(const Geometry *p_geometry, const Material *p_material, const Skeleton *p_skeleton, const float *p_morphs) {
5235
5236 switch (p_geometry->type) {
5237
5238 case Geometry::GEOMETRY_MULTISURFACE:
5239 case Geometry::GEOMETRY_SURFACE: {
5240
5241 const Surface *surf = NULL;
5242 if (p_geometry->type == Geometry::GEOMETRY_SURFACE)
5243 surf = static_cast<const Surface *>(p_geometry);
5244 else if (p_geometry->type == Geometry::GEOMETRY_MULTISURFACE)
5245 surf = static_cast<const MultiMeshSurface *>(p_geometry)->surface;
5246
5247 if (surf->format != surf->configured_format) {
5248 if (OS::get_singleton()->is_stdout_verbose()) {
5249
5250 print_line("has format: " + itos(surf->format));
5251 print_line("configured format: " + itos(surf->configured_format));
5252 }
5253 ERR_EXPLAIN("Missing arrays (not set) in surface");
5254 }
5255 ERR_FAIL_COND_V(surf->format != surf->configured_format, ERR_UNCONFIGURED);
5256 uint8_t *base = 0;
5257 int stride = surf->stride;
5258 bool use_VBO = (surf->array_local == 0);
5259 _setup_geometry_vinfo = surf->array_len;
5260
5261 bool skeleton_valid = p_skeleton && (surf->format & VS::ARRAY_FORMAT_BONES) && (surf->format & VS::ARRAY_FORMAT_WEIGHTS) && !p_skeleton->bones.empty() && p_skeleton->bones.size() > surf->max_bone;
5262 /*
5263 if (surf->packed) {
5264 float scales[4]={surf->vertex_scale,surf->uv_scale,surf->uv2_scale,0.0};
5265 glVertexAttrib4fv( 7, scales );
5266 } else {
5267 glVertexAttrib4f( 7, 1,1,1,1 );
5268
5269 }*/
5270
5271 if (!use_VBO) {
5272
5273 DEBUG_TEST_ERROR("Draw NO VBO");
5274
5275 base = surf->array_local;
5276 glBindBuffer(GL_ARRAY_BUFFER, 0);
5277 bool can_copy_to_local = surf->local_stride * surf->array_len <= skinned_buffer_size;
5278 if (p_morphs && surf->stride * surf->array_len > skinned_buffer_size)
5279 can_copy_to_local = false;
5280
5281 if (!can_copy_to_local)
5282 skeleton_valid = false;
5283
5284 /* compute morphs */
5285
5286 if (p_morphs && surf->morph_target_count && can_copy_to_local) {
5287
5288 base = skinned_buffer;
5289 stride = surf->local_stride;
5290
5291 //copy all first
5292 float coef = 1.0;
5293
5294 for (int i = 0; i < surf->morph_target_count; i++) {
5295 if (surf->mesh->morph_target_mode == VS::MORPH_MODE_NORMALIZED)
5296 coef -= p_morphs[i];
5297 ERR_FAIL_COND_V(surf->morph_format != surf->morph_targets_local[i].configured_format, ERR_INVALID_DATA);
5298 }
5299
5300 int16_t coeffp = CLAMP(coef * 255, 0, 255);
5301
5302 for (int i = 0; i < VS::ARRAY_MAX - 1; i++) {
5303
5304 const Surface::ArrayData &ad = surf->array[i];
5305 if (ad.size == 0)
5306 continue;
5307
5308 int ofs = ad.ofs;
5309 int src_stride = surf->stride;
5310 int dst_stride = skeleton_valid ? surf->stride : surf->local_stride;
5311 int count = surf->array_len;
5312
5313 if (!skeleton_valid && i >= VS::ARRAY_MAX - 3)
5314 break;
5315
5316 switch (i) {
5317
5318 case VS::ARRAY_VERTEX:
5319 case VS::ARRAY_NORMAL:
5320 case VS::ARRAY_TANGENT: {
5321
5322 for (int k = 0; k < count; k++) {
5323
5324 const float *src = (const float *)&surf->array_local[ofs + k * src_stride];
5325 float *dst = (float *)&base[ofs + k * dst_stride];
5326
5327 dst[0] = src[0] * coef;
5328 dst[1] = src[1] * coef;
5329 dst[2] = src[2] * coef;
5330 };
5331
5332 } break;
5333 case VS::ARRAY_COLOR: {
5334
5335 for (int k = 0; k < count; k++) {
5336
5337 const uint8_t *src = (const uint8_t *)&surf->array_local[ofs + k * src_stride];
5338 uint8_t *dst = (uint8_t *)&base[ofs + k * dst_stride];
5339
5340 dst[0] = (src[0] * coeffp) >> 8;
5341 dst[1] = (src[1] * coeffp) >> 8;
5342 dst[2] = (src[2] * coeffp) >> 8;
5343 dst[3] = (src[3] * coeffp) >> 8;
5344 }
5345
5346 } break;
5347 case VS::ARRAY_TEX_UV:
5348 case VS::ARRAY_TEX_UV2: {
5349
5350 for (int k = 0; k < count; k++) {
5351
5352 const float *src = (const float *)&surf->array_local[ofs + k * src_stride];
5353 float *dst = (float *)&base[ofs + k * dst_stride];
5354
5355 dst[0] = src[0] * coef;
5356 dst[1] = src[1] * coef;
5357 }
5358
5359 } break;
5360 case VS::ARRAY_BONES:
5361 case VS::ARRAY_WEIGHTS: {
5362
5363 for (int k = 0; k < count; k++) {
5364
5365 const float *src = (const float *)&surf->array_local[ofs + k * src_stride];
5366 float *dst = (float *)&base[ofs + k * dst_stride];
5367
5368 dst[0] = src[0];
5369 dst[1] = src[1];
5370 dst[2] = src[2];
5371 dst[3] = src[3];
5372 }
5373
5374 } break;
5375 }
5376 }
5377
5378 for (int j = 0; j < surf->morph_target_count; j++) {
5379
5380 for (int i = 0; i < VS::ARRAY_MAX - 3; i++) {
5381
5382 const Surface::ArrayData &ad = surf->array[i];
5383 if (ad.size == 0)
5384 continue;
5385
5386 int ofs = ad.ofs;
5387 int src_stride = surf->local_stride;
5388 int dst_stride = skeleton_valid ? surf->stride : surf->local_stride;
5389 int count = surf->array_len;
5390 const uint8_t *morph = surf->morph_targets_local[j].array;
5391 float w = p_morphs[j];
5392 int16_t wfp = CLAMP(w * 255, 0, 255);
5393
5394 switch (i) {
5395
5396 case VS::ARRAY_VERTEX:
5397 case VS::ARRAY_NORMAL:
5398 case VS::ARRAY_TANGENT: {
5399
5400 for (int k = 0; k < count; k++) {
5401
5402 const float *src_morph = (const float *)&morph[ofs + k * src_stride];
5403 float *dst = (float *)&base[ofs + k * dst_stride];
5404
5405 dst[0] += src_morph[0] * w;
5406 dst[1] += src_morph[1] * w;
5407 dst[2] += src_morph[2] * w;
5408 }
5409
5410 } break;
5411 case VS::ARRAY_COLOR: {
5412 for (int k = 0; k < count; k++) {
5413
5414 const uint8_t *src = (const uint8_t *)&morph[ofs + k * src_stride];
5415 uint8_t *dst = (uint8_t *)&base[ofs + k * dst_stride];
5416
5417 dst[0] = (src[0] * wfp) >> 8;
5418 dst[1] = (src[1] * wfp) >> 8;
5419 dst[2] = (src[2] * wfp) >> 8;
5420 dst[3] = (src[3] * wfp) >> 8;
5421 }
5422
5423 } break;
5424 case VS::ARRAY_TEX_UV:
5425 case VS::ARRAY_TEX_UV2: {
5426
5427 for (int k = 0; k < count; k++) {
5428
5429 const float *src_morph = (const float *)&morph[ofs + k * src_stride];
5430 float *dst = (float *)&base[ofs + k * dst_stride];
5431
5432 dst[0] += src_morph[0] * w;
5433 dst[1] += src_morph[1] * w;
5434 }
5435
5436 } break;
5437 }
5438 }
5439 }
5440
5441 if (skeleton_valid) {
5442
5443 const uint8_t *src_weights = &surf->array_local[surf->array[VS::ARRAY_WEIGHTS].ofs];
5444 const uint8_t *src_bones = &surf->array_local[surf->array[VS::ARRAY_BONES].ofs];
5445 const Skeleton::Bone *skeleton = &p_skeleton->bones[0];
5446
5447 if (surf->format & VS::ARRAY_FORMAT_NORMAL && surf->format & VS::ARRAY_FORMAT_TANGENT)
5448 _skeleton_xform<true, true, true>(base, surf->stride, base, surf->stride, surf->array_len, src_bones, src_weights, skeleton);
5449 else if (surf->format & (VS::ARRAY_FORMAT_NORMAL))
5450 _skeleton_xform<true, false, true>(base, surf->stride, base, surf->stride, surf->array_len, src_bones, src_weights, skeleton);
5451 else if (surf->format & (VS::ARRAY_FORMAT_TANGENT))
5452 _skeleton_xform<false, true, true>(base, surf->stride, base, surf->stride, surf->array_len, src_bones, src_weights, skeleton);
5453 else
5454 _skeleton_xform<false, false, true>(base, surf->stride, base, surf->stride, surf->array_len, src_bones, src_weights, skeleton);
5455 }
5456
5457 stride = skeleton_valid ? surf->stride : surf->local_stride;
5458
5459 #if 0
5460 {
5461 //in-place skeleton tansformation, only used for morphs, slow.
5462 //should uptimize some day....
5463
5464 const uint8_t *src_weights=&surf->array_local[surf->array[VS::ARRAY_WEIGHTS].ofs];
5465 const uint8_t *src_bones=&surf->array_local[surf->array[VS::ARRAY_BONES].ofs];
5466 int src_stride = surf->stride;
5467 int count = surf->array_len;
5468 const Transform *skeleton = &p_skeleton->bones[0];
5469
5470 for(int i=0;i<VS::ARRAY_MAX-1;i++) {
5471
5472 const Surface::ArrayData& ad=surf->array[i];
5473 if (ad.size==0)
5474 continue;
5475
5476 int ofs = ad.ofs;
5477
5478
5479 switch(i) {
5480
5481 case VS::ARRAY_VERTEX: {
5482 for(int k=0;k<count;k++) {
5483
5484 float *ptr= (float*)&base[ofs+k*stride];
5485 const GLfloat* weights = reinterpret_cast<const GLfloat*>(&src_weights[k*src_stride]);
5486 const GLfloat *bones = reinterpret_cast<const GLfloat*>(&src_bones[k*src_stride]);
5487
5488 Vector3 src( ptr[0], ptr[1], ptr[2] );
5489 Vector3 dst;
5490 for(int j=0;j<VS::ARRAY_WEIGHTS_SIZE;j++) {
5491
5492 float w = weights[j];
5493 if (w==0)
5494 break;
5495
5496 //print_line("accum "+itos(i)+" += "+rtos(Math::ftoi(bones[j]))+" * "+skeleton[ Math::ftoi(bones[j]) ]+" * "+rtos(w));
5497 int bidx = Math::fast_ftoi(bones[j]);
5498 dst+=skeleton[ bidx ].xform(src) * w;
5499 }
5500
5501 ptr[0]=dst.x;
5502 ptr[1]=dst.y;
5503 ptr[2]=dst.z;
5504
5505 } break;
5506
5507 } break;
5508 case VS::ARRAY_NORMAL:
5509 case VS::ARRAY_TANGENT: {
5510 for(int k=0;k<count;k++) {
5511
5512 float *ptr= (float*)&base[ofs+k*stride];
5513 const GLfloat* weights = reinterpret_cast<const GLfloat*>(&src_weights[k*src_stride]);
5514 const GLfloat *bones = reinterpret_cast<const GLfloat*>(&src_bones[k*src_stride]);
5515
5516 Vector3 src( ptr[0], ptr[1], ptr[2] );
5517 Vector3 dst;
5518 for(int j=0;j<VS::ARRAY_WEIGHTS_SIZE;j++) {
5519
5520 float w = weights[j];
5521 if (w==0)
5522 break;
5523
5524 //print_line("accum "+itos(i)+" += "+rtos(Math::ftoi(bones[j]))+" * "+skeleton[ Math::ftoi(bones[j]) ]+" * "+rtos(w));
5525 int bidx=Math::fast_ftoi(bones[j]);
5526 dst+=skeleton[ bidx ].basis.xform(src) * w;
5527 }
5528
5529 ptr[0]=dst.x;
5530 ptr[1]=dst.y;
5531 ptr[2]=dst.z;
5532
5533 } break;
5534
5535 } break;
5536 }
5537 }
5538 }
5539 #endif
5540
5541 } else if (skeleton_valid) {
5542
5543 base = skinned_buffer;
5544 //copy stuff and get it ready for the skeleton
5545
5546 int dst_stride = surf->stride - (surf->array[VS::ARRAY_BONES].size + surf->array[VS::ARRAY_WEIGHTS].size);
5547 const uint8_t *src_weights = &surf->array_local[surf->array[VS::ARRAY_WEIGHTS].ofs];
5548 const uint8_t *src_bones = &surf->array_local[surf->array[VS::ARRAY_BONES].ofs];
5549 const Skeleton::Bone *skeleton = &p_skeleton->bones[0];
5550
5551 if (surf->format & VS::ARRAY_FORMAT_NORMAL && surf->format & VS::ARRAY_FORMAT_TANGENT)
5552 _skeleton_xform<true, true, false>(surf->array_local, surf->stride, base, dst_stride, surf->array_len, src_bones, src_weights, skeleton);
5553 else if (surf->format & (VS::ARRAY_FORMAT_NORMAL))
5554 _skeleton_xform<true, false, false>(surf->array_local, surf->stride, base, dst_stride, surf->array_len, src_bones, src_weights, skeleton);
5555 else if (surf->format & (VS::ARRAY_FORMAT_TANGENT))
5556 _skeleton_xform<false, true, false>(surf->array_local, surf->stride, base, dst_stride, surf->array_len, src_bones, src_weights, skeleton);
5557 else
5558 _skeleton_xform<false, false, false>(surf->array_local, surf->stride, base, dst_stride, surf->array_len, src_bones, src_weights, skeleton);
5559
5560 stride = dst_stride;
5561 }
5562
5563 } else {
5564
5565 glBindBuffer(GL_ARRAY_BUFFER, surf->vertex_id);
5566 };
5567
5568 for (int i = 0; i < (VS::ARRAY_MAX - 1); i++) {
5569
5570 const Surface::ArrayData &ad = surf->array[i];
5571
5572 // if (!gl_texcoord_shader[i])
5573 // continue;
5574
5575 if (ad.size == 0 || !ad.bind) {
5576 glDisableVertexAttribArray(i);
5577 if (i == VS::ARRAY_COLOR) {
5578 _set_color_attrib(Color(1, 1, 1, 1));
5579 };
5580 //print_line("disable: "+itos(i));
5581 continue; // this one is disabled.
5582 }
5583
5584 glEnableVertexAttribArray(i);
5585 // print_line("set: "+itos(i)+" - count: "+itos(ad.count)+" datatype: "+itos(ad.datatype)+" ofs: "+itos(ad.ofs)+" stride: "+itos(stride)+" total len: "+itos(surf->array_len));
5586 glVertexAttribPointer(i, ad.count, ad.datatype, ad.normalize, stride, &base[ad.ofs]);
5587 }
5588 #ifdef GLEW_ENABLED
5589 //"desktop" opengl needs this.
5590 if (surf->primitive == VS::PRIMITIVE_POINTS) {
5591 glEnable(GL_POINT_SPRITE);
5592 glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
5593
5594 } else {
5595 glDisable(GL_POINT_SPRITE);
5596 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
5597 }
5598 #endif
5599 } break;
5600
5601 default: break;
5602 };
5603
5604 return OK;
5605 };
5606
5607 static const GLenum gl_primitive[] = {
5608 GL_POINTS,
5609 GL_LINES,
5610 GL_LINE_STRIP,
5611 GL_LINE_LOOP,
5612 GL_TRIANGLES,
5613 GL_TRIANGLE_STRIP,
5614 GL_TRIANGLE_FAN
5615 };
5616
_render(const Geometry * p_geometry,const Material * p_material,const Skeleton * p_skeleton,const GeometryOwner * p_owner,const Transform & p_xform)5617 void RasterizerGLES2::_render(const Geometry *p_geometry, const Material *p_material, const Skeleton *p_skeleton, const GeometryOwner *p_owner, const Transform &p_xform) {
5618
5619 _rinfo.object_count++;
5620
5621 switch (p_geometry->type) {
5622
5623 case Geometry::GEOMETRY_SURFACE: {
5624
5625 Surface *s = (Surface *)p_geometry;
5626
5627 _rinfo.vertex_count += s->array_len;
5628
5629 if (s->index_array_len > 0) {
5630
5631 if (s->index_array_local) {
5632
5633 //print_line("LOCAL F: "+itos(s->format)+" C: "+itos(s->index_array_len)+" VC: "+itos(s->array_len));
5634 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
5635 glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len > (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, s->index_array_local);
5636
5637 } else {
5638 // print_line("indices: "+itos(s->index_array_local) );
5639
5640 //print_line("VBO F: "+itos(s->format)+" C: "+itos(s->index_array_len)+" VC: "+itos(s->array_len));
5641 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
5642 glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len > (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
5643 }
5644
5645 } else {
5646
5647 glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
5648 };
5649
5650 _rinfo.draw_calls++;
5651 } break;
5652
5653 case Geometry::GEOMETRY_MULTISURFACE: {
5654
5655 material_shader.bind_uniforms();
5656 Surface *s = static_cast<const MultiMeshSurface *>(p_geometry)->surface;
5657 const MultiMesh *mm = static_cast<const MultiMesh *>(p_owner);
5658 int element_count = mm->elements.size();
5659
5660 if (element_count == 0)
5661 return;
5662
5663 if (mm->visible >= 0) {
5664 element_count = MIN(element_count, mm->visible);
5665 }
5666
5667 const MultiMesh::Element *elements = &mm->elements[0];
5668
5669 _rinfo.vertex_count += s->array_len * element_count;
5670
5671 _rinfo.draw_calls += element_count;
5672
5673 if (use_texture_instancing) {
5674 //this is probably the fastest all around way if vertex texture fetch is supported
5675
5676 float twd = (1.0 / mm->tw) * 4.0;
5677 float thd = 1.0 / mm->th;
5678 float parm[3] = { 0.0, 01.0, (1.0f / mm->tw) };
5679 glActiveTexture(GL_TEXTURE0 + max_texture_units - 2);
5680 glDisableVertexAttribArray(6);
5681 glBindTexture(GL_TEXTURE_2D, mm->tex_id);
5682 material_shader.set_uniform(MaterialShaderGLES2::INSTANCE_MATRICES, GL_TEXTURE0 + max_texture_units - 2);
5683
5684 if (s->index_array_len > 0) {
5685
5686 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
5687 for (int i = 0; i < element_count; i++) {
5688 parm[0] = (i % (mm->tw >> 2)) * twd;
5689 parm[1] = (i / (mm->tw >> 2)) * thd;
5690 glVertexAttrib3fv(6, parm);
5691 glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len > (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
5692 }
5693
5694 } else {
5695
5696 for (int i = 0; i < element_count; i++) {
5697 //parm[0]=(i%(mm->tw>>2))*twd;
5698 //parm[1]=(i/(mm->tw>>2))*thd;
5699 glVertexAttrib3fv(6, parm);
5700 glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
5701 }
5702 };
5703
5704 } else if (use_attribute_instancing) {
5705 //if not, using atributes instead of uniforms can be really fast in forward rendering architectures
5706 if (s->index_array_len > 0) {
5707
5708 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
5709 for (int i = 0; i < element_count; i++) {
5710 glVertexAttrib4fv(8, &elements[i].matrix[0]);
5711 glVertexAttrib4fv(9, &elements[i].matrix[4]);
5712 glVertexAttrib4fv(10, &elements[i].matrix[8]);
5713 glVertexAttrib4fv(11, &elements[i].matrix[12]);
5714 glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len > (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
5715 }
5716
5717 } else {
5718
5719 for (int i = 0; i < element_count; i++) {
5720 glVertexAttrib4fv(8, &elements[i].matrix[0]);
5721 glVertexAttrib4fv(9, &elements[i].matrix[4]);
5722 glVertexAttrib4fv(10, &elements[i].matrix[8]);
5723 glVertexAttrib4fv(11, &elements[i].matrix[12]);
5724 glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
5725 }
5726 };
5727
5728 } else {
5729
5730 //nothing to do, slow path (hope no hardware has to use it... but you never know)
5731
5732 if (s->index_array_len > 0) {
5733
5734 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
5735 for (int i = 0; i < element_count; i++) {
5736
5737 glUniformMatrix4fv(material_shader.get_uniform_location(MaterialShaderGLES2::INSTANCE_TRANSFORM), 1, false, elements[i].matrix);
5738 glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len > (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
5739 }
5740
5741 } else {
5742
5743 for (int i = 0; i < element_count; i++) {
5744 glUniformMatrix4fv(material_shader.get_uniform_location(MaterialShaderGLES2::INSTANCE_TRANSFORM), 1, false, elements[i].matrix);
5745 glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
5746 }
5747 };
5748 }
5749 } break;
5750 case Geometry::GEOMETRY_IMMEDIATE: {
5751
5752 bool restore_tex = false;
5753 const Immediate *im = static_cast<const Immediate *>(p_geometry);
5754 if (im->building) {
5755 return;
5756 }
5757
5758 glBindBuffer(GL_ARRAY_BUFFER, 0);
5759
5760 for (const List<Immediate::Chunk>::Element *E = im->chunks.front(); E; E = E->next()) {
5761
5762 const Immediate::Chunk &c = E->get();
5763 if (c.vertices.empty()) {
5764 continue;
5765 }
5766 for (int i = 0; i < c.vertices.size(); i++)
5767
5768 if (c.texture.is_valid() && texture_owner.owns(c.texture)) {
5769
5770 const Texture *t = texture_owner.get(c.texture);
5771 glActiveTexture(GL_TEXTURE0 + tc0_idx);
5772 glBindTexture(t->target, t->tex_id);
5773 restore_tex = true;
5774
5775 } else if (restore_tex) {
5776
5777 glActiveTexture(GL_TEXTURE0 + tc0_idx);
5778 glBindTexture(GL_TEXTURE_2D, tc0_id_cache);
5779 restore_tex = false;
5780 }
5781
5782 if (!c.normals.empty()) {
5783
5784 glEnableVertexAttribArray(VS::ARRAY_NORMAL);
5785 glVertexAttribPointer(VS::ARRAY_NORMAL, 3, GL_FLOAT, false, sizeof(Vector3), c.normals.ptr());
5786
5787 } else {
5788
5789 glDisableVertexAttribArray(VS::ARRAY_NORMAL);
5790 }
5791
5792 if (!c.tangents.empty()) {
5793
5794 glEnableVertexAttribArray(VS::ARRAY_TANGENT);
5795 glVertexAttribPointer(VS::ARRAY_TANGENT, 4, GL_FLOAT, false, sizeof(Plane), c.tangents.ptr());
5796
5797 } else {
5798
5799 glDisableVertexAttribArray(VS::ARRAY_TANGENT);
5800 }
5801
5802 if (!c.colors.empty()) {
5803
5804 glEnableVertexAttribArray(VS::ARRAY_COLOR);
5805 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), c.colors.ptr());
5806
5807 } else {
5808
5809 glDisableVertexAttribArray(VS::ARRAY_COLOR);
5810 _set_color_attrib(Color(1, 1, 1, 1));
5811 }
5812
5813 if (!c.uvs.empty()) {
5814
5815 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
5816 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), c.uvs.ptr());
5817
5818 } else {
5819
5820 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
5821 }
5822
5823 if (!c.uvs2.empty()) {
5824
5825 glEnableVertexAttribArray(VS::ARRAY_TEX_UV2);
5826 glVertexAttribPointer(VS::ARRAY_TEX_UV2, 2, GL_FLOAT, false, sizeof(Vector2), c.uvs2.ptr());
5827
5828 } else {
5829
5830 glDisableVertexAttribArray(VS::ARRAY_TEX_UV2);
5831 }
5832
5833 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
5834 glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, sizeof(Vector3), c.vertices.ptr());
5835 glDrawArrays(gl_primitive[c.primitive], 0, c.vertices.size());
5836 }
5837
5838 if (restore_tex) {
5839
5840 glActiveTexture(GL_TEXTURE0 + tc0_idx);
5841 glBindTexture(GL_TEXTURE_2D, tc0_id_cache);
5842 restore_tex = false;
5843 }
5844
5845 } break;
5846 case Geometry::GEOMETRY_PARTICLES: {
5847
5848 //print_line("particulinas");
5849 const Particles *particles = static_cast<const Particles *>(p_geometry);
5850 ERR_FAIL_COND(!p_owner);
5851 ParticlesInstance *particles_instance = (ParticlesInstance *)p_owner;
5852
5853 ParticleSystemProcessSW &pp = particles_instance->particles_process;
5854 float td = time_delta; //MIN(time_delta,1.0/10.0);
5855 pp.process(&particles->data, particles_instance->transform, td);
5856 ERR_EXPLAIN("A parameter in the particle system is not correct.");
5857 ERR_FAIL_COND(!pp.valid);
5858
5859 Transform camera;
5860 if (shadow)
5861 camera = shadow->transform;
5862 else
5863 camera = camera_transform;
5864
5865 particle_draw_info.prepare(&particles->data, &pp, particles_instance->transform, camera);
5866 _rinfo.draw_calls += particles->data.amount;
5867
5868 _rinfo.vertex_count += 4 * particles->data.amount;
5869
5870 {
5871 static const Vector3 points[4] = {
5872 Vector3(-1.0, 1.0, 0),
5873 Vector3(1.0, 1.0, 0),
5874 Vector3(1.0, -1.0, 0),
5875 Vector3(-1.0, -1.0, 0)
5876 };
5877 static const Vector3 uvs[4] = {
5878 Vector3(0.0, 0.0, 0.0),
5879 Vector3(1.0, 0.0, 0.0),
5880 Vector3(1.0, 1.0, 0.0),
5881 Vector3(0, 1.0, 0.0)
5882 };
5883 static const Vector3 normals[4] = {
5884 Vector3(0, 0, 1),
5885 Vector3(0, 0, 1),
5886 Vector3(0, 0, 1),
5887 Vector3(0, 0, 1)
5888 };
5889
5890 static const Plane tangents[4] = {
5891 Plane(Vector3(1, 0, 0), 0),
5892 Plane(Vector3(1, 0, 0), 0),
5893 Plane(Vector3(1, 0, 0), 0),
5894 Plane(Vector3(1, 0, 0), 0)
5895 };
5896
5897 for (int i = 0; i < particles->data.amount; i++) {
5898
5899 ParticleSystemDrawInfoSW::ParticleDrawInfo &pinfo = *particle_draw_info.draw_info_order[i];
5900 if (!pinfo.data->active)
5901 continue;
5902
5903 material_shader.set_uniform(MaterialShaderGLES2::WORLD_TRANSFORM, pinfo.transform);
5904 _set_color_attrib(pinfo.color);
5905 _draw_primitive(4, points, normals, NULL, uvs, tangents);
5906 }
5907 }
5908
5909 } break;
5910 default: break;
5911 };
5912 };
5913
_setup_shader_params(const Material * p_material)5914 void RasterizerGLES2::_setup_shader_params(const Material *p_material) {
5915
5916 #if 0
5917 int idx=0;
5918 int tex_idx=0;
5919 for(Map<StringName,Variant>::Element *E=p_material->shader_cache->params.front();E;E=E->next(),idx++) {
5920
5921 Variant v; //
5922 v = E->get();
5923 const Map<StringName,Variant>::Element *F=p_material->shader_params.find(E->key());
5924 if (F)
5925 v=F->get();
5926
5927 switch(v.get_type() ) {
5928 case Variant::OBJECT:
5929 case Variant::_RID: {
5930
5931 RID tex=v;
5932 if (!tex.is_valid())
5933 break;
5934
5935 Texture *texture = texture_owner.get(tex);
5936 if (!texture)
5937 break;
5938 glUniform1i( material_shader.get_custom_uniform_location(idx), tex_idx);
5939 glActiveTexture(tex_idx);
5940 glBindTexture(texture->target,texture->tex_id);
5941
5942 } break;
5943 case Variant::COLOR: {
5944
5945 Color c=v;
5946 material_shader.set_custom_uniform(idx,Vector3(c.r,c.g,c.b));
5947 } break;
5948 default: {
5949
5950 material_shader.set_custom_uniform(idx,v);
5951 } break;
5952 }
5953
5954 }
5955 #endif
5956 }
5957
_setup_skeleton(const Skeleton * p_skeleton)5958 void RasterizerGLES2::_setup_skeleton(const Skeleton *p_skeleton) {
5959
5960 material_shader.set_conditional(MaterialShaderGLES2::USE_SKELETON, p_skeleton != NULL);
5961 if (p_skeleton && p_skeleton->tex_id) {
5962
5963 glActiveTexture(GL_TEXTURE0 + max_texture_units - 2);
5964 glBindTexture(GL_TEXTURE_2D, p_skeleton->tex_id);
5965 }
5966 }
5967
_render_list_forward(RenderList * p_render_list,const Transform & p_view_transform,const Transform & p_view_transform_inverse,const CameraMatrix & p_projection,bool p_reverse_cull,bool p_fragment_light,bool p_alpha_pass)5968 void RasterizerGLES2::_render_list_forward(RenderList *p_render_list, const Transform &p_view_transform, const Transform &p_view_transform_inverse, const CameraMatrix &p_projection, bool p_reverse_cull, bool p_fragment_light, bool p_alpha_pass) {
5969
5970 if (current_rt && current_rt_vflip) {
5971 //p_reverse_cull=!p_reverse_cull;
5972 glFrontFace(GL_CCW);
5973 }
5974
5975 const Material *prev_material = NULL;
5976 uint16_t prev_light = 0x777E;
5977 const Geometry *prev_geometry_cmp = NULL;
5978 uint8_t prev_light_type = 0xEF;
5979 const Skeleton *prev_skeleton = NULL;
5980 uint8_t prev_sort_flags = 0xFF;
5981 const BakedLightData *prev_baked_light = NULL;
5982 RID prev_baked_light_texture;
5983 const float *prev_morph_values = NULL;
5984 int prev_receive_shadows_state = -1;
5985 int prev_unshaded_state = -1;
5986
5987 material_shader.set_conditional(MaterialShaderGLES2::USE_VERTEX_LIGHTING, !shadow && !p_fragment_light);
5988 material_shader.set_conditional(MaterialShaderGLES2::USE_FRAGMENT_LIGHTING, !shadow && p_fragment_light);
5989 material_shader.set_conditional(MaterialShaderGLES2::USE_SKELETON, false);
5990
5991 if (shadow) {
5992 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_DIRECTIONAL, false);
5993 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_OMNI, false);
5994 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT, false);
5995 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW, false);
5996 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM, false);
5997 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4, false);
5998 material_shader.set_conditional(MaterialShaderGLES2::SHADELESS, false);
5999 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE, false);
6000 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP, false);
6001 // material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_TEXTURE,false);
6002 }
6003
6004 bool stores_glow = !shadow && (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) && !p_alpha_pass;
6005 float sampled_light_dp_multiplier = 1.0;
6006
6007 bool prev_blend = false;
6008 glDisable(GL_BLEND);
6009 for (int i = 0; i < p_render_list->element_count; i++) {
6010
6011 RenderList::Element *e = p_render_list->elements[i];
6012 const Material *material = e->material;
6013 uint16_t light = e->light;
6014 uint8_t light_type = e->light_type;
6015 uint8_t sort_flags = e->sort_flags;
6016 const Skeleton *skeleton = e->skeleton;
6017 const Geometry *geometry_cmp = e->geometry_cmp;
6018 const BakedLightData *baked_light = e->instance->baked_light;
6019 const float *morph_values = e->instance->morph_values.ptr();
6020 int receive_shadows_state = e->instance->receive_shadows == true ? 1 : 0;
6021 int unshaded_state = (material->flags[VS::MATERIAL_FLAG_UNSHADED] || current_debug == VS::SCENARIO_DEBUG_SHADELESS) ? 1 : 0;
6022
6023 bool rebind = false;
6024 bool bind_baked_light_octree = false;
6025 bool bind_baked_lightmap = false;
6026 bool additive = false;
6027 bool bind_dp_sampler = false;
6028
6029 if (!shadow) {
6030
6031 if (texscreen_used && !texscreen_copied && material->shader_cache && material->shader_cache->valid && material->shader_cache->has_texscreen) {
6032 texscreen_copied = true;
6033 _copy_to_texscreen();
6034
6035 //force reset state
6036 prev_material = NULL;
6037 prev_light = 0x777E;
6038 prev_geometry_cmp = NULL;
6039 prev_light_type = 0xEF;
6040 prev_skeleton = NULL;
6041 prev_sort_flags = 0xFF;
6042 prev_morph_values = NULL;
6043 prev_receive_shadows_state = -1;
6044 prev_unshaded_state = -1;
6045 glEnable(GL_BLEND);
6046 glDepthMask(GL_TRUE);
6047 glEnable(GL_DEPTH_TEST);
6048 glDisable(GL_SCISSOR_TEST);
6049 }
6050
6051 if (light_type != prev_light_type || receive_shadows_state != prev_receive_shadows_state || unshaded_state != prev_unshaded_state) {
6052
6053 if (unshaded_state == 1) {
6054 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_DIRECTIONAL, false);
6055 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_OMNI, false);
6056 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT, false);
6057 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW, false);
6058 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM, false);
6059 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4, false);
6060 material_shader.set_conditional(MaterialShaderGLES2::SHADELESS, true);
6061 } else {
6062 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_DIRECTIONAL, (light_type & 0x3) == VS::LIGHT_DIRECTIONAL);
6063 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_OMNI, (light_type & 0x3) == VS::LIGHT_OMNI);
6064 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT, (light_type & 0x3) == VS::LIGHT_SPOT);
6065 if (receive_shadows_state == 1) {
6066 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW, (light_type & 0x8));
6067 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM, (light_type & 0x10));
6068 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4, (light_type & 0x20));
6069 } else {
6070 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW, false);
6071 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM, false);
6072 material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4, false);
6073 }
6074 material_shader.set_conditional(MaterialShaderGLES2::SHADELESS, false);
6075 }
6076
6077 rebind = true;
6078 }
6079
6080 if (!*e->additive_ptr) {
6081
6082 additive = false;
6083 *e->additive_ptr = true;
6084 } else {
6085 additive = true;
6086 }
6087
6088 if (stores_glow)
6089 material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW, !additive);
6090
6091 bool desired_blend = false;
6092 VS::MaterialBlendMode desired_blend_mode = VS::MATERIAL_BLEND_MODE_MIX;
6093
6094 if (additive) {
6095 desired_blend = true;
6096 desired_blend_mode = VS::MATERIAL_BLEND_MODE_ADD;
6097 } else {
6098 desired_blend = p_alpha_pass;
6099 desired_blend_mode = material->blend_mode;
6100 }
6101
6102 if (prev_blend != desired_blend) {
6103
6104 if (desired_blend) {
6105 glEnable(GL_BLEND);
6106 if (!current_rt || !current_rt_transparent)
6107 glColorMask(1, 1, 1, 0);
6108 } else {
6109 glDisable(GL_BLEND);
6110 glColorMask(1, 1, 1, 1);
6111 }
6112
6113 prev_blend = desired_blend;
6114 }
6115
6116 if (desired_blend && desired_blend_mode != current_blend_mode) {
6117
6118 switch (desired_blend_mode) {
6119
6120 case VS::MATERIAL_BLEND_MODE_MIX: {
6121 glBlendEquation(GL_FUNC_ADD);
6122 if (current_rt && current_rt_transparent) {
6123 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
6124 } else {
6125 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6126 }
6127
6128 } break;
6129 case VS::MATERIAL_BLEND_MODE_ADD: {
6130
6131 glBlendEquation(GL_FUNC_ADD);
6132 glBlendFunc(p_alpha_pass ? GL_SRC_ALPHA : GL_ONE, GL_ONE);
6133
6134 } break;
6135 case VS::MATERIAL_BLEND_MODE_SUB: {
6136
6137 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
6138 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
6139 } break;
6140 case VS::MATERIAL_BLEND_MODE_MUL: {
6141 glBlendEquation(GL_FUNC_ADD);
6142 if (current_rt && current_rt_transparent) {
6143 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
6144 } else {
6145 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6146 }
6147
6148 } break;
6149 }
6150
6151 current_blend_mode = desired_blend_mode;
6152 }
6153
6154 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE, false);
6155 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP, false);
6156 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_DP_SAMPLER, false);
6157
6158 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_COLOR, false);
6159
6160 if (material->flags[VS::MATERIAL_FLAG_UNSHADED] == false && current_debug != VS::SCENARIO_DEBUG_SHADELESS) {
6161
6162 if (baked_light != NULL) {
6163 if (baked_light->realtime_color_enabled) {
6164 float realtime_energy = baked_light->realtime_energy;
6165 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_COLOR, true);
6166 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_COLOR, Vector3(baked_light->realtime_color.r * realtime_energy, baked_light->realtime_color.g * realtime_energy, baked_light->realtime_color.b * realtime_energy));
6167 }
6168 }
6169
6170 if (e->instance->sampled_light.is_valid()) {
6171
6172 SampledLight *sl = sampled_light_owner.get(e->instance->sampled_light);
6173 if (sl) {
6174
6175 baked_light = NULL; //can't mix
6176 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_DP_SAMPLER, true);
6177 glActiveTexture(GL_TEXTURE0 + max_texture_units - 3);
6178 glBindTexture(GL_TEXTURE_2D, sl->texture); //bind the texture
6179 sampled_light_dp_multiplier = sl->multiplier;
6180 bind_dp_sampler = true;
6181 }
6182 }
6183
6184 if (!additive && baked_light) {
6185
6186 if (baked_light->mode == VS::BAKED_LIGHT_OCTREE && baked_light->octree_texture.is_valid() && e->instance->baked_light_octree_xform) {
6187 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_OCTREE, true);
6188 bind_baked_light_octree = true;
6189 if (prev_baked_light != baked_light) {
6190 Texture *tex = texture_owner.get(baked_light->octree_texture);
6191 if (tex) {
6192
6193 glActiveTexture(GL_TEXTURE0 + max_texture_units - 3);
6194 glBindTexture(tex->target, tex->tex_id); //bind the texture
6195 }
6196 if (baked_light->light_texture.is_valid()) {
6197 Texture *texl = texture_owner.get(baked_light->light_texture);
6198 if (texl) {
6199 glActiveTexture(GL_TEXTURE0 + max_texture_units - 4);
6200 glBindTexture(texl->target, texl->tex_id); //bind the light texture
6201 }
6202 }
6203 }
6204 } else if (baked_light->mode == VS::BAKED_LIGHT_LIGHTMAPS) {
6205
6206 int lightmap_idx = e->instance->baked_lightmap_id;
6207
6208 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP, false);
6209 bind_baked_lightmap = false;
6210
6211 if (baked_light->lightmaps.has(lightmap_idx)) {
6212
6213 RID texid = baked_light->lightmaps[lightmap_idx];
6214
6215 if (prev_baked_light != baked_light || texid != prev_baked_light_texture) {
6216
6217 Texture *tex = texture_owner.get(texid);
6218 if (tex) {
6219
6220 glActiveTexture(GL_TEXTURE0 + max_texture_units - 3);
6221 glBindTexture(tex->target, tex->tex_id); //bind the texture
6222 }
6223
6224 prev_baked_light_texture = texid;
6225 }
6226
6227 if (texid.is_valid()) {
6228 material_shader.set_conditional(MaterialShaderGLES2::ENABLE_AMBIENT_LIGHTMAP, true);
6229 bind_baked_lightmap = true;
6230 }
6231 }
6232 }
6233 }
6234
6235 if (int(prev_baked_light != NULL) ^ int(baked_light != NULL)) {
6236 rebind = true;
6237 }
6238 }
6239 }
6240
6241 if (sort_flags != prev_sort_flags) {
6242
6243 if (sort_flags & RenderList::SORT_FLAG_INSTANCING) {
6244 material_shader.set_conditional(MaterialShaderGLES2::USE_UNIFORM_INSTANCING, !use_texture_instancing && !use_attribute_instancing);
6245 material_shader.set_conditional(MaterialShaderGLES2::USE_ATTRIBUTE_INSTANCING, use_attribute_instancing);
6246 material_shader.set_conditional(MaterialShaderGLES2::USE_TEXTURE_INSTANCING, use_texture_instancing);
6247 } else {
6248 material_shader.set_conditional(MaterialShaderGLES2::USE_UNIFORM_INSTANCING, false);
6249 material_shader.set_conditional(MaterialShaderGLES2::USE_ATTRIBUTE_INSTANCING, false);
6250 material_shader.set_conditional(MaterialShaderGLES2::USE_TEXTURE_INSTANCING, false);
6251 }
6252 rebind = true;
6253 }
6254
6255 if (use_hw_skeleton_xform && (skeleton != prev_skeleton || morph_values != prev_morph_values)) {
6256 if (!prev_skeleton || !skeleton)
6257 rebind = true; //went from skeleton <-> no skeleton, needs rebind
6258
6259 if (morph_values == NULL)
6260 _setup_skeleton(skeleton);
6261 else
6262 _setup_skeleton(NULL);
6263 }
6264
6265 if (material != prev_material || rebind) {
6266
6267 rebind = _setup_material(e->geometry, material, additive, !p_alpha_pass);
6268
6269 DEBUG_TEST_ERROR("Setup material");
6270 _rinfo.mat_change_count++;
6271 //_setup_material_overrides(e->material,NULL,material_overrides);
6272 //_setup_material_skeleton(material,skeleton);
6273 } else {
6274
6275 if (prev_skeleton != skeleton) {
6276 //_setup_material_skeleton(material,skeleton);
6277 };
6278 }
6279
6280 if (geometry_cmp != prev_geometry_cmp || prev_skeleton != skeleton) {
6281
6282 _setup_geometry(e->geometry, material, e->skeleton, e->instance->morph_values.ptr());
6283 _rinfo.surface_count++;
6284 DEBUG_TEST_ERROR("Setup geometry");
6285 };
6286
6287 if (i == 0 || light != prev_light || rebind) {
6288 if (e->light != 0xFFFF) {
6289 _setup_light(e->light);
6290 }
6291 }
6292
6293 if (bind_baked_light_octree && (baked_light != prev_baked_light || rebind)) {
6294
6295 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_INVERSE_TRANSFORM, *e->instance->baked_light_octree_xform);
6296 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LATTICE_SIZE, baked_light->octree_lattice_size);
6297 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LATTICE_DIVIDE, baked_light->octree_lattice_divide);
6298 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_STEPS, baked_light->octree_steps);
6299 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_TEX, max_texture_units - 3);
6300 if (baked_light->light_texture.is_valid()) {
6301
6302 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_TEX, max_texture_units - 4);
6303 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_PIX_SIZE, baked_light->light_tex_pixel_size);
6304 } else {
6305 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_TEX, max_texture_units - 3);
6306 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_LIGHT_PIX_SIZE, baked_light->octree_tex_pixel_size);
6307 }
6308 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_MULTIPLIER, baked_light->texture_multiplier);
6309 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_OCTREE_PIX_SIZE, baked_light->octree_tex_pixel_size);
6310 }
6311
6312 if (bind_baked_lightmap && (baked_light != prev_baked_light || rebind)) {
6313
6314 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHTMAP, max_texture_units - 3);
6315 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHTMAP_MULTIPLIER, baked_light->lightmap_multiplier);
6316 }
6317
6318 if (bind_dp_sampler) {
6319
6320 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_DP_SAMPLER_MULTIPLIER, sampled_light_dp_multiplier);
6321 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_DP_SAMPLER, max_texture_units - 3);
6322 }
6323
6324 _set_cull(e->mirror, p_reverse_cull);
6325
6326 if (i == 0 || rebind) {
6327 material_shader.set_uniform(MaterialShaderGLES2::CAMERA_INVERSE_TRANSFORM, p_view_transform_inverse);
6328 material_shader.set_uniform(MaterialShaderGLES2::PROJECTION_TRANSFORM, p_projection);
6329 if (!shadow) {
6330
6331 if (!additive && current_env && current_env->fx_enabled[VS::ENV_FX_AMBIENT_LIGHT]) {
6332 Color ambcolor = _convert_color(current_env->fx_param[VS::ENV_FX_PARAM_AMBIENT_LIGHT_COLOR]);
6333 float ambnrg = current_env->fx_param[VS::ENV_FX_PARAM_AMBIENT_LIGHT_ENERGY];
6334 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHT, Vector3(ambcolor.r * ambnrg, ambcolor.g * ambnrg, ambcolor.b * ambnrg));
6335 } else {
6336 material_shader.set_uniform(MaterialShaderGLES2::AMBIENT_LIGHT, Vector3());
6337 }
6338 }
6339
6340 _rinfo.shader_change_count++;
6341 }
6342
6343 if (skeleton != prev_skeleton || rebind) {
6344 if (skeleton && morph_values == NULL) {
6345 material_shader.set_uniform(MaterialShaderGLES2::SKELETON_MATRICES, max_texture_units - 2);
6346 material_shader.set_uniform(MaterialShaderGLES2::SKELTEX_PIXEL_SIZE, skeleton->pixel_size);
6347 }
6348 }
6349
6350 if (e->instance->billboard || e->instance->depth_scale) {
6351
6352 Transform xf = e->instance->transform;
6353 if (e->instance->depth_scale) {
6354
6355 if (p_projection.matrix[3][3]) {
6356 //orthogonal matrix, try to do about the same
6357 //with viewport size
6358 //real_t w = Math::abs( 1.0/(2.0*(p_projection.matrix[0][0])) );
6359 real_t h = Math::abs(1.0 / (2.0 * p_projection.matrix[1][1]));
6360 float sc = (h * 2.0); //consistent with Y-fov
6361 xf.basis.scale(Vector3(sc, sc, sc));
6362 } else {
6363 //just scale by depth
6364 real_t sc = -camera_plane.distance_to(xf.origin);
6365 xf.basis.scale(Vector3(sc, sc, sc));
6366 }
6367 }
6368
6369 if (e->instance->billboard) {
6370
6371 Vector3 scale = xf.basis.get_scale();
6372
6373 if (current_rt && current_rt_vflip) {
6374 xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), -p_view_transform.get_basis().get_axis(1));
6375 } else {
6376 xf.set_look_at(xf.origin, xf.origin + p_view_transform.get_basis().get_axis(2), p_view_transform.get_basis().get_axis(1));
6377 }
6378
6379 xf.basis.scale(scale);
6380 }
6381 material_shader.set_uniform(MaterialShaderGLES2::WORLD_TRANSFORM, xf);
6382
6383 } else {
6384 material_shader.set_uniform(MaterialShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
6385 }
6386
6387 material_shader.set_uniform(MaterialShaderGLES2::NORMAL_MULT, e->mirror ? -1.0 : 1.0);
6388 material_shader.set_uniform(MaterialShaderGLES2::CONST_LIGHT_MULT, additive ? 0.0 : 1.0);
6389
6390 _render(e->geometry, material, skeleton, e->owner, e->instance->transform);
6391 DEBUG_TEST_ERROR("Rendering");
6392
6393 prev_material = material;
6394 prev_skeleton = skeleton;
6395 prev_geometry_cmp = geometry_cmp;
6396 prev_light = e->light;
6397 prev_light_type = e->light_type;
6398 prev_sort_flags = sort_flags;
6399 prev_baked_light = baked_light;
6400 prev_morph_values = morph_values;
6401 prev_receive_shadows_state = receive_shadows_state;
6402 prev_unshaded_state = unshaded_state;
6403 }
6404
6405 //print_line("shaderchanges: "+itos(p_alpha_pass)+": "+itos(_rinfo.shader_change_count));
6406
6407 if (current_rt && current_rt_vflip) {
6408 glFrontFace(GL_CW);
6409 }
6410 };
6411
_copy_to_texscreen()6412 void RasterizerGLES2::_copy_to_texscreen() {
6413
6414 //what am i missing?
6415 glDisable(GL_CULL_FACE);
6416 glDisable(GL_DEPTH_TEST);
6417 glDisable(GL_SCISSOR_TEST);
6418 #ifdef GLEW_ENABLED
6419 glDisable(GL_POINT_SPRITE);
6420 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
6421 #endif
6422 glDisable(GL_BLEND);
6423 glBlendEquation(GL_FUNC_ADD);
6424 if (current_rt && current_rt_transparent) {
6425 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
6426 } else {
6427 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6428 }
6429 //glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
6430 glBindBuffer(GL_ARRAY_BUFFER, 0);
6431 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6432
6433 for (int i = 0; i < VS::ARRAY_MAX; i++) {
6434 glDisableVertexAttribArray(i);
6435 }
6436
6437 glActiveTexture(GL_TEXTURE0);
6438
6439 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.sample_fbo);
6440 glActiveTexture(GL_TEXTURE0);
6441 glBindTexture(GL_TEXTURE_2D, framebuffer.color);
6442 copy_shader.bind();
6443 _copy_screen_quad();
6444 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.fbo);
6445 }
6446
_copy_screen_quad()6447 void RasterizerGLES2::_copy_screen_quad() {
6448
6449 Vector2 dst_pos[4] = {
6450 Vector2(-1, 1),
6451 Vector2(1, 1),
6452 Vector2(1, -1),
6453 Vector2(-1, -1)
6454 };
6455
6456 Size2 uvscale(
6457 (viewport.width / float(framebuffer.scale)) / framebuffer.width,
6458 (viewport.height / float(framebuffer.scale)) / framebuffer.height);
6459
6460 Vector2 src_uv[4] = {
6461 Vector2(0, 1) * uvscale,
6462 Vector2(1, 1) * uvscale,
6463 Vector2(1, 0) * uvscale,
6464 Vector2(0, 0) * uvscale
6465 };
6466
6467 Vector2 full_uv[4] = {
6468 Vector2(0, 1),
6469 Vector2(1, 1),
6470 Vector2(1, 0),
6471 Vector2(0, 0)
6472 };
6473
6474 _draw_gui_primitive2(4, dst_pos, NULL, src_uv, full_uv);
6475 }
6476
_process_glow_bloom()6477 void RasterizerGLES2::_process_glow_bloom() {
6478
6479 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.blur[0].fbo);
6480 glActiveTexture(GL_TEXTURE0);
6481 glBindTexture(GL_TEXTURE_2D, framebuffer.color);
6482 copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_COPY, true);
6483 if (current_vd && current_env->fx_enabled[VS::ENV_FX_HDR]) {
6484
6485 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR, true);
6486 }
6487
6488 copy_shader.bind();
6489 copy_shader.set_uniform(CopyShaderGLES2::BLOOM, float(current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM]));
6490 copy_shader.set_uniform(CopyShaderGLES2::BLOOM_TRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLOOM_TRESHOLD]));
6491 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0);
6492
6493 if (current_vd && current_env->fx_enabled[VS::ENV_FX_HDR]) {
6494 glActiveTexture(GL_TEXTURE2);
6495 glBindTexture(GL_TEXTURE_2D, current_vd->lum_color);
6496 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::HDR_SOURCE), 2);
6497 copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_EXPOSURE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE]));
6498 copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_WHITE]));
6499 // copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE,1.0);
6500 copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_TRESHOLD, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_TRESHOLD]));
6501 copy_shader.set_uniform(CopyShaderGLES2::HDR_GLOW_SCALE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_GLOW_SCALE]));
6502
6503 glActiveTexture(GL_TEXTURE0);
6504 }
6505
6506 glViewport(0, 0, framebuffer.blur_size, framebuffer.blur_size);
6507 _copy_screen_quad();
6508
6509 copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_COPY, false);
6510 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR, false);
6511 int passes = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_PASSES];
6512 Vector2 psize(1.0 / framebuffer.blur_size, 1.0 / framebuffer.blur_size);
6513 float pscale = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_SCALE];
6514 float pmag = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_STRENGTH];
6515
6516 for (int i = 0; i < passes; i++) {
6517
6518 static const Vector2 src_uv[4] = {
6519 Vector2(0, 1),
6520 Vector2(1, 1),
6521 Vector2(1, 0),
6522 Vector2(0, 0)
6523 };
6524 static const Vector2 dst_pos[4] = {
6525 Vector2(-1, 1),
6526 Vector2(1, 1),
6527 Vector2(1, -1),
6528 Vector2(-1, -1)
6529 };
6530
6531 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.blur[1].fbo);
6532 glBindTexture(GL_TEXTURE_2D, framebuffer.blur[0].color);
6533 copy_shader.set_conditional(CopyShaderGLES2::BLUR_V_PASS, true);
6534 copy_shader.set_conditional(CopyShaderGLES2::BLUR_H_PASS, false);
6535 copy_shader.bind();
6536 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE, psize);
6537 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SCALE, pscale);
6538 copy_shader.set_uniform(CopyShaderGLES2::BLUR_MAGNITUDE, pmag);
6539
6540 _draw_gui_primitive(4, dst_pos, NULL, src_uv);
6541
6542 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.blur[0].fbo);
6543 glBindTexture(GL_TEXTURE_2D, framebuffer.blur[1].color);
6544 copy_shader.set_conditional(CopyShaderGLES2::BLUR_V_PASS, false);
6545 copy_shader.set_conditional(CopyShaderGLES2::BLUR_H_PASS, true);
6546 copy_shader.bind();
6547 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE, psize);
6548 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SCALE, pscale);
6549 copy_shader.set_uniform(CopyShaderGLES2::BLUR_MAGNITUDE, pmag);
6550
6551 _draw_gui_primitive(4, dst_pos, NULL, src_uv);
6552 }
6553
6554 copy_shader.set_conditional(CopyShaderGLES2::BLUR_V_PASS, false);
6555 copy_shader.set_conditional(CopyShaderGLES2::BLUR_H_PASS, false);
6556 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR, false);
6557
6558 //blur it
6559 }
6560
_process_hdr()6561 void RasterizerGLES2::_process_hdr() {
6562
6563 if (framebuffer.luminance.empty()) {
6564 return;
6565 }
6566
6567 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.luminance[0].fbo);
6568 glActiveTexture(GL_TEXTURE0);
6569 glBindTexture(GL_TEXTURE_2D, framebuffer.color);
6570 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR_COPY, true);
6571 copy_shader.bind();
6572 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0);
6573 glViewport(0, 0, framebuffer.luminance[0].size, framebuffer.luminance[0].size);
6574 _copy_screen_quad();
6575
6576 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR_COPY, false);
6577 // int passes = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_PASSES];
6578
6579 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR_REDUCE, true);
6580 copy_shader.bind();
6581
6582 for (int i = 1; i < framebuffer.luminance.size(); i++) {
6583
6584 static const Vector2 src_uv[4] = {
6585 Vector2(0, 1),
6586 Vector2(1, 1),
6587 Vector2(1, 0),
6588 Vector2(0, 0)
6589 };
6590 static const Vector2 dst_pos[4] = {
6591 Vector2(-1, 1),
6592 Vector2(1, 1),
6593 Vector2(1, -1),
6594 Vector2(-1, -1)
6595 };
6596
6597 Vector2 psize(1.0 / framebuffer.luminance[i - 1].size, 1.0 / framebuffer.luminance[i - 1].size);
6598 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.luminance[i].fbo);
6599 glBindTexture(GL_TEXTURE_2D, framebuffer.luminance[i - 1].color);
6600 glViewport(0, 0, framebuffer.luminance[i].size, framebuffer.luminance[i].size);
6601 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0);
6602
6603 if (framebuffer.luminance[i].size == 1) {
6604 //last step
6605 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR_STORE, true);
6606 copy_shader.bind();
6607 glActiveTexture(GL_TEXTURE1);
6608 glBindTexture(GL_TEXTURE_2D, current_vd->lum_color);
6609 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE_VD_LUM), 1);
6610 copy_shader.set_uniform(CopyShaderGLES2::HDR_TIME_DELTA, time_delta);
6611 copy_shader.set_uniform(CopyShaderGLES2::HDR_EXP_ADJ_SPEED, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE_ADJUST_SPEED]));
6612 copy_shader.set_uniform(CopyShaderGLES2::MIN_LUMINANCE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_MIN_LUMINANCE]));
6613 copy_shader.set_uniform(CopyShaderGLES2::MAX_LUMINANCE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_MAX_LUMINANCE]));
6614 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0);
6615
6616 //swap them
6617 SWAP(current_vd->lum_color, framebuffer.luminance[i].color);
6618 SWAP(current_vd->lum_fbo, framebuffer.luminance[i].fbo);
6619 }
6620
6621 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE, psize);
6622
6623 _draw_gui_primitive(4, dst_pos, NULL, src_uv);
6624 }
6625
6626 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR_REDUCE, false);
6627 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR_STORE, false);
6628
6629 draw_next_frame = true;
6630 }
6631
_draw_tex_bg()6632 void RasterizerGLES2::_draw_tex_bg() {
6633
6634 glDepthMask(GL_TRUE);
6635 glEnable(GL_DEPTH_TEST);
6636 glDisable(GL_CULL_FACE);
6637 glDisable(GL_BLEND);
6638 glColorMask(1, 1, 1, 1);
6639
6640 RID texture;
6641
6642 if (current_env->bg_mode == VS::ENV_BG_TEXTURE) {
6643 texture = current_env->bg_param[VS::ENV_BG_PARAM_TEXTURE];
6644 } else {
6645 texture = current_env->bg_param[VS::ENV_BG_PARAM_CUBEMAP];
6646 }
6647
6648 if (!texture_owner.owns(texture)) {
6649 return;
6650 }
6651
6652 Texture *t = texture_owner.get(texture);
6653
6654 glActiveTexture(GL_TEXTURE0);
6655 glBindTexture(t->target, t->tex_id);
6656
6657 copy_shader.set_conditional(CopyShaderGLES2::USE_ENERGY, true);
6658
6659 if (current_env->bg_mode == VS::ENV_BG_TEXTURE) {
6660 copy_shader.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false);
6661
6662 } else {
6663 copy_shader.set_conditional(CopyShaderGLES2::USE_CUBEMAP, true);
6664 }
6665
6666 copy_shader.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA, true);
6667
6668 copy_shader.bind();
6669
6670 if (current_env->bg_mode == VS::ENV_BG_TEXTURE) {
6671 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0);
6672 } else {
6673 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE_CUBE), 0);
6674 }
6675
6676 float nrg = float(current_env->bg_param[VS::ENV_BG_PARAM_ENERGY]);
6677 if (current_env->fx_enabled[VS::ENV_FX_HDR] && !use_fp16_fb)
6678 nrg *= 0.25; //go down a quarter for hdr
6679 copy_shader.set_uniform(CopyShaderGLES2::ENERGY, nrg);
6680 copy_shader.set_uniform(CopyShaderGLES2::CUSTOM_ALPHA, float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW]));
6681
6682 float flip_sign = (current_env->bg_mode == VS::ENV_BG_TEXTURE && current_rt && current_rt_vflip) ? -1 : 1;
6683
6684 Vector3 vertices[4] = {
6685 Vector3(-1, -1 * flip_sign, 1),
6686 Vector3(1, -1 * flip_sign, 1),
6687 Vector3(1, 1 * flip_sign, 1),
6688 Vector3(-1, 1 * flip_sign, 1)
6689 };
6690
6691 Vector3 src_uv[4] = {
6692 Vector3(0, 1, 0),
6693 Vector3(1, 1, 0),
6694 Vector3(1, 0, 0),
6695 Vector3(0, 0, 0)
6696 };
6697
6698 if (current_env->bg_mode == VS::ENV_BG_TEXTURE) {
6699
6700 //regular texture
6701 //adjust aspect
6702
6703 float aspect_t = t->width / float(t->height);
6704 float aspect_v = viewport.width / float(viewport.height);
6705
6706 if (aspect_v > aspect_t) {
6707 //wider than texture
6708 for (int i = 0; i < 4; i++) {
6709 src_uv[i].y = (src_uv[i].y - 0.5) * (aspect_t / aspect_v) + 0.5;
6710 }
6711
6712 } else {
6713 //narrower than texture
6714 for (int i = 0; i < 4; i++) {
6715 src_uv[i].x = (src_uv[i].x - 0.5) * (aspect_v / aspect_t) + 0.5;
6716 }
6717 }
6718
6719 float scale = current_env->bg_param[VS::ENV_BG_PARAM_SCALE];
6720 for (int i = 0; i < 4; i++) {
6721
6722 src_uv[i].x *= scale;
6723 src_uv[i].y *= scale;
6724 }
6725 } else {
6726
6727 //skybox uv vectors
6728 float vw, vh, zn;
6729 camera_projection.get_viewport_size(vw, vh);
6730 zn = camera_projection.get_z_near();
6731
6732 float scale = current_env->bg_param[VS::ENV_BG_PARAM_SCALE];
6733
6734 for (int i = 0; i < 4; i++) {
6735
6736 Vector3 uv = src_uv[i];
6737 uv.x = (uv.x * 2.0 - 1.0) * vw * scale;
6738 uv.y = -(uv.y * 2.0 - 1.0) * vh * scale;
6739 uv.z = -zn;
6740 src_uv[i] = camera_transform.basis.xform(uv).normalized();
6741 src_uv[i].z = -src_uv[i].z;
6742 }
6743 }
6744
6745 _draw_primitive(4, vertices, NULL, NULL, src_uv);
6746
6747 copy_shader.set_conditional(CopyShaderGLES2::USE_ENERGY, false);
6748 copy_shader.set_conditional(CopyShaderGLES2::USE_RGBE, false);
6749 copy_shader.set_conditional(CopyShaderGLES2::USE_CUBEMAP, false);
6750 copy_shader.set_conditional(CopyShaderGLES2::USE_CUSTOM_ALPHA, false);
6751 }
6752
end_scene()6753 void RasterizerGLES2::end_scene() {
6754
6755 glEnable(GL_BLEND);
6756 glDepthMask(GL_TRUE);
6757 glEnable(GL_DEPTH_TEST);
6758 glDisable(GL_SCISSOR_TEST);
6759
6760 bool use_fb = false;
6761
6762 if (framebuffer.active) {
6763
6764 //detect when to use the framebuffer object
6765 if (using_canvas_bg || texscreen_used || framebuffer.scale != 1) {
6766 use_fb = true;
6767 } else if (current_env) {
6768 use_fb = false;
6769 for (int i = 0; i < VS::ENV_FX_MAX; i++) {
6770
6771 if (i == VS::ENV_FX_FOG) //does not need fb
6772 continue;
6773
6774 if (current_env->fx_enabled[i]) {
6775 use_fb = true;
6776 break;
6777 }
6778 }
6779 }
6780 }
6781
6782 if (use_fb) {
6783
6784 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.fbo);
6785 glViewport(0, 0, viewport.width / framebuffer.scale, viewport.height / framebuffer.scale);
6786 glScissor(0, 0, viewport.width / framebuffer.scale, viewport.height / framebuffer.scale);
6787
6788 material_shader.set_conditional(MaterialShaderGLES2::USE_8BIT_HDR, !use_fp16_fb && current_env && current_env->fx_enabled[VS::ENV_FX_HDR]);
6789
6790 } else {
6791 if (current_rt) {
6792 glScissor(0, 0, viewport.width, viewport.height);
6793 } else {
6794 glScissor(viewport.x, window_size.height - (viewport.height + viewport.y), viewport.width, viewport.height);
6795 }
6796 }
6797
6798 glEnable(GL_SCISSOR_TEST);
6799 _glClearDepth(1.0);
6800
6801 bool draw_tex_background = false;
6802
6803 if (current_debug == VS::SCENARIO_DEBUG_OVERDRAW) {
6804
6805 glClearColor(0, 0, 0, 1);
6806 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6807 } else if (current_rt && current_rt_transparent) {
6808
6809 glClearColor(0, 0, 0, 0);
6810 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6811
6812 } else if (current_env) {
6813
6814 switch (current_env->bg_mode) {
6815
6816 case VS::ENV_BG_CANVAS:
6817 case VS::ENV_BG_KEEP: {
6818 //copy from framebuffer if framebuffer
6819 glClear(GL_DEPTH_BUFFER_BIT);
6820 } break;
6821 case VS::ENV_BG_DEFAULT_COLOR:
6822 case VS::ENV_BG_COLOR: {
6823
6824 Color bgcolor;
6825 if (current_env->bg_mode == VS::ENV_BG_COLOR)
6826 bgcolor = current_env->bg_param[VS::ENV_BG_PARAM_COLOR];
6827 else
6828 bgcolor = Globals::get_singleton()->get("render/default_clear_color");
6829 bgcolor = _convert_color(bgcolor);
6830 float a = use_fb ? float(current_env->bg_param[VS::ENV_BG_PARAM_GLOW]) : 1.0;
6831 glClearColor(bgcolor.r, bgcolor.g, bgcolor.b, a);
6832 _glClearDepth(1.0);
6833 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6834
6835 } break;
6836 case VS::ENV_BG_TEXTURE:
6837 case VS::ENV_BG_CUBEMAP: {
6838
6839 glClear(GL_DEPTH_BUFFER_BIT);
6840 draw_tex_background = true;
6841 } break;
6842 }
6843 } else {
6844
6845 Color c = _convert_color(Color(0.3, 0.3, 0.3));
6846 glClearColor(c.r, c.g, c.b, 0.0);
6847 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6848 }
6849
6850 glDisable(GL_SCISSOR_TEST);
6851
6852 //material_shader.set_uniform_camera(MaterialShaderGLES2::PROJECTION_MATRIX, camera_projection);
6853
6854 /*
6855 printf("setting projection to ");
6856 for (int i=0; i<16; i++) {
6857 printf("%f, ", ((float*)camera_projection.matrix)[i]);
6858 };
6859 printf("\n");
6860
6861 print_line(String("setting camera to ")+camera_transform_inverse);
6862 */
6863 // material_shader.set_uniform_default(MaterialShaderGLES2::CAMERA_INVERSE, camera_transform_inverse);
6864
6865 current_depth_test = true;
6866 current_depth_mask = true;
6867 texscreen_copied = false;
6868 glBlendEquation(GL_FUNC_ADD);
6869 if (current_rt && current_rt_transparent) {
6870 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
6871 } else {
6872 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6873 }
6874 glDisable(GL_BLEND);
6875 current_blend_mode = VS::MATERIAL_BLEND_MODE_MIX;
6876
6877 //material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW,current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]);
6878 opaque_render_list.sort_mat_light_type_flags();
6879 _render_list_forward(&opaque_render_list, camera_transform, camera_transform_inverse, camera_projection, false, fragment_lighting);
6880
6881 if (draw_tex_background) {
6882
6883 //most 3D vendors recommend drawing a texture bg or skybox here,
6884 //after opaque geometry has been drawn
6885 //so the zbuffer can get rid of most pixels
6886 _draw_tex_bg();
6887 }
6888
6889 glBlendEquation(GL_FUNC_ADD);
6890 if (current_rt && current_rt_transparent) {
6891 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
6892 } else {
6893 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
6894 }
6895 glDisable(GL_BLEND);
6896 current_blend_mode = VS::MATERIAL_BLEND_MODE_MIX;
6897 material_shader.set_conditional(MaterialShaderGLES2::USE_GLOW, false);
6898 if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) {
6899 glColorMask(1, 1, 1, 0); //don't touch alpha
6900 }
6901
6902 alpha_render_list.sort_z();
6903 _render_list_forward(&alpha_render_list, camera_transform, camera_transform_inverse, camera_projection, false, fragment_lighting, true);
6904 glColorMask(1, 1, 1, 1);
6905
6906 // material_shader.set_conditional( MaterialShaderGLES2::USE_FOG,false);
6907
6908 DEBUG_TEST_ERROR("Drawing Scene");
6909
6910 #ifdef GLEW_ENABLED
6911 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
6912 #endif
6913
6914 if (use_fb) {
6915
6916 for (int i = 0; i < VS::ARRAY_MAX; i++) {
6917 glDisableVertexAttribArray(i);
6918 }
6919 glBindBuffer(GL_ARRAY_BUFFER, 0);
6920 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6921 glDisable(GL_BLEND);
6922 glDisable(GL_DEPTH_TEST);
6923 glDisable(GL_CULL_FACE);
6924 glDisable(GL_SCISSOR_TEST);
6925 glDepthMask(false);
6926
6927 if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR]) {
6928
6929 int hdr_tm = current_env->fx_param[VS::ENV_FX_PARAM_HDR_TONEMAPPER];
6930 switch (hdr_tm) {
6931 case VS::ENV_FX_HDR_TONE_MAPPER_LINEAR: {
6932
6933 } break;
6934 case VS::ENV_FX_HDR_TONE_MAPPER_LOG: {
6935 copy_shader.set_conditional(CopyShaderGLES2::USE_LOG_TONEMAPPER, true);
6936
6937 } break;
6938 case VS::ENV_FX_HDR_TONE_MAPPER_REINHARDT: {
6939 copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER, true);
6940 } break;
6941 case VS::ENV_FX_HDR_TONE_MAPPER_REINHARDT_AUTOWHITE: {
6942
6943 copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER, true);
6944 copy_shader.set_conditional(CopyShaderGLES2::USE_AUTOWHITE, true);
6945 } break;
6946 }
6947
6948 _process_hdr();
6949 }
6950 if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) {
6951 _process_glow_bloom();
6952 int glow_transfer_mode = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE];
6953 if (glow_transfer_mode == 1)
6954 copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN, true);
6955 if (glow_transfer_mode == 2)
6956 copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT, true);
6957 }
6958
6959 glBindFramebuffer(GL_FRAMEBUFFER, current_rt ? current_rt->fbo : base_framebuffer);
6960
6961 Size2 size;
6962 if (current_rt) {
6963 glBindFramebuffer(GL_FRAMEBUFFER, current_rt->fbo);
6964 glViewport(0, 0, viewport.width, viewport.height);
6965 size = Size2(viewport.width, viewport.height);
6966 } else {
6967 glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
6968 glViewport(viewport.x, window_size.height - (viewport.height + viewport.y), viewport.width, viewport.height);
6969 size = Size2(viewport.width, viewport.height);
6970 }
6971
6972 //time to copy!!!
6973 copy_shader.set_conditional(CopyShaderGLES2::USE_BCS, current_env && current_env->fx_enabled[VS::ENV_FX_BCS]);
6974 copy_shader.set_conditional(CopyShaderGLES2::USE_SRGB, current_env && current_env->fx_enabled[VS::ENV_FX_SRGB]);
6975 copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW, current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]);
6976 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR, current_env && current_env->fx_enabled[VS::ENV_FX_HDR]);
6977 copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA, true);
6978 copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA, current_env && current_env->fx_enabled[VS::ENV_FX_FXAA]);
6979
6980 copy_shader.bind();
6981 //copy_shader.set_uniform(CopyShaderGLES2::SOURCE,0);
6982
6983 if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) {
6984
6985 glActiveTexture(GL_TEXTURE1);
6986 glBindTexture(GL_TEXTURE_2D, framebuffer.blur[0].color);
6987 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::GLOW_SOURCE), 1);
6988 }
6989
6990 if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR]) {
6991
6992 glActiveTexture(GL_TEXTURE2);
6993 glBindTexture(GL_TEXTURE_2D, current_vd->lum_color);
6994 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::HDR_SOURCE), 2);
6995 copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_EXPOSURE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE]));
6996 copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE, float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_WHITE]));
6997 }
6998
6999 if (current_env && current_env->fx_enabled[VS::ENV_FX_FXAA])
7000 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE, Size2(1.0 / size.x, 1.0 / size.y));
7001
7002 if (current_env && current_env->fx_enabled[VS::ENV_FX_BCS]) {
7003
7004 Vector3 bcs;
7005 bcs.x = current_env->fx_param[VS::ENV_FX_PARAM_BCS_BRIGHTNESS];
7006 bcs.y = current_env->fx_param[VS::ENV_FX_PARAM_BCS_CONTRAST];
7007 bcs.z = current_env->fx_param[VS::ENV_FX_PARAM_BCS_SATURATION];
7008 copy_shader.set_uniform(CopyShaderGLES2::BCS, bcs);
7009 }
7010
7011 glActiveTexture(GL_TEXTURE0);
7012 glBindTexture(GL_TEXTURE_2D, framebuffer.color);
7013 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0);
7014
7015 _copy_screen_quad();
7016
7017 copy_shader.set_conditional(CopyShaderGLES2::USE_BCS, false);
7018 copy_shader.set_conditional(CopyShaderGLES2::USE_SRGB, false);
7019 copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW, false);
7020 copy_shader.set_conditional(CopyShaderGLES2::USE_HDR, false);
7021 copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA, false);
7022 copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA, false);
7023 copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN, false);
7024 copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT, false);
7025 copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER, false);
7026 copy_shader.set_conditional(CopyShaderGLES2::USE_AUTOWHITE, false);
7027 copy_shader.set_conditional(CopyShaderGLES2::USE_LOG_TONEMAPPER, false);
7028
7029 material_shader.set_conditional(MaterialShaderGLES2::USE_8BIT_HDR, false);
7030
7031 if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR] && GLOBAL_DEF("rasterizer/debug_hdr", false)) {
7032 _debug_luminances();
7033 }
7034 }
7035
7036 current_env = NULL;
7037 current_debug = VS::SCENARIO_DEBUG_DISABLED;
7038 if (GLOBAL_DEF("rasterizer/debug_shadow_maps", false)) {
7039 _debug_shadows();
7040 }
7041 // _debug_luminances();
7042 // _debug_samplers();
7043
7044 if (using_canvas_bg) {
7045 using_canvas_bg = false;
7046 glColorMask(1, 1, 1, 1); //don't touch alpha
7047 }
7048 }
end_shadow_map()7049 void RasterizerGLES2::end_shadow_map() {
7050
7051 ERR_FAIL_COND(!shadow);
7052
7053 glDisable(GL_BLEND);
7054 glDisable(GL_SCISSOR_TEST);
7055 glDisable(GL_DITHER);
7056 glEnable(GL_DEPTH_TEST);
7057 glDepthMask(true);
7058
7059 ShadowBuffer *sb = shadow->near_shadow_buffer;
7060
7061 ERR_FAIL_COND(!sb);
7062
7063 glBindFramebuffer(GL_FRAMEBUFFER, sb->fbo);
7064
7065 if (!use_rgba_shadowmaps)
7066 glColorMask(0, 0, 0, 0);
7067
7068 //glEnable(GL_POLYGON_OFFSET_FILL);
7069 //glPolygonOffset( 8.0f, 16.0f);
7070
7071 CameraMatrix cm;
7072 float z_near, z_far;
7073 Transform light_transform;
7074
7075 float dp_direction = 0.0;
7076 bool flip_facing = false;
7077 Rect2 vp_rect;
7078
7079 switch (shadow->base->type) {
7080
7081 case VS::LIGHT_DIRECTIONAL: {
7082
7083 if (shadow->base->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
7084
7085 cm = shadow->custom_projection[shadow_pass];
7086 light_transform = shadow->custom_transform[shadow_pass];
7087
7088 if (shadow_pass == 0) {
7089
7090 vp_rect = Rect2(0, sb->size / 2, sb->size / 2, sb->size / 2);
7091 glViewport(0, sb->size / 2, sb->size / 2, sb->size / 2);
7092 glScissor(0, sb->size / 2, sb->size / 2, sb->size / 2);
7093 } else if (shadow_pass == 1) {
7094
7095 vp_rect = Rect2(0, 0, sb->size / 2, sb->size / 2);
7096 glViewport(0, 0, sb->size / 2, sb->size / 2);
7097 glScissor(0, 0, sb->size / 2, sb->size / 2);
7098
7099 } else if (shadow_pass == 2) {
7100
7101 vp_rect = Rect2(sb->size / 2, sb->size / 2, sb->size / 2, sb->size / 2);
7102 glViewport(sb->size / 2, sb->size / 2, sb->size / 2, sb->size / 2);
7103 glScissor(sb->size / 2, sb->size / 2, sb->size / 2, sb->size / 2);
7104 } else if (shadow_pass == 3) {
7105
7106 vp_rect = Rect2(sb->size / 2, 0, sb->size / 2, sb->size / 2);
7107 glViewport(sb->size / 2, 0, sb->size / 2, sb->size / 2);
7108 glScissor(sb->size / 2, 0, sb->size / 2, sb->size / 2);
7109 }
7110
7111 glEnable(GL_SCISSOR_TEST);
7112
7113 } else if (shadow->base->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
7114
7115 if (shadow_pass == 0) {
7116
7117 cm = shadow->custom_projection[0];
7118 light_transform = shadow->custom_transform[0];
7119 vp_rect = Rect2(0, sb->size / 2, sb->size, sb->size / 2);
7120 glViewport(0, sb->size / 2, sb->size, sb->size / 2);
7121 glScissor(0, sb->size / 2, sb->size, sb->size / 2);
7122 } else {
7123
7124 cm = shadow->custom_projection[1];
7125 light_transform = shadow->custom_transform[1];
7126 vp_rect = Rect2(0, 0, sb->size, sb->size / 2);
7127 glViewport(0, 0, sb->size, sb->size / 2);
7128 glScissor(0, 0, sb->size, sb->size / 2);
7129 }
7130
7131 glEnable(GL_SCISSOR_TEST);
7132
7133 } else {
7134 cm = shadow->custom_projection[0];
7135 light_transform = shadow->custom_transform[0];
7136 vp_rect = Rect2(0, 0, sb->size, sb->size);
7137 glViewport(0, 0, sb->size, sb->size);
7138 }
7139
7140 z_near = cm.get_z_near();
7141 z_far = cm.get_z_far();
7142
7143 _glClearDepth(1.0f);
7144 glClearColor(1, 1, 1, 1);
7145
7146 if (use_rgba_shadowmaps)
7147 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
7148 else
7149 glClear(GL_DEPTH_BUFFER_BIT);
7150
7151 glDisable(GL_SCISSOR_TEST);
7152
7153 } break;
7154 case VS::LIGHT_OMNI: {
7155
7156 material_shader.set_conditional(MaterialShaderGLES2::USE_DUAL_PARABOLOID, true);
7157 dp_direction = shadow_pass ? 1.0 : -1.0;
7158 flip_facing = (shadow_pass == 1);
7159 light_transform = shadow->transform;
7160 z_near = 0;
7161 z_far = shadow->base->vars[VS::LIGHT_PARAM_RADIUS];
7162 shadow->dp.x = 1.0 / z_far;
7163 shadow->dp.y = dp_direction;
7164
7165 if (shadow_pass == 0) {
7166 vp_rect = Rect2(0, sb->size / 2, sb->size, sb->size / 2);
7167 glViewport(0, sb->size / 2, sb->size, sb->size / 2);
7168 glScissor(0, sb->size / 2, sb->size, sb->size / 2);
7169 } else {
7170 vp_rect = Rect2(0, 0, sb->size, sb->size / 2);
7171 glViewport(0, 0, sb->size, sb->size / 2);
7172 glScissor(0, 0, sb->size, sb->size / 2);
7173 }
7174 glEnable(GL_SCISSOR_TEST);
7175 shadow->projection = cm;
7176
7177 glClearColor(1, 1, 1, 1);
7178 _glClearDepth(1.0f);
7179 if (use_rgba_shadowmaps)
7180 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
7181 else
7182 glClear(GL_DEPTH_BUFFER_BIT);
7183 glDisable(GL_SCISSOR_TEST);
7184
7185 } break;
7186 case VS::LIGHT_SPOT: {
7187
7188 float far = shadow->base->vars[VS::LIGHT_PARAM_RADIUS];
7189 ERR_FAIL_COND(far <= 0);
7190 float near = far / 200.0;
7191 if (near < 0.05)
7192 near = 0.05;
7193
7194 float angle = shadow->base->vars[VS::LIGHT_PARAM_SPOT_ANGLE];
7195
7196 cm.set_perspective(angle * 2.0, 1.0, near, far);
7197
7198 shadow->projection = cm; // cache
7199 light_transform = shadow->transform;
7200 z_near = cm.get_z_near();
7201 z_far = cm.get_z_far();
7202
7203 glViewport(0, 0, sb->size, sb->size);
7204 vp_rect = Rect2(0, 0, sb->size, sb->size);
7205 _glClearDepth(1.0f);
7206 glClearColor(1, 1, 1, 1);
7207 if (use_rgba_shadowmaps)
7208 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
7209 else
7210 glClear(GL_DEPTH_BUFFER_BIT);
7211
7212 } break;
7213 }
7214
7215 Transform light_transform_inverse = light_transform.affine_inverse();
7216
7217 opaque_render_list.sort_mat_geom();
7218 _render_list_forward(&opaque_render_list, light_transform, light_transform_inverse, cm, flip_facing, false);
7219
7220 material_shader.set_conditional(MaterialShaderGLES2::USE_DUAL_PARABOLOID, false);
7221
7222 //if (!use_rgba_shadowmaps)
7223
7224 if (shadow_filter == SHADOW_FILTER_ESM) {
7225
7226 copy_shader.set_conditional(CopyShaderGLES2::USE_RGBA_DEPTH, use_rgba_shadowmaps);
7227 copy_shader.set_conditional(CopyShaderGLES2::USE_HIGHP_SOURCE, !use_rgba_shadowmaps);
7228
7229 Vector2 psize(1.0 / sb->size, 1.0 / sb->size);
7230 float pscale = 1.0;
7231 int passes = shadow->base->vars[VS::LIGHT_PARAM_SHADOW_BLUR_PASSES];
7232 glDisable(GL_BLEND);
7233 glDisable(GL_CULL_FACE);
7234 #ifdef GLEW_ENABLED
7235 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
7236 #endif
7237
7238 for (int i = 0; i < VS::ARRAY_MAX; i++) {
7239 glDisableVertexAttribArray(i);
7240 }
7241 glBindBuffer(GL_ARRAY_BUFFER, 0);
7242 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
7243 glDisable(GL_SCISSOR_TEST);
7244
7245 if (!use_rgba_shadowmaps) {
7246 glEnable(GL_DEPTH_TEST);
7247 glDepthFunc(GL_ALWAYS);
7248 glDepthMask(true);
7249 } else {
7250 glDisable(GL_DEPTH_TEST);
7251 }
7252
7253 for (int i = 0; i < passes; i++) {
7254
7255 Vector2 src_sb_uv[4] = {
7256 (vp_rect.pos + Vector2(0, vp_rect.size.y)) / sb->size,
7257 (vp_rect.pos + vp_rect.size) / sb->size,
7258 (vp_rect.pos + Vector2(vp_rect.size.x, 0)) / sb->size,
7259 (vp_rect.pos) / sb->size
7260 };
7261 /*
7262 Vector2 src_uv[4]={
7263 Vector2( 0, 1),
7264 Vector2( 1, 1),
7265 Vector2( 1, 0),
7266 Vector2( 0, 0)
7267 };
7268 */
7269 static const Vector2 dst_pos[4] = {
7270 Vector2(-1, 1),
7271 Vector2(1, 1),
7272 Vector2(1, -1),
7273 Vector2(-1, -1)
7274 };
7275
7276 glBindFramebuffer(GL_FRAMEBUFFER, blur_shadow_buffer.fbo);
7277 glActiveTexture(GL_TEXTURE0);
7278 glBindTexture(GL_TEXTURE_2D, sb->depth);
7279 #ifdef GLEW_ENABLED
7280 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
7281 #endif
7282
7283 copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_V_PASS, true);
7284 copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS, false);
7285
7286 copy_shader.bind();
7287 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE, psize);
7288 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SCALE, pscale);
7289 copy_shader.set_uniform(CopyShaderGLES2::BLUR_MAGNITUDE, 1);
7290 //copy_shader.set_uniform(CopyShaderGLES2::SOURCE,0);
7291 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0);
7292
7293 _draw_gui_primitive(4, dst_pos, NULL, src_sb_uv);
7294
7295 Vector2 src_bb_uv[4] = {
7296 (vp_rect.pos + Vector2(0, vp_rect.size.y)) / blur_shadow_buffer.size,
7297 (vp_rect.pos + vp_rect.size) / blur_shadow_buffer.size,
7298 (vp_rect.pos + Vector2(vp_rect.size.x, 0)) / blur_shadow_buffer.size,
7299 (vp_rect.pos) / blur_shadow_buffer.size,
7300 };
7301
7302 glBindFramebuffer(GL_FRAMEBUFFER, sb->fbo);
7303 glActiveTexture(GL_TEXTURE0);
7304 glBindTexture(GL_TEXTURE_2D, blur_shadow_buffer.depth);
7305 #ifdef GLEW_ENABLED
7306
7307 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
7308 #endif
7309
7310 copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_V_PASS, false);
7311 copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS, true);
7312 copy_shader.bind();
7313 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE, psize);
7314 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SCALE, pscale);
7315 copy_shader.set_uniform(CopyShaderGLES2::BLUR_MAGNITUDE, 1);
7316 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE), 0);
7317
7318 _draw_gui_primitive(4, dst_pos, NULL, src_bb_uv);
7319 }
7320
7321 glDepthFunc(GL_LEQUAL);
7322 copy_shader.set_conditional(CopyShaderGLES2::USE_RGBA_DEPTH, false);
7323 copy_shader.set_conditional(CopyShaderGLES2::USE_HIGHP_SOURCE, false);
7324 copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_V_PASS, false);
7325 copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS, false);
7326 }
7327
7328 DEBUG_TEST_ERROR("Drawing Shadow");
7329 shadow = NULL;
7330 glBindFramebuffer(GL_FRAMEBUFFER, current_rt ? current_rt->fbo : base_framebuffer);
7331 glColorMask(1, 1, 1, 1);
7332 //glDisable(GL_POLYGON_OFFSET_FILL);
7333 }
7334
_debug_draw_shadow(GLuint tex,const Rect2 & p_rect)7335 void RasterizerGLES2::_debug_draw_shadow(GLuint tex, const Rect2 &p_rect) {
7336
7337 Matrix32 modelview;
7338 modelview.translate(p_rect.pos.x, p_rect.pos.y);
7339 canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, modelview);
7340 glBindTexture(GL_TEXTURE_2D, tex);
7341
7342 Vector3 coords[4] = {
7343 Vector3(p_rect.pos.x, p_rect.pos.y, 0),
7344 Vector3(p_rect.pos.x + p_rect.size.width,
7345 p_rect.pos.y, 0),
7346 Vector3(p_rect.pos.x + p_rect.size.width,
7347 p_rect.pos.y + p_rect.size.height, 0),
7348 Vector3(p_rect.pos.x,
7349 p_rect.pos.y + p_rect.size.height, 0)
7350 };
7351
7352 Vector3 texcoords[4] = {
7353 Vector3(0.0f, 0.0f, 0),
7354 Vector3(1.0f, 0.0f, 0),
7355 Vector3(1.0f, 1.0f, 0),
7356 Vector3(0.0f, 1.0f, 0),
7357 };
7358
7359 _draw_primitive(4, coords, 0, 0, texcoords);
7360 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
7361 }
7362
_debug_draw_shadows_type(Vector<ShadowBuffer> & p_shadows,Point2 & ofs)7363 void RasterizerGLES2::_debug_draw_shadows_type(Vector<ShadowBuffer> &p_shadows, Point2 &ofs) {
7364
7365 Size2 debug_size(128, 128);
7366 // Size2 debug_size(512,512);
7367
7368 int useblur = shadow_filter == SHADOW_FILTER_ESM ? 1 : 0;
7369 for (int i = 0; i < p_shadows.size() + useblur; i++) {
7370
7371 ShadowBuffer *sb = i == p_shadows.size() ? &blur_shadow_buffer : &p_shadows[i];
7372
7373 if (!sb->owner && i != p_shadows.size())
7374 continue;
7375
7376 _debug_draw_shadow(sb->depth, Rect2(ofs, debug_size));
7377 ofs.x += debug_size.x;
7378 if ((ofs.x + debug_size.x) > viewport.width) {
7379
7380 ofs.x = 0;
7381 ofs.y += debug_size.y;
7382 }
7383 }
7384 }
7385
_debug_luminances()7386 void RasterizerGLES2::_debug_luminances() {
7387
7388 canvas_shader.set_conditional(CanvasShaderGLES2::DEBUG_ENCODED_32, !use_fp16_fb);
7389 canvas_begin();
7390 glDisable(GL_BLEND);
7391 canvas_shader.bind();
7392
7393 Size2 debug_size(128, 128);
7394 Size2 ofs;
7395
7396 for (int i = 0; i <= framebuffer.luminance.size(); i++) {
7397
7398 if (i == framebuffer.luminance.size()) {
7399 if (!current_vd)
7400 break;
7401 _debug_draw_shadow(current_vd->lum_color, Rect2(ofs, debug_size));
7402 } else {
7403 _debug_draw_shadow(framebuffer.luminance[i].color, Rect2(ofs, debug_size));
7404 }
7405 ofs.x += debug_size.x / 2;
7406 if ((ofs.x + debug_size.x) > viewport.width) {
7407
7408 ofs.x = 0;
7409 ofs.y += debug_size.y;
7410 }
7411 }
7412
7413 canvas_shader.set_conditional(CanvasShaderGLES2::DEBUG_ENCODED_32, false);
7414 }
7415
_debug_samplers()7416 void RasterizerGLES2::_debug_samplers() {
7417 canvas_shader.set_conditional(CanvasShaderGLES2::DEBUG_ENCODED_32, false);
7418 canvas_begin();
7419 glDisable(GL_BLEND);
7420 _set_color_attrib(Color(1, 1, 1, 1));
7421 canvas_shader.bind();
7422
7423 List<RID> samplers;
7424 sampled_light_owner.get_owned_list(&samplers);
7425
7426 Size2 debug_size(128, 128);
7427 Size2 ofs;
7428
7429 for (List<RID>::Element *E = samplers.front(); E; E = E->next()) {
7430
7431 SampledLight *sl = sampled_light_owner.get(E->get());
7432
7433 _debug_draw_shadow(sl->texture, Rect2(ofs, debug_size));
7434
7435 ofs.x += debug_size.x / 2;
7436 if ((ofs.x + debug_size.x) > viewport.width) {
7437
7438 ofs.x = 0;
7439 ofs.y += debug_size.y;
7440 }
7441 }
7442 }
_debug_shadows()7443 void RasterizerGLES2::_debug_shadows() {
7444
7445 canvas_begin();
7446 glDisable(GL_BLEND);
7447 Size2 ofs;
7448
7449 /*
7450 for(int i=0;i<16;i++) {
7451 glActiveTexture(GL_TEXTURE0+i);
7452 //glDisable(GL_TEXTURE_2D);
7453 }
7454 glActiveTexture(GL_TEXTURE0);
7455 //glEnable(GL_TEXTURE_2D);
7456 */
7457
7458 _debug_draw_shadows_type(near_shadow_buffers, ofs);
7459 // _debug_draw_shadows_type(far_shadow_buffers,ofs);
7460 }
7461
end_frame()7462 void RasterizerGLES2::end_frame() {
7463
7464 //print_line("VTX: "+itos(_rinfo.vertex_count)+" OBJ: "+itos(_rinfo.object_count)+" MAT: "+itos(_rinfo.mat_change_count)+" SHD: "+itos(_rinfo.shader_change_count)+" CI: "+itos(_rinfo.ci_draw_commands));
7465
7466 //print_line("TOTAL VTX: "+itos(_rinfo.vertex_count));
7467 OS::get_singleton()->swap_buffers();
7468 }
7469
flush_frame()7470 void RasterizerGLES2::flush_frame() {
7471
7472 glFlush();
7473 }
7474
7475 /* CANVAS API */
7476
begin_canvas_bg()7477 void RasterizerGLES2::begin_canvas_bg() {
7478
7479 if (framebuffer.active) {
7480 using_canvas_bg = true;
7481 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.fbo);
7482 glViewport(0, 0, viewport.width, viewport.height);
7483 } else {
7484 using_canvas_bg = false;
7485 }
7486 }
7487
canvas_begin()7488 void RasterizerGLES2::canvas_begin() {
7489
7490 if (using_canvas_bg) {
7491 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.fbo);
7492 glColorMask(1, 1, 1, 0); //don't touch alpha
7493 }
7494
7495 glDisable(GL_CULL_FACE);
7496 glDisable(GL_DEPTH_TEST);
7497 glDisable(GL_SCISSOR_TEST);
7498 #ifdef GLEW_ENABLED
7499 glDisable(GL_POINT_SPRITE);
7500 glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
7501 #endif
7502 glEnable(GL_BLEND);
7503 glBlendEquation(GL_FUNC_ADD);
7504 if (current_rt && current_rt_transparent) {
7505 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
7506 } else {
7507 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
7508 }
7509 //glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
7510 glLineWidth(1.0);
7511 glBindBuffer(GL_ARRAY_BUFFER, 0);
7512 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
7513 for (int i = 0; i < VS::ARRAY_MAX; i++) {
7514 glDisableVertexAttribArray(i);
7515 }
7516
7517 glActiveTexture(GL_TEXTURE0);
7518 glBindTexture(GL_TEXTURE_2D, white_tex);
7519 canvas_tex = RID();
7520 //material_shader.unbind();
7521 canvas_shader.unbind();
7522 canvas_shader.set_custom_shader(0);
7523 canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE, false);
7524 canvas_shader.bind();
7525 canvas_shader.set_uniform(CanvasShaderGLES2::TEXTURE, 0);
7526 canvas_use_modulate = false;
7527 _set_color_attrib(Color(1, 1, 1));
7528 canvas_transform = Transform();
7529 canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f);
7530 float csy = 1.0;
7531 if (current_rt && current_rt_vflip)
7532 csy = -1.0;
7533
7534 canvas_transform.scale(Vector3(2.0f / viewport.width, csy * -2.0f / viewport.height, 1.0f));
7535 canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX, canvas_transform);
7536 canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, Matrix32());
7537 canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, Matrix32());
7538
7539 canvas_opacity = 1.0;
7540 canvas_blend_mode = VS::MATERIAL_BLEND_MODE_MIX;
7541 canvas_texscreen_used = false;
7542 uses_texpixel_size = false;
7543
7544 canvas_last_material = NULL;
7545 }
7546
canvas_disable_blending()7547 void RasterizerGLES2::canvas_disable_blending() {
7548
7549 glDisable(GL_BLEND);
7550 }
7551
canvas_set_opacity(float p_opacity)7552 void RasterizerGLES2::canvas_set_opacity(float p_opacity) {
7553
7554 canvas_opacity = p_opacity;
7555 }
7556
canvas_set_blend_mode(VS::MaterialBlendMode p_mode)7557 void RasterizerGLES2::canvas_set_blend_mode(VS::MaterialBlendMode p_mode) {
7558
7559 if (p_mode == canvas_blend_mode)
7560 return;
7561 switch (p_mode) {
7562
7563 case VS::MATERIAL_BLEND_MODE_MIX: {
7564 glBlendEquation(GL_FUNC_ADD);
7565 if (current_rt && current_rt_transparent) {
7566 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
7567 } else {
7568 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
7569 }
7570
7571 } break;
7572 case VS::MATERIAL_BLEND_MODE_ADD: {
7573
7574 glBlendEquation(GL_FUNC_ADD);
7575 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
7576
7577 } break;
7578 case VS::MATERIAL_BLEND_MODE_SUB: {
7579
7580 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
7581 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
7582 } break;
7583 case VS::MATERIAL_BLEND_MODE_MUL: {
7584 glBlendEquation(GL_FUNC_ADD);
7585 glBlendFunc(GL_DST_COLOR, GL_ZERO);
7586 } break;
7587 case VS::MATERIAL_BLEND_MODE_PREMULT_ALPHA: {
7588 glBlendEquation(GL_FUNC_ADD);
7589 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
7590 } break;
7591 }
7592
7593 canvas_blend_mode = p_mode;
7594 }
7595
canvas_begin_rect(const Matrix32 & p_transform)7596 void RasterizerGLES2::canvas_begin_rect(const Matrix32 &p_transform) {
7597
7598 canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, p_transform);
7599 canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, Matrix32());
7600 }
7601
canvas_set_clip(bool p_clip,const Rect2 & p_rect)7602 void RasterizerGLES2::canvas_set_clip(bool p_clip, const Rect2 &p_rect) {
7603
7604 if (p_clip) {
7605
7606 glEnable(GL_SCISSOR_TEST);
7607 //glScissor(viewport.x+p_rect.pos.x,viewport.y+ (viewport.height-(p_rect.pos.y+p_rect.size.height)),
7608
7609 int x = p_rect.pos.x;
7610 int y = window_size.height - (p_rect.pos.y + p_rect.size.y);
7611 int w = p_rect.size.x;
7612 int h = p_rect.size.y;
7613
7614 glScissor(x, y, w, h);
7615
7616 } else {
7617
7618 glDisable(GL_SCISSOR_TEST);
7619 }
7620 }
7621
canvas_end_rect()7622 void RasterizerGLES2::canvas_end_rect() {
7623
7624 //glPopMatrix();
7625 }
7626
_bind_canvas_texture(const RID & p_texture)7627 RasterizerGLES2::Texture *RasterizerGLES2::_bind_canvas_texture(const RID &p_texture) {
7628
7629 if (p_texture == canvas_tex && !rebind_texpixel_size) {
7630 if (canvas_tex.is_valid()) {
7631 Texture *texture = texture_owner.get(p_texture);
7632 return texture;
7633 }
7634 return NULL;
7635 }
7636
7637 rebind_texpixel_size = false;
7638
7639 if (p_texture.is_valid()) {
7640
7641 Texture *texture = texture_owner.get(p_texture);
7642 if (!texture) {
7643 canvas_tex = RID();
7644 glBindTexture(GL_TEXTURE_2D, white_tex);
7645
7646 return NULL;
7647 }
7648
7649 if (texture->render_target)
7650 texture->render_target->last_pass = frame;
7651
7652 glBindTexture(GL_TEXTURE_2D, texture->tex_id);
7653 canvas_tex = p_texture;
7654 if (uses_texpixel_size) {
7655 canvas_shader.set_uniform(CanvasShaderGLES2::TEXPIXEL_SIZE, Size2(1.0 / texture->width, 1.0 / texture->height));
7656 }
7657 return texture;
7658
7659 } else {
7660
7661 glBindTexture(GL_TEXTURE_2D, white_tex);
7662 canvas_tex = p_texture;
7663 }
7664
7665 return NULL;
7666 }
7667
canvas_draw_line(const Point2 & p_from,const Point2 & p_to,const Color & p_color,float p_width)7668 void RasterizerGLES2::canvas_draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
7669
7670 _bind_canvas_texture(RID());
7671 Color c = p_color;
7672 c.a *= canvas_opacity;
7673 _set_color_attrib(c);
7674
7675 Vector3 verts[2] = {
7676 Vector3(p_from.x, p_from.y, 0),
7677 Vector3(p_to.x, p_to.y, 0)
7678 };
7679
7680 glLineWidth(p_width);
7681 _draw_primitive(2, verts, 0, 0, 0);
7682 _rinfo.ci_draw_commands++;
7683 }
7684
_draw_gui_primitive(int p_points,const Vector2 * p_vertices,const Color * p_colors,const Vector2 * p_uvs)7685 void RasterizerGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) {
7686
7687 static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
7688
7689 //#define GLES_USE_PRIMITIVE_BUFFER
7690
7691 #ifndef GLES_NO_CLIENT_ARRAYS
7692
7693 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
7694 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), p_vertices);
7695
7696 if (p_colors) {
7697
7698 glEnableVertexAttribArray(VS::ARRAY_COLOR);
7699 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), p_colors);
7700 } else {
7701 glDisableVertexAttribArray(VS::ARRAY_COLOR);
7702 }
7703
7704 if (p_uvs) {
7705
7706 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
7707 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), p_uvs);
7708 } else {
7709 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
7710 }
7711
7712 glDrawArrays(prim[p_points], 0, p_points);
7713
7714 #else
7715
7716 glBindBuffer(GL_ARRAY_BUFFER, gui_quad_buffer);
7717 float b[32];
7718 int ofs = 0;
7719 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
7720 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(float) * 2, ((float *)0) + ofs);
7721 for (int i = 0; i < p_points; i++) {
7722 b[ofs++] = p_vertices[i].x;
7723 b[ofs++] = p_vertices[i].y;
7724 }
7725
7726 if (p_colors) {
7727
7728 glEnableVertexAttribArray(VS::ARRAY_COLOR);
7729 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(float) * 4, ((float *)0) + ofs);
7730 for (int i = 0; i < p_points; i++) {
7731 b[ofs++] = p_colors[i].r;
7732 b[ofs++] = p_colors[i].g;
7733 b[ofs++] = p_colors[i].b;
7734 b[ofs++] = p_colors[i].a;
7735 }
7736
7737 } else {
7738 glDisableVertexAttribArray(VS::ARRAY_COLOR);
7739 }
7740
7741 if (p_uvs) {
7742
7743 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
7744 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(float) * 2, ((float *)0) + ofs);
7745 for (int i = 0; i < p_points; i++) {
7746 b[ofs++] = p_uvs[i].x;
7747 b[ofs++] = p_uvs[i].y;
7748 }
7749
7750 } else {
7751 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
7752 }
7753
7754 glBufferSubData(GL_ARRAY_BUFFER, 0, ofs * 4, &b[0]);
7755 glDrawArrays(prim[p_points], 0, p_points);
7756 glBindBuffer(GL_ARRAY_BUFFER, 0);
7757
7758 #endif
7759 _rinfo.ci_draw_commands++;
7760 }
7761
_draw_gui_primitive2(int p_points,const Vector2 * p_vertices,const Color * p_colors,const Vector2 * p_uvs,const Vector2 * p_uvs2)7762 void RasterizerGLES2::_draw_gui_primitive2(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs, const Vector2 *p_uvs2) {
7763
7764 static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
7765
7766 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
7767 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), p_vertices);
7768 if (p_colors) {
7769
7770 glEnableVertexAttribArray(VS::ARRAY_COLOR);
7771 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), p_colors);
7772 } else {
7773 glDisableVertexAttribArray(VS::ARRAY_COLOR);
7774 }
7775
7776 if (p_uvs) {
7777
7778 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
7779 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), p_uvs);
7780 } else {
7781 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
7782 }
7783
7784 if (p_uvs2) {
7785
7786 glEnableVertexAttribArray(VS::ARRAY_TEX_UV2);
7787 glVertexAttribPointer(VS::ARRAY_TEX_UV2, 2, GL_FLOAT, false, sizeof(Vector2), p_uvs2);
7788 } else {
7789 glDisableVertexAttribArray(VS::ARRAY_TEX_UV2);
7790 }
7791
7792 glDrawArrays(prim[p_points], 0, p_points);
7793 _rinfo.ci_draw_commands++;
7794 }
7795
_draw_textured_quad(const Rect2 & p_rect,const Rect2 & p_src_region,const Size2 & p_tex_size,bool p_h_flip,bool p_v_flip,bool p_transpose)7796 void RasterizerGLES2::_draw_textured_quad(const Rect2 &p_rect, const Rect2 &p_src_region, const Size2 &p_tex_size, bool p_h_flip, bool p_v_flip, bool p_transpose) {
7797
7798 Vector2 texcoords[4] = {
7799 Vector2(p_src_region.pos.x / p_tex_size.width,
7800 p_src_region.pos.y / p_tex_size.height),
7801
7802 Vector2((p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width,
7803 p_src_region.pos.y / p_tex_size.height),
7804
7805 Vector2((p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width,
7806 (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height),
7807
7808 Vector2(p_src_region.pos.x / p_tex_size.width,
7809 (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height)
7810 };
7811
7812 if (p_transpose) {
7813 SWAP(texcoords[1], texcoords[3]);
7814 }
7815 if (p_h_flip) {
7816 SWAP(texcoords[0], texcoords[1]);
7817 SWAP(texcoords[2], texcoords[3]);
7818 }
7819 if (p_v_flip) {
7820 SWAP(texcoords[1], texcoords[2]);
7821 SWAP(texcoords[0], texcoords[3]);
7822 }
7823
7824 Vector2 coords[4] = {
7825 Vector2(p_rect.pos.x, p_rect.pos.y),
7826 Vector2(p_rect.pos.x + p_rect.size.width, p_rect.pos.y),
7827 Vector2(p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height),
7828 Vector2(p_rect.pos.x, p_rect.pos.y + p_rect.size.height)
7829 };
7830
7831 _draw_gui_primitive(4, coords, 0, texcoords);
7832 _rinfo.ci_draw_commands++;
7833 }
7834
_draw_quad(const Rect2 & p_rect)7835 void RasterizerGLES2::_draw_quad(const Rect2 &p_rect) {
7836
7837 Vector2 coords[4] = {
7838 Vector2(p_rect.pos.x, p_rect.pos.y),
7839 Vector2(p_rect.pos.x + p_rect.size.width, p_rect.pos.y),
7840 Vector2(p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height),
7841 Vector2(p_rect.pos.x, p_rect.pos.y + p_rect.size.height)
7842 };
7843
7844 _draw_gui_primitive(4, coords, 0, 0);
7845 _rinfo.ci_draw_commands++;
7846 }
7847
canvas_draw_rect(const Rect2 & p_rect,int p_flags,const Rect2 & p_source,RID p_texture,const Color & p_modulate)7848 void RasterizerGLES2::canvas_draw_rect(const Rect2 &p_rect, int p_flags, const Rect2 &p_source, RID p_texture, const Color &p_modulate) {
7849
7850 Color m = p_modulate;
7851 m.a *= canvas_opacity;
7852 _set_color_attrib(m);
7853 Texture *texture = _bind_canvas_texture(p_texture);
7854
7855 if (texture) {
7856
7857 bool untile = false;
7858
7859 if (p_flags & CANVAS_RECT_TILE && !(texture->flags & VS::TEXTURE_FLAG_REPEAT)) {
7860 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
7861 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
7862 untile = true;
7863 }
7864
7865 if (!(p_flags & CANVAS_RECT_REGION)) {
7866
7867 Rect2 region = Rect2(0, 0, texture->width, texture->height);
7868 _draw_textured_quad(p_rect, region, region.size, p_flags & CANVAS_RECT_FLIP_H, p_flags & CANVAS_RECT_FLIP_V, p_flags & CANVAS_RECT_TRANSPOSE);
7869
7870 } else {
7871
7872 _draw_textured_quad(p_rect, p_source, Size2(texture->width, texture->height), p_flags & CANVAS_RECT_FLIP_H, p_flags & CANVAS_RECT_FLIP_V, p_flags & CANVAS_RECT_TRANSPOSE);
7873 }
7874
7875 if (untile) {
7876 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
7877 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
7878 }
7879
7880 } else {
7881
7882 //glDisable(GL_TEXTURE_2D);
7883 _draw_quad(p_rect);
7884 //print_line("rect: "+p_rect);
7885 }
7886
7887 _rinfo.ci_draw_commands++;
7888 }
7889
canvas_draw_style_box(const Rect2 & p_rect,const Rect2 & p_src_region,RID p_texture,const float * p_margin,bool p_draw_center,const Color & p_modulate)7890 void RasterizerGLES2::canvas_draw_style_box(const Rect2 &p_rect, const Rect2 &p_src_region, RID p_texture, const float *p_margin, bool p_draw_center, const Color &p_modulate) {
7891
7892 Color m = p_modulate;
7893 m.a *= canvas_opacity;
7894 _set_color_attrib(m);
7895
7896 Texture *texture = _bind_canvas_texture(p_texture);
7897 ERR_FAIL_COND(!texture);
7898
7899 Rect2 region = p_src_region;
7900 if (region.size.width <= 0)
7901 region.size.width = texture->width;
7902 if (region.size.height <= 0)
7903 region.size.height = texture->height;
7904 /* CORNERS */
7905 _draw_textured_quad( // top left
7906 Rect2(p_rect.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])),
7907 Rect2(region.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])),
7908 Size2(texture->width, texture->height));
7909
7910 _draw_textured_quad( // top right
7911 Rect2(Point2(p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_TOP])),
7912 Rect2(Point2(region.pos.x + region.size.width - p_margin[MARGIN_RIGHT], region.pos.y), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_TOP])),
7913 Size2(texture->width, texture->height));
7914
7915 _draw_textured_quad( // bottom left
7916 Rect2(Point2(p_rect.pos.x, p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_BOTTOM])),
7917 Rect2(Point2(region.pos.x, region.pos.y + region.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_BOTTOM])),
7918 Size2(texture->width, texture->height));
7919
7920 _draw_textured_quad( // bottom right
7921 Rect2(Point2(p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_BOTTOM])),
7922 Rect2(Point2(region.pos.x + region.size.width - p_margin[MARGIN_RIGHT], region.pos.y + region.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_BOTTOM])),
7923 Size2(texture->width, texture->height));
7924
7925 Rect2 rect_center(p_rect.pos + Point2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP]), Size2(p_rect.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], p_rect.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM]));
7926
7927 Rect2 src_center(Point2(region.pos.x + p_margin[MARGIN_LEFT], region.pos.y + p_margin[MARGIN_TOP]), Size2(region.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], region.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM]));
7928
7929 _draw_textured_quad( // top
7930 Rect2(Point2(rect_center.pos.x, p_rect.pos.y), Size2(rect_center.size.width, p_margin[MARGIN_TOP])),
7931 Rect2(Point2(src_center.pos.x, region.pos.y), Size2(src_center.size.width, p_margin[MARGIN_TOP])),
7932 Size2(texture->width, texture->height));
7933
7934 _draw_textured_quad( // bottom
7935 Rect2(Point2(rect_center.pos.x, rect_center.pos.y + rect_center.size.height), Size2(rect_center.size.width, p_margin[MARGIN_BOTTOM])),
7936 Rect2(Point2(src_center.pos.x, src_center.pos.y + src_center.size.height), Size2(src_center.size.width, p_margin[MARGIN_BOTTOM])),
7937 Size2(texture->width, texture->height));
7938
7939 _draw_textured_quad( // left
7940 Rect2(Point2(p_rect.pos.x, rect_center.pos.y), Size2(p_margin[MARGIN_LEFT], rect_center.size.height)),
7941 Rect2(Point2(region.pos.x, region.pos.y + p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_LEFT], src_center.size.height)),
7942 Size2(texture->width, texture->height));
7943
7944 _draw_textured_quad( // right
7945 Rect2(Point2(rect_center.pos.x + rect_center.size.width, rect_center.pos.y), Size2(p_margin[MARGIN_RIGHT], rect_center.size.height)),
7946 Rect2(Point2(src_center.pos.x + src_center.size.width, region.pos.y + p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_RIGHT], src_center.size.height)),
7947 Size2(texture->width, texture->height));
7948
7949 if (p_draw_center) {
7950
7951 _draw_textured_quad(
7952 rect_center,
7953 src_center,
7954 Size2(texture->width, texture->height));
7955 }
7956
7957 _rinfo.ci_draw_commands++;
7958 }
7959
canvas_draw_primitive(const Vector<Point2> & p_points,const Vector<Color> & p_colors,const Vector<Point2> & p_uvs,RID p_texture,float p_width)7960 void RasterizerGLES2::canvas_draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width) {
7961
7962 ERR_FAIL_COND(p_points.size() < 1);
7963 _set_color_attrib(Color(1, 1, 1, canvas_opacity));
7964 _bind_canvas_texture(p_texture);
7965 _draw_gui_primitive(p_points.size(), p_points.ptr(), p_colors.ptr(), p_uvs.ptr());
7966
7967 _rinfo.ci_draw_commands++;
7968 }
7969
canvas_draw_polygon(int p_vertex_count,const int * p_indices,const Vector2 * p_vertices,const Vector2 * p_uvs,const Color * p_colors,const RID & p_texture,bool p_singlecolor)7970 void RasterizerGLES2::canvas_draw_polygon(int p_vertex_count, const int *p_indices, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, const RID &p_texture, bool p_singlecolor) {
7971
7972 bool do_colors = false;
7973 Color m;
7974 if (p_singlecolor) {
7975 m = *p_colors;
7976 m.a *= canvas_opacity;
7977 _set_color_attrib(m);
7978 } else if (!p_colors) {
7979 m = Color(1, 1, 1, canvas_opacity);
7980 _set_color_attrib(m);
7981 } else
7982 do_colors = true;
7983
7984 Texture *texture = _bind_canvas_texture(p_texture);
7985
7986 #ifndef GLES_NO_CLIENT_ARRAYS
7987 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
7988 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), p_vertices);
7989 if (do_colors) {
7990
7991 glEnableVertexAttribArray(VS::ARRAY_COLOR);
7992 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), p_colors);
7993 } else {
7994 glDisableVertexAttribArray(VS::ARRAY_COLOR);
7995 }
7996
7997 if (texture && p_uvs) {
7998
7999 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
8000 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), p_uvs);
8001 } else {
8002 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
8003 }
8004
8005 if (p_indices) {
8006 #ifdef GLEW_ENABLED
8007 glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_INT, p_indices);
8008 #else
8009 static const int _max_draw_poly_indices = 16 * 1024; // change this size if needed!!!
8010 ERR_FAIL_COND(p_vertex_count > _max_draw_poly_indices);
8011 static uint16_t _draw_poly_indices[_max_draw_poly_indices];
8012 for (int i = 0; i < p_vertex_count; i++) {
8013 _draw_poly_indices[i] = p_indices[i];
8014 };
8015 glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_SHORT, _draw_poly_indices);
8016 #endif
8017 } else {
8018 glDrawArrays(GL_TRIANGLES, 0, p_vertex_count);
8019 }
8020
8021 #else //WebGL specific impl.
8022 glBindBuffer(GL_ARRAY_BUFFER, gui_quad_buffer);
8023 float *b = GlobalVertexBuffer;
8024 int ofs = 0;
8025 if (p_vertex_count > MAX_POLYGON_VERTICES) {
8026 print_line("Too many vertices to render");
8027 return;
8028 }
8029 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
8030 glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(float) * 2, ((float *)0) + ofs);
8031 for (int i = 0; i < p_vertex_count; i++) {
8032 b[ofs++] = p_vertices[i].x;
8033 b[ofs++] = p_vertices[i].y;
8034 }
8035
8036 if (p_colors && do_colors) {
8037
8038 glEnableVertexAttribArray(VS::ARRAY_COLOR);
8039 glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(float) * 4, ((float *)0) + ofs);
8040 for (int i = 0; i < p_vertex_count; i++) {
8041 b[ofs++] = p_colors[i].r;
8042 b[ofs++] = p_colors[i].g;
8043 b[ofs++] = p_colors[i].b;
8044 b[ofs++] = p_colors[i].a;
8045 }
8046
8047 } else {
8048 glDisableVertexAttribArray(VS::ARRAY_COLOR);
8049 }
8050
8051 if (p_uvs) {
8052
8053 glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
8054 glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(float) * 2, ((float *)0) + ofs);
8055 for (int i = 0; i < p_vertex_count; i++) {
8056 b[ofs++] = p_uvs[i].x;
8057 b[ofs++] = p_uvs[i].y;
8058 }
8059
8060 } else {
8061 glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
8062 }
8063
8064 glBufferSubData(GL_ARRAY_BUFFER, 0, ofs * 4, &b[0]);
8065
8066 //bind the indices buffer.
8067 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer);
8068
8069 static const int _max_draw_poly_indices = 16 * 1024; // change this size if needed!!!
8070 ERR_FAIL_COND(p_vertex_count > _max_draw_poly_indices);
8071 static uint16_t _draw_poly_indices[_max_draw_poly_indices];
8072 for (int i = 0; i < p_vertex_count; i++) {
8073 _draw_poly_indices[i] = p_indices[i];
8074 //OS::get_singleton()->print("ind: %d ", p_indices[i]);
8075 };
8076
8077 //copy the data to GPU.
8078 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, p_vertex_count * sizeof(uint16_t), &_draw_poly_indices[0]);
8079
8080 //draw the triangles.
8081 glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_SHORT, 0);
8082
8083 glBindBuffer(GL_ARRAY_BUFFER, 0);
8084 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
8085 #endif
8086
8087 _rinfo.ci_draw_commands++;
8088 };
8089
canvas_set_transform(const Matrix32 & p_transform)8090 void RasterizerGLES2::canvas_set_transform(const Matrix32 &p_transform) {
8091
8092 canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, p_transform);
8093
8094 //canvas_transform = Variant(p_transform);
8095 }
8096
canvas_light_occluder_create()8097 RID RasterizerGLES2::canvas_light_occluder_create() {
8098
8099 CanvasOccluder *co = memnew(CanvasOccluder);
8100 co->index_id = 0;
8101 co->vertex_id = 0;
8102 co->len = 0;
8103
8104 return canvas_occluder_owner.make_rid(co);
8105 }
8106
canvas_light_occluder_set_polylines(RID p_occluder,const DVector<Vector2> & p_lines)8107 void RasterizerGLES2::canvas_light_occluder_set_polylines(RID p_occluder, const DVector<Vector2> &p_lines) {
8108
8109 CanvasOccluder *co = canvas_occluder_owner.get(p_occluder);
8110 ERR_FAIL_COND(!co);
8111
8112 co->lines = p_lines;
8113
8114 if (p_lines.size() != co->len) {
8115
8116 if (co->index_id)
8117 glDeleteBuffers(1, &co->index_id);
8118 if (co->vertex_id)
8119 glDeleteBuffers(1, &co->vertex_id);
8120
8121 co->index_id = 0;
8122 co->vertex_id = 0;
8123 co->len = 0;
8124 }
8125
8126 if (p_lines.size()) {
8127
8128 DVector<float> geometry;
8129 DVector<uint16_t> indices;
8130 int lc = p_lines.size();
8131
8132 geometry.resize(lc * 6);
8133 indices.resize(lc * 3);
8134
8135 DVector<float>::Write vw = geometry.write();
8136 DVector<uint16_t>::Write iw = indices.write();
8137
8138 DVector<Vector2>::Read lr = p_lines.read();
8139
8140 const int POLY_HEIGHT = 16384;
8141
8142 for (int i = 0; i < lc / 2; i++) {
8143
8144 vw[i * 12 + 0] = lr[i * 2 + 0].x;
8145 vw[i * 12 + 1] = lr[i * 2 + 0].y;
8146 vw[i * 12 + 2] = POLY_HEIGHT;
8147
8148 vw[i * 12 + 3] = lr[i * 2 + 1].x;
8149 vw[i * 12 + 4] = lr[i * 2 + 1].y;
8150 vw[i * 12 + 5] = POLY_HEIGHT;
8151
8152 vw[i * 12 + 6] = lr[i * 2 + 1].x;
8153 vw[i * 12 + 7] = lr[i * 2 + 1].y;
8154 vw[i * 12 + 8] = -POLY_HEIGHT;
8155
8156 vw[i * 12 + 9] = lr[i * 2 + 0].x;
8157 vw[i * 12 + 10] = lr[i * 2 + 0].y;
8158 vw[i * 12 + 11] = -POLY_HEIGHT;
8159
8160 iw[i * 6 + 0] = i * 4 + 0;
8161 iw[i * 6 + 1] = i * 4 + 1;
8162 iw[i * 6 + 2] = i * 4 + 2;
8163
8164 iw[i * 6 + 3] = i * 4 + 2;
8165 iw[i * 6 + 4] = i * 4 + 3;
8166 iw[i * 6 + 5] = i * 4 + 0;
8167 }
8168
8169 //if same buffer len is being set, just use BufferSubData to avoid a pipeline flush
8170
8171 if (!co->vertex_id) {
8172 glGenBuffers(1, &co->vertex_id);
8173 glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
8174 glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
8175 } else {
8176
8177 glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
8178 glBufferSubData(GL_ARRAY_BUFFER, 0, lc * 6 * sizeof(real_t), vw.ptr());
8179 }
8180
8181 glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
8182
8183 if (!co->index_id) {
8184
8185 glGenBuffers(1, &co->index_id);
8186 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
8187 glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_STATIC_DRAW);
8188 } else {
8189
8190 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
8191 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, lc * 3 * sizeof(uint16_t), iw.ptr());
8192 }
8193
8194 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
8195
8196 co->len = lc;
8197 }
8198 }
8199
canvas_light_shadow_buffer_create(int p_width)8200 RID RasterizerGLES2::canvas_light_shadow_buffer_create(int p_width) {
8201
8202 CanvasLightShadow *cls = memnew(CanvasLightShadow);
8203 if (p_width > max_texture_size)
8204 p_width = max_texture_size;
8205
8206 cls->size = p_width;
8207 glActiveTexture(GL_TEXTURE0);
8208
8209 glGenFramebuffers(1, &cls->fbo);
8210 glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
8211
8212 // Create a render buffer
8213 glGenRenderbuffers(1, &cls->rbo);
8214 glBindRenderbuffer(GL_RENDERBUFFER, cls->rbo);
8215
8216 // Create a texture for storing the depth
8217 glGenTextures(1, &cls->depth);
8218 glBindTexture(GL_TEXTURE_2D, cls->depth);
8219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8221
8222 // Remove artifact on the edges of the shadowmap
8223 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
8224 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
8225
8226 cls->height = 16;
8227
8228 //print_line("ERROR? "+itos(glGetError()));
8229 if (read_depth_supported) {
8230
8231 // We'll use a depth texture to store the depths in the shadow map
8232 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, cls->size, cls->height, 0,
8233 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
8234
8235 #ifdef GLEW_ENABLED
8236 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
8237 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
8238 #endif
8239
8240 // Attach the depth texture to FBO depth attachment point
8241 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
8242 GL_TEXTURE_2D, cls->depth, 0);
8243
8244 #ifdef GLEW_ENABLED
8245 glDrawBuffer(GL_NONE);
8246 #endif
8247
8248 } else {
8249 // We'll use a RGBA texture into which we pack the depth info
8250 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cls->size, cls->height, 0,
8251 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
8252
8253 // Attach the RGBA texture to FBO color attachment point
8254 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
8255 GL_TEXTURE_2D, cls->depth, 0);
8256 cls->rgba = cls->depth;
8257
8258 // Allocate 16-bit depth buffer
8259 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, cls->size, cls->height);
8260
8261 // Attach the render buffer as depth buffer - will be ignored
8262 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
8263 GL_RENDERBUFFER, cls->rbo);
8264 }
8265
8266 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
8267 //printf("errnum: %x\n",status);
8268 #ifdef GLEW_ENABLED
8269 if (read_depth_supported) {
8270 //glDrawBuffer(GL_BACK);
8271 }
8272 #endif
8273 glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
8274 DEBUG_TEST_ERROR("2D Shadow Buffer Init");
8275 ERR_FAIL_COND_V(status != GL_FRAMEBUFFER_COMPLETE, RID());
8276
8277 #ifdef GLEW_ENABLED
8278 if (read_depth_supported) {
8279 //glDrawBuffer(GL_BACK);
8280 }
8281 #endif
8282
8283 return canvas_light_shadow_owner.make_rid(cls);
8284 }
8285
canvas_light_shadow_buffer_update(RID p_buffer,const Matrix32 & p_light_xform,int p_light_mask,float p_near,float p_far,CanvasLightOccluderInstance * p_occluders,CameraMatrix * p_xform_cache)8286 void RasterizerGLES2::canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32 &p_light_xform, int p_light_mask, float p_near, float p_far, CanvasLightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {
8287
8288 CanvasLightShadow *cls = canvas_light_shadow_owner.get(p_buffer);
8289 ERR_FAIL_COND(!cls);
8290
8291 glDisable(GL_BLEND);
8292 glDisable(GL_SCISSOR_TEST);
8293 glDisable(GL_DITHER);
8294 glDisable(GL_CULL_FACE);
8295 glDepthFunc(GL_LEQUAL);
8296 glEnable(GL_DEPTH_TEST);
8297 glDepthMask(true);
8298
8299 glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
8300
8301 if (!use_rgba_shadowmaps)
8302 glColorMask(0, 0, 0, 0);
8303
8304 glEnableVertexAttribArray(VS::ARRAY_VERTEX);
8305 canvas_shadow_shader.bind();
8306
8307 glViewport(0, 0, cls->size, cls->height);
8308 _glClearDepth(1.0f);
8309 glClearColor(1, 1, 1, 1);
8310 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
8311
8312 VS::CanvasOccluderPolygonCullMode cull = VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
8313
8314 for (int i = 0; i < 4; i++) {
8315
8316 //make sure it remains orthogonal, makes easy to read angle later
8317
8318 Transform light;
8319 light.origin[0] = p_light_xform[2][0];
8320 light.origin[1] = p_light_xform[2][1];
8321 light.basis[0][0] = p_light_xform[0][0];
8322 light.basis[0][1] = p_light_xform[1][0];
8323 light.basis[1][0] = p_light_xform[0][1];
8324 light.basis[1][1] = p_light_xform[1][1];
8325
8326 //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1));
8327
8328 /// p_near=1;
8329 CameraMatrix projection;
8330 {
8331 real_t fov = 90;
8332 real_t near = p_near;
8333 real_t far = p_far;
8334 real_t aspect = 1.0;
8335
8336 real_t ymax = near * Math::tan(Math::deg2rad(fov * 0.5));
8337 real_t ymin = -ymax;
8338 real_t xmin = ymin * aspect;
8339 real_t xmax = ymax * aspect;
8340
8341 projection.set_frustum(xmin, xmax, ymin, ymax, near, far);
8342 }
8343
8344 Vector3 cam_target = Matrix3(Vector3(0, 0, Math_PI * 2 * (i / 4.0))).xform(Vector3(0, 1, 0));
8345 projection = projection * CameraMatrix(Transform().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse());
8346
8347 canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::PROJECTION_MATRIX, projection);
8348 canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::LIGHT_MATRIX, light);
8349
8350 if (i == 0)
8351 *p_xform_cache = projection;
8352
8353 glViewport(0, (cls->height / 4) * i, cls->size, cls->height / 4);
8354
8355 CanvasLightOccluderInstance *instance = p_occluders;
8356
8357 while (instance) {
8358
8359 CanvasOccluder *cc = canvas_occluder_owner.get(instance->polygon_buffer);
8360 if (!cc || cc->len == 0 || !(p_light_mask & instance->light_mask)) {
8361
8362 instance = instance->next;
8363 continue;
8364 }
8365
8366 canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::WORLD_MATRIX, instance->xform_cache);
8367 if (cull != instance->cull_cache) {
8368
8369 cull = instance->cull_cache;
8370 switch (cull) {
8371 case VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: {
8372
8373 glDisable(GL_CULL_FACE);
8374
8375 } break;
8376 case VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE: {
8377
8378 glEnable(GL_CULL_FACE);
8379 glCullFace(GL_FRONT);
8380 } break;
8381 case VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE: {
8382
8383 glEnable(GL_CULL_FACE);
8384 glCullFace(GL_BACK);
8385
8386 } break;
8387 }
8388 }
8389 /*
8390 if (i==0) {
8391 for(int i=0;i<cc->lines.size();i++) {
8392 Vector2 p = instance->xform_cache.xform(cc->lines.get(i));
8393 Plane pp(Vector3(p.x,p.y,0),1);
8394 pp.normal = light.xform(pp.normal);
8395 pp = projection.xform4(pp);
8396 print_line(itos(i)+": "+pp.normal/pp.d);
8397 //pp=light_mat.xform4(pp);
8398 //print_line(itos(i)+": "+pp.normal/pp.d);
8399 }
8400 }
8401 */
8402 glBindBuffer(GL_ARRAY_BUFFER, cc->vertex_id);
8403 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cc->index_id);
8404 glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0);
8405 glDrawElements(GL_TRIANGLES, cc->len * 3, GL_UNSIGNED_SHORT, 0);
8406
8407 instance = instance->next;
8408 }
8409 }
8410
8411 glDisableVertexAttribArray(VS::ARRAY_VERTEX);
8412 glBindBuffer(GL_ARRAY_BUFFER, 0);
8413 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
8414
8415 if (shadow_filter == SHADOW_FILTER_ESM) {
8416 //blur the buffer
8417 #if 0
8418 //this is ignord, it did not make any difference..
8419 if (read_depth_supported) {
8420 glDepthFunc(GL_ALWAYS);
8421 } else {
8422 glDisable(GL_DEPTH_TEST);
8423 glDepthMask(false);
8424 }
8425 glDisable(GL_CULL_FACE);
8426 glViewport(0, 0, cls->size,cls->height);
8427
8428 int passes=1;
8429 CanvasLightShadow *blur = canvas_light_shadow_owner.get(canvas_shadow_blur);
8430
8431 copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS,true);
8432 copy_shader.bind();
8433 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SCALE,1);
8434 copy_shader.set_uniform(CopyShaderGLES2::BLUR_MAGNITUDE,1);
8435 glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE),0);
8436
8437 for(int i=0;i<passes;i++) {
8438
8439 glBindFramebuffer(GL_FRAMEBUFFER, blur->fbo);
8440 glActiveTexture(GL_TEXTURE0);
8441
8442 if (read_depth_supported)
8443 glBindTexture(GL_TEXTURE_2D,cls->depth);
8444 else
8445 glBindTexture(GL_TEXTURE_2D,cls->rgba);
8446
8447
8448 {
8449 Vector2 src_sb_uv[4]={
8450 Vector2( 0, 1),
8451 Vector2( 1, 1),
8452 Vector2( 1, 0),
8453 Vector2( 0, 0)
8454 };
8455 static const Vector2 dst_pos[4]={
8456 Vector2(-1, 1),
8457 Vector2( 1, 1),
8458 Vector2( 1,-1),
8459 Vector2(-1,-1)
8460 };
8461
8462
8463
8464 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Vector2(1.0,1.0)/cls->size);
8465 _draw_gui_primitive(4,dst_pos,NULL,src_sb_uv);
8466 }
8467
8468 glActiveTexture(GL_TEXTURE0);
8469 if (read_depth_supported)
8470 glBindTexture(GL_TEXTURE_2D,blur->depth);
8471 else
8472 glBindTexture(GL_TEXTURE_2D,blur->rgba);
8473
8474 glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
8475
8476 {
8477 float hlimit = float(cls->size) / blur->size;
8478 //hlimit*=2.0;
8479 Vector2 src_sb_uv[4]={
8480 Vector2( 0, 1),
8481 Vector2( hlimit, 1),
8482 Vector2( hlimit, 0),
8483 Vector2( 0, 0)
8484 };
8485 static const Vector2 dst_pos[4]={
8486 Vector2(-1, 1),
8487 Vector2( 1, 1),
8488 Vector2( 1,-1),
8489 Vector2(-1,-1)
8490 };
8491
8492
8493 copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Vector2(1.0,1.0)/blur->size);
8494 _draw_gui_primitive(4,dst_pos,NULL,src_sb_uv);
8495 }
8496
8497 }
8498 copy_shader.set_conditional(CopyShaderGLES2::SHADOW_BLUR_H_PASS,false);
8499 glDepthFunc(GL_LEQUAL);
8500 #endif
8501 }
8502
8503 glBindFramebuffer(GL_FRAMEBUFFER, current_rt ? current_rt->fbo : base_framebuffer);
8504 glColorMask(1, 1, 1, 1);
8505 }
8506
canvas_debug_viewport_shadows(CanvasLight * p_lights_with_shadow)8507 void RasterizerGLES2::canvas_debug_viewport_shadows(CanvasLight *p_lights_with_shadow) {
8508
8509 CanvasLight *light = p_lights_with_shadow;
8510
8511 canvas_begin(); //reset
8512
8513 int h = 10;
8514 int w = viewport.width;
8515 int ofs = h;
8516
8517 //print_line(" debug lights ");
8518 while (light) {
8519
8520 // print_line("debug light");
8521 if (light->shadow_buffer.is_valid()) {
8522
8523 // print_line("sb is valid");
8524 CanvasLightShadow *sb = canvas_light_shadow_owner.get(light->shadow_buffer);
8525 if (sb) {
8526 glActiveTexture(GL_TEXTURE0);
8527 if (read_depth_supported)
8528 glBindTexture(GL_TEXTURE_2D, sb->depth);
8529 else
8530 glBindTexture(GL_TEXTURE_2D, sb->rgba);
8531 _draw_textured_quad(Rect2(h, ofs, w - h * 2, h), Rect2(0, 0, sb->size, 10), Size2(sb->size, 10), false, false);
8532 ofs += h * 2;
8533 }
8534 }
8535
8536 light = light->shadows_next_ptr;
8537 }
8538 }
8539
_canvas_normal_set_flip(const Vector2 & p_flip)8540 void RasterizerGLES2::_canvas_normal_set_flip(const Vector2 &p_flip) {
8541
8542 if (p_flip == normal_flip)
8543 return;
8544 normal_flip = p_flip;
8545 canvas_shader.set_uniform(CanvasShaderGLES2::NORMAL_FLIP, normal_flip);
8546 }
8547
8548 template <bool use_normalmap>
_canvas_item_render_commands(CanvasItem * p_item,CanvasItem * current_clip,bool & reclip)8549 void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item, CanvasItem *current_clip, bool &reclip) {
8550
8551 int cc = p_item->commands.size();
8552 CanvasItem::Command **commands = p_item->commands.ptr();
8553
8554 for (int i = 0; i < cc; i++) {
8555
8556 CanvasItem::Command *c = commands[i];
8557
8558 switch (c->type) {
8559 case CanvasItem::Command::TYPE_LINE: {
8560
8561 CanvasItem::CommandLine *line = static_cast<CanvasItem::CommandLine *>(c);
8562 canvas_draw_line(line->from, line->to, line->color, line->width);
8563 } break;
8564 case CanvasItem::Command::TYPE_RECT: {
8565
8566 CanvasItem::CommandRect *rect = static_cast<CanvasItem::CommandRect *>(c);
8567 // canvas_draw_rect(rect->rect,rect->region,rect->source,rect->flags&CanvasItem::CommandRect::FLAG_TILE,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H,rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V,rect->texture,rect->modulate);
8568 #if 0
8569 int flags=0;
8570
8571 if (rect->flags&CanvasItem::CommandRect::FLAG_REGION) {
8572 flags|=Rasterizer::CANVAS_RECT_REGION;
8573 }
8574 if (rect->flags&CanvasItem::CommandRect::FLAG_TILE) {
8575 flags|=Rasterizer::CANVAS_RECT_TILE;
8576 }
8577 if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_H) {
8578
8579 flags|=Rasterizer::CANVAS_RECT_FLIP_H;
8580 }
8581 if (rect->flags&CanvasItem::CommandRect::FLAG_FLIP_V) {
8582
8583 flags|=Rasterizer::CANVAS_RECT_FLIP_V;
8584 }
8585 #else
8586
8587 int flags = rect->flags;
8588 #endif
8589 if (use_normalmap)
8590 _canvas_normal_set_flip(Vector2((flags & CANVAS_RECT_FLIP_H) ? -1 : 1, (flags & CANVAS_RECT_FLIP_V) ? -1 : 1));
8591 canvas_draw_rect(rect->rect, flags, rect->source, rect->texture, rect->modulate);
8592
8593 } break;
8594 case CanvasItem::Command::TYPE_STYLE: {
8595
8596 CanvasItem::CommandStyle *style = static_cast<CanvasItem::CommandStyle *>(c);
8597 if (use_normalmap)
8598 _canvas_normal_set_flip(Vector2(1, 1));
8599 canvas_draw_style_box(style->rect, style->source, style->texture, style->margin, style->draw_center, style->color);
8600
8601 } break;
8602 case CanvasItem::Command::TYPE_PRIMITIVE: {
8603
8604 if (use_normalmap)
8605 _canvas_normal_set_flip(Vector2(1, 1));
8606 CanvasItem::CommandPrimitive *primitive = static_cast<CanvasItem::CommandPrimitive *>(c);
8607 canvas_draw_primitive(primitive->points, primitive->colors, primitive->uvs, primitive->texture, primitive->width);
8608 } break;
8609 case CanvasItem::Command::TYPE_POLYGON: {
8610
8611 if (use_normalmap)
8612 _canvas_normal_set_flip(Vector2(1, 1));
8613 CanvasItem::CommandPolygon *polygon = static_cast<CanvasItem::CommandPolygon *>(c);
8614 canvas_draw_polygon(polygon->count, polygon->indices.ptr(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->texture, polygon->colors.size() == 1);
8615
8616 } break;
8617
8618 case CanvasItem::Command::TYPE_POLYGON_PTR: {
8619
8620 if (use_normalmap)
8621 _canvas_normal_set_flip(Vector2(1, 1));
8622 CanvasItem::CommandPolygonPtr *polygon = static_cast<CanvasItem::CommandPolygonPtr *>(c);
8623 canvas_draw_polygon(polygon->count, polygon->indices, polygon->points, polygon->uvs, polygon->colors, polygon->texture, false);
8624 } break;
8625 case CanvasItem::Command::TYPE_CIRCLE: {
8626
8627 CanvasItem::CommandCircle *circle = static_cast<CanvasItem::CommandCircle *>(c);
8628 static const int numpoints = 32;
8629 Vector2 points[numpoints + 1];
8630 points[numpoints] = circle->pos;
8631 int indices[numpoints * 3];
8632
8633 for (int i = 0; i < numpoints; i++) {
8634
8635 points[i] = circle->pos + Vector2(Math::sin(i * Math_PI * 2.0 / numpoints), Math::cos(i * Math_PI * 2.0 / numpoints)) * circle->radius;
8636 indices[i * 3 + 0] = i;
8637 indices[i * 3 + 1] = (i + 1) % numpoints;
8638 indices[i * 3 + 2] = numpoints;
8639 }
8640 canvas_draw_polygon(numpoints * 3, indices, points, NULL, &circle->color, RID(), true);
8641 //canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1);
8642 } break;
8643 case CanvasItem::Command::TYPE_TRANSFORM: {
8644
8645 CanvasItem::CommandTransform *transform = static_cast<CanvasItem::CommandTransform *>(c);
8646 canvas_set_transform(transform->xform);
8647 } break;
8648 case CanvasItem::Command::TYPE_BLEND_MODE: {
8649
8650 CanvasItem::CommandBlendMode *bm = static_cast<CanvasItem::CommandBlendMode *>(c);
8651 canvas_set_blend_mode(bm->blend_mode);
8652
8653 } break;
8654 case CanvasItem::Command::TYPE_CLIP_IGNORE: {
8655
8656 CanvasItem::CommandClipIgnore *ci = static_cast<CanvasItem::CommandClipIgnore *>(c);
8657 if (current_clip) {
8658
8659 if (ci->ignore != reclip) {
8660 if (ci->ignore) {
8661
8662 glDisable(GL_SCISSOR_TEST);
8663 reclip = true;
8664 } else {
8665
8666 glEnable(GL_SCISSOR_TEST);
8667 //glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
8668 //current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
8669
8670 int x;
8671 int y;
8672 int w;
8673 int h;
8674
8675 if (current_rt) {
8676 x = current_clip->final_clip_rect.pos.x;
8677 y = current_clip->final_clip_rect.pos.y;
8678 w = current_clip->final_clip_rect.size.x;
8679 h = current_clip->final_clip_rect.size.y;
8680 } else {
8681 x = current_clip->final_clip_rect.pos.x;
8682 y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
8683 w = current_clip->final_clip_rect.size.x;
8684 h = current_clip->final_clip_rect.size.y;
8685 }
8686
8687 glScissor(x, y, w, h);
8688
8689 reclip = false;
8690 }
8691 }
8692 }
8693
8694 } break;
8695 }
8696 }
8697 }
8698
_canvas_item_setup_shader_params(CanvasItemMaterial * material,Shader * shader)8699 void RasterizerGLES2::_canvas_item_setup_shader_params(CanvasItemMaterial *material, Shader *shader) {
8700
8701 if (canvas_shader.bind())
8702 rebind_texpixel_size = true;
8703
8704 if (material->shader_version != shader->version) {
8705 //todo optimize uniforms
8706 material->shader_version = shader->version;
8707 }
8708
8709 if (shader->has_texscreen && framebuffer.active) {
8710
8711 int x = viewport.x;
8712 int y = window_size.height - (viewport.height + viewport.y);
8713
8714 canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT, Vector2(float(viewport.width) / framebuffer.width, float(viewport.height) / framebuffer.height));
8715 canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP, Color(float(x) / framebuffer.width, float(y) / framebuffer.height, float(x + viewport.width) / framebuffer.width, float(y + viewport.height) / framebuffer.height));
8716 canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX, max_texture_units - 1);
8717 glActiveTexture(GL_TEXTURE0 + max_texture_units - 1);
8718 glBindTexture(GL_TEXTURE_2D, framebuffer.sample_color);
8719 if (framebuffer.scale == 1 && !canvas_texscreen_used) {
8720 #ifdef GLEW_ENABLED
8721 if (current_rt) {
8722 glReadBuffer(GL_COLOR_ATTACHMENT0);
8723 } else {
8724 glReadBuffer(GL_BACK);
8725 }
8726 #endif
8727 if (current_rt) {
8728 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, viewport.x, viewport.y, viewport.x, viewport.y, viewport.width, viewport.height);
8729 canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP, Color(float(x) / framebuffer.width, float(viewport.y) / framebuffer.height, float(x + viewport.width) / framebuffer.width, float(y + viewport.height) / framebuffer.height));
8730 //window_size.height-(viewport.height+viewport.y)
8731 } else {
8732 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, y, x, y, viewport.width, viewport.height);
8733 }
8734 // if (current_clip) {
8735 // // print_line(" a clip ");
8736 // }
8737
8738 canvas_texscreen_used = true;
8739 }
8740
8741 glActiveTexture(GL_TEXTURE0);
8742 }
8743
8744 if (shader->has_screen_uv) {
8745 canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT, Vector2(1.0 / viewport.width, 1.0 / viewport.height));
8746 }
8747
8748 uses_texpixel_size = shader->uses_texpixel_size;
8749 }
8750
_canvas_item_setup_shader_uniforms(CanvasItemMaterial * material,Shader * shader)8751 void RasterizerGLES2::_canvas_item_setup_shader_uniforms(CanvasItemMaterial *material, Shader *shader) {
8752
8753 //this can be optimized..
8754 int tex_id = 1;
8755 int idx = 0;
8756 for (Map<StringName, ShaderLanguage::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
8757
8758 Map<StringName, Variant>::Element *F = material->shader_param.find(E->key());
8759
8760 if ((E->get().type == ShaderLanguage::TYPE_TEXTURE || E->get().type == ShaderLanguage::TYPE_CUBEMAP)) {
8761
8762 RID rid;
8763 if (F) {
8764 rid = F->get();
8765 }
8766
8767 if (!rid.is_valid()) {
8768
8769 Map<StringName, RID>::Element *DT = shader->default_textures.find(E->key());
8770 if (DT) {
8771 rid = DT->get();
8772 }
8773 }
8774
8775 if (rid.is_valid()) {
8776
8777 int loc = canvas_shader.get_custom_uniform_location(idx); //should be automatic..
8778
8779 glActiveTexture(GL_TEXTURE0 + tex_id);
8780 Texture *t = texture_owner.get(rid);
8781 if (!t)
8782 glBindTexture(GL_TEXTURE_2D, white_tex);
8783 else
8784 glBindTexture(t->target, t->tex_id);
8785
8786 glUniform1i(loc, tex_id);
8787 tex_id++;
8788 }
8789 } else {
8790 Variant &v = F ? F->get() : E->get().default_value;
8791 canvas_shader.set_custom_uniform(idx, v);
8792 }
8793
8794 idx++;
8795 }
8796
8797 if (tex_id > 1) {
8798 glActiveTexture(GL_TEXTURE0);
8799 }
8800
8801 if (shader->uses_time) {
8802 canvas_shader.set_uniform(CanvasShaderGLES2::TIME, Math::fmod(scaled_time, shader_time_rollback));
8803 draw_next_frame = true;
8804 }
8805 //if uses TIME - draw_next_frame=true
8806 }
8807
canvas_render_items(CanvasItem * p_item_list,int p_z,const Color & p_modulate,CanvasLight * p_light)8808 void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list, int p_z, const Color &p_modulate, CanvasLight *p_light) {
8809
8810 CanvasItem *current_clip = NULL;
8811 Shader *shader_cache = NULL;
8812
8813 bool rebind_shader = true;
8814
8815 canvas_opacity = 1.0;
8816 canvas_use_modulate = p_modulate != Color(1, 1, 1, 1);
8817 canvas_modulate = p_modulate;
8818 canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE, canvas_use_modulate);
8819 canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD, false);
8820
8821 bool reset_modulate = false;
8822 bool prev_distance_field = false;
8823
8824 while (p_item_list) {
8825
8826 CanvasItem *ci = p_item_list;
8827
8828 if (ci->vp_render) {
8829 if (draw_viewport_func) {
8830 draw_viewport_func(ci->vp_render->owner, ci->vp_render->udata, ci->vp_render->rect);
8831 }
8832 memdelete(ci->vp_render);
8833 ci->vp_render = NULL;
8834 canvas_last_material = NULL;
8835 canvas_use_modulate = p_modulate != Color(1, 1, 1, 1);
8836 canvas_modulate = p_modulate;
8837 canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE, canvas_use_modulate);
8838 canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD, false);
8839 prev_distance_field = false;
8840 rebind_shader = true;
8841 reset_modulate = true;
8842 }
8843
8844 if (prev_distance_field != ci->distance_field) {
8845
8846 canvas_shader.set_conditional(CanvasShaderGLES2::USE_DISTANCE_FIELD, ci->distance_field);
8847 prev_distance_field = ci->distance_field;
8848 rebind_shader = true;
8849 }
8850
8851 if (current_clip != ci->final_clip_owner) {
8852
8853 current_clip = ci->final_clip_owner;
8854
8855 //setup clip
8856 if (current_clip) {
8857
8858 glEnable(GL_SCISSOR_TEST);
8859 //glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
8860 //current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
8861
8862 /* int x = viewport.x+current_clip->final_clip_rect.pos.x;
8863 int y = window_size.height-(viewport.y+current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y);
8864 int w = current_clip->final_clip_rect.size.x;
8865 int h = current_clip->final_clip_rect.size.y;
8866 */
8867 int x;
8868 int y;
8869 int w;
8870 int h;
8871
8872 if (current_rt) {
8873 x = current_clip->final_clip_rect.pos.x;
8874 y = current_clip->final_clip_rect.pos.y;
8875 w = current_clip->final_clip_rect.size.x;
8876 h = current_clip->final_clip_rect.size.y;
8877 } else {
8878 x = current_clip->final_clip_rect.pos.x;
8879 y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
8880 w = current_clip->final_clip_rect.size.x;
8881 h = current_clip->final_clip_rect.size.y;
8882 }
8883
8884 glScissor(x, y, w, h);
8885
8886 } else {
8887
8888 glDisable(GL_SCISSOR_TEST);
8889 }
8890 }
8891
8892 if (ci->copy_back_buffer && framebuffer.active && framebuffer.scale == 1) {
8893
8894 Rect2 rect;
8895 int x, y;
8896
8897 if (ci->copy_back_buffer->full) {
8898
8899 x = viewport.x;
8900 y = window_size.height - (viewport.height + viewport.y);
8901 } else {
8902 x = viewport.x + ci->copy_back_buffer->screen_rect.pos.x;
8903 y = window_size.height - (viewport.y + ci->copy_back_buffer->screen_rect.pos.y + ci->copy_back_buffer->screen_rect.size.y);
8904 }
8905 glActiveTexture(GL_TEXTURE0 + max_texture_units - 1);
8906 glBindTexture(GL_TEXTURE_2D, framebuffer.sample_color);
8907
8908 #ifdef GLEW_ENABLED
8909 if (current_rt) {
8910 glReadBuffer(GL_COLOR_ATTACHMENT0);
8911 } else {
8912 glReadBuffer(GL_BACK);
8913 }
8914 #endif
8915 if (current_rt) {
8916 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, viewport.x, viewport.y, viewport.x, viewport.y, viewport.width, viewport.height);
8917 //window_size.height-(viewport.height+viewport.y)
8918 } else {
8919 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x, y, x, y, viewport.width, viewport.height);
8920 }
8921
8922 canvas_texscreen_used = true;
8923 glActiveTexture(GL_TEXTURE0);
8924 }
8925
8926 //begin rect
8927 CanvasItem *material_owner = ci->material_owner ? ci->material_owner : ci;
8928 CanvasItemMaterial *material = material_owner->material;
8929
8930 if (material != canvas_last_material || rebind_shader) {
8931
8932 Shader *shader = NULL;
8933 if (material && material->shader.is_valid()) {
8934 shader = shader_owner.get(material->shader);
8935 if (shader && !shader->valid) {
8936 shader = NULL;
8937 }
8938 }
8939
8940 shader_cache = shader;
8941
8942 if (shader) {
8943 canvas_shader.set_custom_shader(shader->custom_code_id);
8944 _canvas_item_setup_shader_params(material, shader);
8945 } else {
8946 shader_cache = NULL;
8947 canvas_shader.set_custom_shader(0);
8948 canvas_shader.bind();
8949 uses_texpixel_size = false;
8950 }
8951
8952 canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX, canvas_transform);
8953 if (canvas_use_modulate)
8954 reset_modulate = true;
8955 canvas_last_material = material;
8956 rebind_shader = false;
8957 }
8958
8959 if (material && shader_cache) {
8960
8961 _canvas_item_setup_shader_uniforms(material, shader_cache);
8962 }
8963
8964 bool unshaded = (material && material->shading_mode == VS::CANVAS_ITEM_SHADING_UNSHADED) || ci->blend_mode != VS::MATERIAL_BLEND_MODE_MIX;
8965
8966 if (unshaded) {
8967 canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE, Color(1, 1, 1, 1));
8968 reset_modulate = true;
8969 } else if (reset_modulate) {
8970 canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE, canvas_modulate);
8971 reset_modulate = false;
8972 }
8973
8974 canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, ci->final_transform);
8975 canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, Matrix32());
8976
8977 bool reclip = false;
8978
8979 if (ci == p_item_list || ci->blend_mode != canvas_blend_mode) {
8980
8981 switch (ci->blend_mode) {
8982
8983 case VS::MATERIAL_BLEND_MODE_MIX: {
8984 glBlendEquation(GL_FUNC_ADD);
8985 if (current_rt && current_rt_transparent) {
8986 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
8987 } else {
8988 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
8989 }
8990
8991 } break;
8992 case VS::MATERIAL_BLEND_MODE_ADD: {
8993
8994 glBlendEquation(GL_FUNC_ADD);
8995 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
8996
8997 } break;
8998 case VS::MATERIAL_BLEND_MODE_SUB: {
8999
9000 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
9001 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
9002 } break;
9003 case VS::MATERIAL_BLEND_MODE_MUL: {
9004 glBlendEquation(GL_FUNC_ADD);
9005 glBlendFunc(GL_DST_COLOR, GL_ZERO);
9006 } break;
9007 case VS::MATERIAL_BLEND_MODE_PREMULT_ALPHA: {
9008 glBlendEquation(GL_FUNC_ADD);
9009 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
9010 } break;
9011 }
9012
9013 canvas_blend_mode = ci->blend_mode;
9014 }
9015
9016 canvas_opacity = ci->final_opacity;
9017
9018 if (unshaded || (p_modulate.a > 0.001 && (!material || material->shading_mode != VS::CANVAS_ITEM_SHADING_ONLY_LIGHT) && !ci->light_masked))
9019 _canvas_item_render_commands<false>(ci, current_clip, reclip);
9020
9021 if (canvas_blend_mode == VS::MATERIAL_BLEND_MODE_MIX && p_light && !unshaded) {
9022
9023 CanvasLight *light = p_light;
9024 bool light_used = false;
9025 VS::CanvasLightMode mode = VS::CANVAS_LIGHT_MODE_ADD;
9026
9027 while (light) {
9028
9029 if (ci->light_mask & light->item_mask && p_z >= light->z_min && p_z <= light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) {
9030
9031 //intersects this light
9032
9033 if (!light_used || mode != light->mode) {
9034
9035 mode = light->mode;
9036
9037 switch (mode) {
9038
9039 case VS::CANVAS_LIGHT_MODE_ADD: {
9040 glBlendEquation(GL_FUNC_ADD);
9041 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
9042
9043 } break;
9044 case VS::CANVAS_LIGHT_MODE_SUB: {
9045 glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
9046 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
9047 } break;
9048 case VS::CANVAS_LIGHT_MODE_MIX:
9049 case VS::CANVAS_LIGHT_MODE_MASK: {
9050 glBlendEquation(GL_FUNC_ADD);
9051 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
9052
9053 } break;
9054 }
9055 }
9056
9057 if (!light_used) {
9058
9059 canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING, true);
9060 canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE, false);
9061 light_used = true;
9062 normal_flip = Vector2(1, 1);
9063 }
9064
9065 bool has_shadow = light->shadow_buffer.is_valid() && ci->light_mask & light->item_shadow_mask;
9066
9067 canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS, has_shadow);
9068
9069 bool light_rebind = canvas_shader.bind();
9070
9071 if (light_rebind) {
9072
9073 if (material && shader_cache) {
9074 _canvas_item_setup_shader_params(material, shader_cache);
9075 _canvas_item_setup_shader_uniforms(material, shader_cache);
9076 }
9077
9078 canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, ci->final_transform);
9079 canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, Matrix32());
9080 canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX, canvas_transform);
9081 if (canvas_use_modulate)
9082 canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE, canvas_modulate);
9083 canvas_shader.set_uniform(CanvasShaderGLES2::NORMAL_FLIP, Vector2(1, 1));
9084 canvas_shader.set_uniform(CanvasShaderGLES2::SHADOWPIXEL_SIZE, 1.0 / light->shadow_buffer_size);
9085 }
9086
9087 canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX, light->light_shader_xform);
9088 canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_POS, light->light_shader_pos);
9089 canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR, Color(light->color.r * light->energy, light->color.g * light->energy, light->color.b * light->energy, light->color.a));
9090 canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT, light->height);
9091 canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX, light->xform_cache.affine_inverse());
9092 canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_OUTSIDE_ALPHA, light->mode == VS::CANVAS_LIGHT_MODE_MASK ? 1.0 : 0.0);
9093
9094 if (has_shadow) {
9095
9096 CanvasLightShadow *cls = canvas_light_shadow_owner.get(light->shadow_buffer);
9097 glActiveTexture(GL_TEXTURE0 + max_texture_units - 3);
9098 if (read_depth_supported)
9099 glBindTexture(GL_TEXTURE_2D, cls->depth);
9100 else
9101 glBindTexture(GL_TEXTURE_2D, cls->rgba);
9102
9103 canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_TEXTURE, max_texture_units - 3);
9104 canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX, light->shadow_matrix_cache);
9105 canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_ESM_MULTIPLIER, light->shadow_esm_mult);
9106 canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_SHADOW_COLOR, light->shadow_color);
9107 }
9108
9109 glActiveTexture(GL_TEXTURE0 + max_texture_units - 2);
9110 canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_TEXTURE, max_texture_units - 2);
9111 Texture *t = texture_owner.get(light->texture);
9112 if (!t) {
9113 glBindTexture(GL_TEXTURE_2D, white_tex);
9114 } else {
9115
9116 glBindTexture(t->target, t->tex_id);
9117 }
9118
9119 glActiveTexture(GL_TEXTURE0);
9120 _canvas_item_render_commands<true>(ci, current_clip, reclip); //redraw using light
9121 }
9122
9123 light = light->next_ptr;
9124 }
9125
9126 if (light_used) {
9127
9128 canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING, false);
9129 canvas_shader.set_conditional(CanvasShaderGLES2::USE_MODULATE, canvas_use_modulate);
9130 canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS, false);
9131
9132 canvas_shader.bind();
9133
9134 if (material && shader_cache) {
9135 _canvas_item_setup_shader_params(material, shader_cache);
9136 _canvas_item_setup_shader_uniforms(material, shader_cache);
9137 }
9138
9139 canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, ci->final_transform);
9140 canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, Matrix32());
9141 if (canvas_use_modulate)
9142 canvas_shader.set_uniform(CanvasShaderGLES2::MODULATE, canvas_modulate);
9143
9144 glBlendEquation(GL_FUNC_ADD);
9145 if (current_rt && current_rt_transparent) {
9146 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
9147 } else {
9148 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
9149 }
9150 }
9151 }
9152
9153 if (reclip) {
9154
9155 glEnable(GL_SCISSOR_TEST);
9156 //glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
9157 //current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
9158
9159 int x;
9160 int y;
9161 int w;
9162 int h;
9163
9164 if (current_rt) {
9165 x = current_clip->final_clip_rect.pos.x;
9166 y = current_clip->final_clip_rect.pos.y;
9167 w = current_clip->final_clip_rect.size.x;
9168 h = current_clip->final_clip_rect.size.y;
9169 } else {
9170 x = current_clip->final_clip_rect.pos.x;
9171 y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
9172 w = current_clip->final_clip_rect.size.x;
9173 h = current_clip->final_clip_rect.size.y;
9174 }
9175
9176 glScissor(x, y, w, h);
9177 }
9178
9179 p_item_list = p_item_list->next;
9180 }
9181
9182 if (current_clip) {
9183 glDisable(GL_SCISSOR_TEST);
9184 }
9185 }
9186
9187 /* ENVIRONMENT */
9188
environment_create()9189 RID RasterizerGLES2::environment_create() {
9190
9191 Environment *env = memnew(Environment);
9192 return environment_owner.make_rid(env);
9193 }
9194
environment_set_background(RID p_env,VS::EnvironmentBG p_bg)9195 void RasterizerGLES2::environment_set_background(RID p_env, VS::EnvironmentBG p_bg) {
9196
9197 ERR_FAIL_INDEX(p_bg, VS::ENV_BG_MAX);
9198 Environment *env = environment_owner.get(p_env);
9199 ERR_FAIL_COND(!env);
9200 env->bg_mode = p_bg;
9201 }
9202
environment_get_background(RID p_env) const9203 VS::EnvironmentBG RasterizerGLES2::environment_get_background(RID p_env) const {
9204
9205 const Environment *env = environment_owner.get(p_env);
9206 ERR_FAIL_COND_V(!env, VS::ENV_BG_MAX);
9207 return env->bg_mode;
9208 }
9209
environment_set_background_param(RID p_env,VS::EnvironmentBGParam p_param,const Variant & p_value)9210 void RasterizerGLES2::environment_set_background_param(RID p_env, VS::EnvironmentBGParam p_param, const Variant &p_value) {
9211
9212 ERR_FAIL_INDEX(p_param, VS::ENV_BG_PARAM_MAX);
9213 Environment *env = environment_owner.get(p_env);
9214 ERR_FAIL_COND(!env);
9215 env->bg_param[p_param] = p_value;
9216 }
environment_get_background_param(RID p_env,VS::EnvironmentBGParam p_param) const9217 Variant RasterizerGLES2::environment_get_background_param(RID p_env, VS::EnvironmentBGParam p_param) const {
9218
9219 ERR_FAIL_INDEX_V(p_param, VS::ENV_BG_PARAM_MAX, Variant());
9220 const Environment *env = environment_owner.get(p_env);
9221 ERR_FAIL_COND_V(!env, Variant());
9222 return env->bg_param[p_param];
9223 }
9224
environment_set_enable_fx(RID p_env,VS::EnvironmentFx p_effect,bool p_enabled)9225 void RasterizerGLES2::environment_set_enable_fx(RID p_env, VS::EnvironmentFx p_effect, bool p_enabled) {
9226
9227 ERR_FAIL_INDEX(p_effect, VS::ENV_FX_MAX);
9228 Environment *env = environment_owner.get(p_env);
9229 ERR_FAIL_COND(!env);
9230 env->fx_enabled[p_effect] = p_enabled;
9231 }
environment_is_fx_enabled(RID p_env,VS::EnvironmentFx p_effect) const9232 bool RasterizerGLES2::environment_is_fx_enabled(RID p_env, VS::EnvironmentFx p_effect) const {
9233
9234 ERR_FAIL_INDEX_V(p_effect, VS::ENV_FX_MAX, false);
9235 const Environment *env = environment_owner.get(p_env);
9236 ERR_FAIL_COND_V(!env, false);
9237 return env->fx_enabled[p_effect];
9238 }
9239
environment_fx_set_param(RID p_env,VS::EnvironmentFxParam p_param,const Variant & p_value)9240 void RasterizerGLES2::environment_fx_set_param(RID p_env, VS::EnvironmentFxParam p_param, const Variant &p_value) {
9241
9242 ERR_FAIL_INDEX(p_param, VS::ENV_FX_PARAM_MAX);
9243 Environment *env = environment_owner.get(p_env);
9244 ERR_FAIL_COND(!env);
9245 env->fx_param[p_param] = p_value;
9246 }
environment_fx_get_param(RID p_env,VS::EnvironmentFxParam p_param) const9247 Variant RasterizerGLES2::environment_fx_get_param(RID p_env, VS::EnvironmentFxParam p_param) const {
9248
9249 ERR_FAIL_INDEX_V(p_param, VS::ENV_FX_PARAM_MAX, Variant());
9250 const Environment *env = environment_owner.get(p_env);
9251 ERR_FAIL_COND_V(!env, Variant());
9252 return env->fx_param[p_param];
9253 }
9254
sampled_light_dp_create(int p_width,int p_height)9255 RID RasterizerGLES2::sampled_light_dp_create(int p_width, int p_height) {
9256
9257 SampledLight *slight = memnew(SampledLight);
9258 slight->w = p_width;
9259 slight->h = p_height;
9260 slight->multiplier = 1.0;
9261 slight->is_float = float_linear_supported;
9262
9263 glActiveTexture(GL_TEXTURE0);
9264 glGenTextures(1, &slight->texture);
9265 glBindTexture(GL_TEXTURE_2D, slight->texture);
9266 // for debug, but glitchy
9267 // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9268 // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9269 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9271
9272 // Remove artifact on the edges of the shadowmap
9273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9275
9276 if (slight->is_float) {
9277 #ifdef GLEW_ENABLED
9278 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_width, p_height, 0, GL_RGBA, GL_FLOAT, NULL);
9279 #else
9280 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_width, p_height, 0, GL_RGBA, GL_FLOAT, NULL);
9281 #endif
9282 } else {
9283
9284 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_width, p_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
9285 }
9286
9287 return sampled_light_owner.make_rid(slight);
9288 }
9289
sampled_light_dp_update(RID p_sampled_light,const Color * p_data,float p_multiplier)9290 void RasterizerGLES2::sampled_light_dp_update(RID p_sampled_light, const Color *p_data, float p_multiplier) {
9291
9292 SampledLight *slight = sampled_light_owner.get(p_sampled_light);
9293 ERR_FAIL_COND(!slight);
9294
9295 glActiveTexture(GL_TEXTURE0);
9296 glBindTexture(GL_TEXTURE_2D, slight->texture);
9297
9298 if (slight->is_float) {
9299
9300 #ifdef GLEW_ENABLED
9301 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, slight->w, slight->h, GL_RGBA, GL_FLOAT, p_data);
9302 #else
9303 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, slight->w, slight->h, GL_RGBA, GL_FLOAT, p_data);
9304 #endif
9305
9306 } else {
9307 //convert to bytes
9308 uint8_t *tex8 = (uint8_t *)alloca(slight->w * slight->h * 4);
9309 const float *src = (const float *)p_data;
9310
9311 for (int i = 0; i < slight->w * slight->h * 4; i++) {
9312
9313 tex8[i] = Math::fast_ftoi(CLAMP(src[i] * 255.0, 0.0, 255.0));
9314 }
9315
9316 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, slight->w, slight->h, GL_RGBA, GL_UNSIGNED_BYTE, p_data);
9317 }
9318
9319 slight->multiplier = p_multiplier;
9320 }
9321
9322 /*MISC*/
9323
is_texture(const RID & p_rid) const9324 bool RasterizerGLES2::is_texture(const RID &p_rid) const {
9325
9326 return texture_owner.owns(p_rid);
9327 }
is_material(const RID & p_rid) const9328 bool RasterizerGLES2::is_material(const RID &p_rid) const {
9329
9330 return material_owner.owns(p_rid);
9331 }
is_mesh(const RID & p_rid) const9332 bool RasterizerGLES2::is_mesh(const RID &p_rid) const {
9333
9334 return mesh_owner.owns(p_rid);
9335 }
is_immediate(const RID & p_rid) const9336 bool RasterizerGLES2::is_immediate(const RID &p_rid) const {
9337
9338 return immediate_owner.owns(p_rid);
9339 }
is_multimesh(const RID & p_rid) const9340 bool RasterizerGLES2::is_multimesh(const RID &p_rid) const {
9341
9342 return multimesh_owner.owns(p_rid);
9343 }
is_particles(const RID & p_beam) const9344 bool RasterizerGLES2::is_particles(const RID &p_beam) const {
9345
9346 return particles_owner.owns(p_beam);
9347 }
9348
is_light(const RID & p_rid) const9349 bool RasterizerGLES2::is_light(const RID &p_rid) const {
9350
9351 return light_owner.owns(p_rid);
9352 }
is_light_instance(const RID & p_rid) const9353 bool RasterizerGLES2::is_light_instance(const RID &p_rid) const {
9354
9355 return light_instance_owner.owns(p_rid);
9356 }
is_particles_instance(const RID & p_rid) const9357 bool RasterizerGLES2::is_particles_instance(const RID &p_rid) const {
9358
9359 return particles_instance_owner.owns(p_rid);
9360 }
is_skeleton(const RID & p_rid) const9361 bool RasterizerGLES2::is_skeleton(const RID &p_rid) const {
9362
9363 return skeleton_owner.owns(p_rid);
9364 }
is_environment(const RID & p_rid) const9365 bool RasterizerGLES2::is_environment(const RID &p_rid) const {
9366
9367 return environment_owner.owns(p_rid);
9368 }
is_shader(const RID & p_rid) const9369 bool RasterizerGLES2::is_shader(const RID &p_rid) const {
9370
9371 return shader_owner.owns(p_rid);
9372 }
9373
is_canvas_light_occluder(const RID & p_rid) const9374 bool RasterizerGLES2::is_canvas_light_occluder(const RID &p_rid) const {
9375
9376 return false;
9377 }
9378
set_time_scale(float p_scale)9379 void RasterizerGLES2::set_time_scale(float p_scale) {
9380
9381 time_scale = p_scale;
9382 }
9383
free(const RID & p_rid)9384 void RasterizerGLES2::free(const RID &p_rid) {
9385 if (texture_owner.owns(p_rid)) {
9386
9387 // delete the texture
9388 Texture *texture = texture_owner.get(p_rid);
9389
9390 // glDeleteTextures( 1,&texture->tex_id );
9391 _rinfo.texture_mem -= texture->total_data_size;
9392 texture_owner.free(p_rid);
9393 memdelete(texture);
9394
9395 } else if (shader_owner.owns(p_rid)) {
9396
9397 // delete the texture
9398 Shader *shader = shader_owner.get(p_rid);
9399
9400 switch (shader->mode) {
9401 case VS::SHADER_MATERIAL: {
9402 material_shader.free_custom_shader(shader->custom_code_id);
9403 } break;
9404 case VS::SHADER_POST_PROCESS: {
9405 //postprocess_shader.free_custom_shader(shader->custom_code_id);
9406 } break;
9407 }
9408
9409 if (shader->dirty_list.in_list())
9410 _shader_dirty_list.remove(&shader->dirty_list);
9411
9412 //material_shader.free_custom_shader(shader->custom_code_id);
9413 shader_owner.free(p_rid);
9414 memdelete(shader);
9415
9416 } else if (material_owner.owns(p_rid)) {
9417
9418 Material *material = material_owner.get(p_rid);
9419 ERR_FAIL_COND(!material);
9420
9421 _free_fixed_material(p_rid); //just in case
9422 material_owner.free(p_rid);
9423 memdelete(material);
9424
9425 } else if (mesh_owner.owns(p_rid)) {
9426
9427 Mesh *mesh = mesh_owner.get(p_rid);
9428 ERR_FAIL_COND(!mesh);
9429 for (int i = 0; i < mesh->surfaces.size(); i++) {
9430
9431 Surface *surface = mesh->surfaces[i];
9432 if (surface->array_local != 0) {
9433 memfree(surface->array_local);
9434 };
9435 if (surface->index_array_local != 0) {
9436 memfree(surface->index_array_local);
9437 };
9438
9439 if (mesh->morph_target_count > 0) {
9440
9441 for (int i = 0; i < mesh->morph_target_count; i++) {
9442
9443 memdelete_arr(surface->morph_targets_local[i].array);
9444 }
9445 memdelete_arr(surface->morph_targets_local);
9446 surface->morph_targets_local = NULL;
9447 }
9448
9449 if (surface->vertex_id)
9450 glDeleteBuffers(1, &surface->vertex_id);
9451 if (surface->index_id)
9452 glDeleteBuffers(1, &surface->index_id);
9453
9454 memdelete(surface);
9455 };
9456
9457 mesh->surfaces.clear();
9458
9459 mesh_owner.free(p_rid);
9460 memdelete(mesh);
9461
9462 } else if (multimesh_owner.owns(p_rid)) {
9463
9464 MultiMesh *multimesh = multimesh_owner.get(p_rid);
9465 ERR_FAIL_COND(!multimesh);
9466
9467 if (multimesh->tex_id) {
9468 glDeleteTextures(1, &multimesh->tex_id);
9469 }
9470
9471 multimesh_owner.free(p_rid);
9472 memdelete(multimesh);
9473
9474 } else if (immediate_owner.owns(p_rid)) {
9475
9476 Immediate *immediate = immediate_owner.get(p_rid);
9477 ERR_FAIL_COND(!immediate);
9478
9479 immediate_owner.free(p_rid);
9480 memdelete(immediate);
9481 } else if (particles_owner.owns(p_rid)) {
9482
9483 Particles *particles = particles_owner.get(p_rid);
9484 ERR_FAIL_COND(!particles);
9485
9486 particles_owner.free(p_rid);
9487 memdelete(particles);
9488 } else if (particles_instance_owner.owns(p_rid)) {
9489
9490 ParticlesInstance *particles_isntance = particles_instance_owner.get(p_rid);
9491 ERR_FAIL_COND(!particles_isntance);
9492
9493 particles_instance_owner.free(p_rid);
9494 memdelete(particles_isntance);
9495
9496 } else if (skeleton_owner.owns(p_rid)) {
9497
9498 Skeleton *skeleton = skeleton_owner.get(p_rid);
9499 ERR_FAIL_COND(!skeleton);
9500
9501 if (skeleton->dirty_list.in_list())
9502 _skeleton_dirty_list.remove(&skeleton->dirty_list);
9503 if (skeleton->tex_id) {
9504 glDeleteTextures(1, &skeleton->tex_id);
9505 }
9506 skeleton_owner.free(p_rid);
9507 memdelete(skeleton);
9508
9509 } else if (light_owner.owns(p_rid)) {
9510
9511 Light *light = light_owner.get(p_rid);
9512 ERR_FAIL_COND(!light)
9513
9514 light_owner.free(p_rid);
9515 memdelete(light);
9516
9517 } else if (light_instance_owner.owns(p_rid)) {
9518
9519 LightInstance *light_instance = light_instance_owner.get(p_rid);
9520 ERR_FAIL_COND(!light_instance);
9521 light_instance->clear_shadow_buffers();
9522 light_instance_owner.free(p_rid);
9523 memdelete(light_instance);
9524
9525 } else if (environment_owner.owns(p_rid)) {
9526
9527 Environment *env = environment_owner.get(p_rid);
9528 ERR_FAIL_COND(!env);
9529
9530 environment_owner.free(p_rid);
9531 memdelete(env);
9532
9533 } else if (viewport_data_owner.owns(p_rid)) {
9534
9535 ViewportData *viewport_data = viewport_data_owner.get(p_rid);
9536 ERR_FAIL_COND(!viewport_data);
9537 glDeleteFramebuffers(1, &viewport_data->lum_fbo);
9538 glDeleteTextures(1, &viewport_data->lum_color);
9539 viewport_data_owner.free(p_rid);
9540 memdelete(viewport_data);
9541
9542 } else if (render_target_owner.owns(p_rid)) {
9543
9544 RenderTarget *render_target = render_target_owner.get(p_rid);
9545 ERR_FAIL_COND(!render_target);
9546 render_target_set_size(p_rid, 0, 0); //clears framebuffer
9547 texture_owner.free(render_target->texture);
9548 memdelete(render_target->texture_ptr);
9549 render_target_owner.free(p_rid);
9550 memdelete(render_target);
9551 } else if (sampled_light_owner.owns(p_rid)) {
9552
9553 SampledLight *sampled_light = sampled_light_owner.get(p_rid);
9554 ERR_FAIL_COND(!sampled_light);
9555 glDeleteTextures(1, &sampled_light->texture);
9556 sampled_light_owner.free(p_rid);
9557 memdelete(sampled_light);
9558 } else if (canvas_occluder_owner.owns(p_rid)) {
9559
9560 CanvasOccluder *co = canvas_occluder_owner.get(p_rid);
9561 if (co->index_id)
9562 glDeleteBuffers(1, &co->index_id);
9563 if (co->vertex_id)
9564 glDeleteBuffers(1, &co->vertex_id);
9565
9566 canvas_occluder_owner.free(p_rid);
9567 memdelete(co);
9568
9569 } else if (canvas_light_shadow_owner.owns(p_rid)) {
9570
9571 CanvasLightShadow *cls = canvas_light_shadow_owner.get(p_rid);
9572 glDeleteFramebuffers(1, &cls->fbo);
9573 glDeleteRenderbuffers(1, &cls->rbo);
9574 glDeleteTextures(1, &cls->depth);
9575 //if (!read_depth_supported) {
9576 // glDeleteTextures(1,&cls->rgba);
9577 //}
9578
9579 canvas_light_shadow_owner.free(p_rid);
9580 memdelete(cls);
9581 };
9582 }
9583
init(int p_size,bool p_use_depth)9584 bool RasterizerGLES2::ShadowBuffer::init(int p_size, bool p_use_depth) {
9585
9586 size = p_size;
9587 // Create a framebuffer object
9588 glGenFramebuffers(1, &fbo);
9589 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
9590
9591 // Create a render buffer
9592 glGenRenderbuffers(1, &rbo);
9593 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
9594
9595 // Create a texture for storing the depth
9596 glGenTextures(1, &depth);
9597 glBindTexture(GL_TEXTURE_2D, depth);
9598 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9599 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9600
9601 // Remove artifact on the edges of the shadowmap
9602 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9603 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9604
9605 //print_line("ERROR? "+itos(glGetError()));
9606 if (p_use_depth) {
9607
9608 // We'll use a depth texture to store the depths in the shadow map
9609 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size, size, 0,
9610 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
9611
9612 #ifdef GLEW_ENABLED
9613 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9614 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9615 #endif
9616
9617 // Attach the depth texture to FBO depth attachment point
9618 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
9619 GL_TEXTURE_2D, depth, 0);
9620
9621 #ifdef GLEW_ENABLED
9622 glDrawBuffer(GL_NONE);
9623 #endif
9624 } else {
9625 // We'll use a RGBA texture into which we pack the depth info
9626 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0,
9627 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
9628
9629 // Attach the RGBA texture to FBO color attachment point
9630 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
9631 GL_TEXTURE_2D, depth, 0);
9632
9633 // Allocate 16-bit depth buffer
9634 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);
9635
9636 // Attach the render buffer as depth buffer - will be ignored
9637 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
9638 GL_RENDERBUFFER, rbo);
9639 }
9640
9641 #if 0
9642
9643 if (!p_use_depth) {
9644
9645
9646 print_line("try no depth!");
9647
9648 glGenTextures(1, &rgba);
9649 glBindTexture(GL_TEXTURE_2D, rgba);
9650 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
9651 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rgba, 0);
9652 /*
9653 glGenRenderbuffers(1, &depth);
9654 glBindRenderbuffer(GL_RENDERBUFFER, depth);
9655 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, p_size, p_size);
9656 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
9657 */
9658 glGenTextures(1, &depth);
9659 glBindTexture(GL_TEXTURE_2D, depth);
9660 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9661 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9662
9663 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9664 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9665
9666 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, size, size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
9667 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
9668
9669 } else {
9670
9671 // glGenRenderbuffers(1, &rbo);
9672 // glBindRenderbuffer(GL_RENDERBUFFER, rbo);
9673
9674 glGenTextures(1, &depth);
9675 glBindTexture(GL_TEXTURE_2D, depth);
9676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9677 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9678
9679 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9680 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9681
9682 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size, size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
9683 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
9684
9685 }
9686
9687 #endif
9688 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
9689 //printf("errnum: %x\n",status);
9690 #ifdef GLEW_ENABLED
9691 if (p_use_depth) {
9692 //glDrawBuffer(GL_BACK);
9693 }
9694 #endif
9695 glBindFramebuffer(GL_FRAMEBUFFER, 0);
9696 DEBUG_TEST_ERROR("Shadow Buffer Init");
9697 ERR_FAIL_COND_V(status != GL_FRAMEBUFFER_COMPLETE, false);
9698
9699 #ifdef GLEW_ENABLED
9700 if (p_use_depth) {
9701 //glDrawBuffer(GL_BACK);
9702 }
9703 #endif
9704
9705 #if 0
9706 glGenFramebuffers(1, &fbo_blur);
9707 glBindFramebuffer(GL_FRAMEBUFFER, fbo_blur);
9708
9709 glGenRenderbuffers(1, &rbo_blur);
9710 glBindRenderbuffer(GL_RENDERBUFFER, rbo_blur);
9711
9712 glGenTextures(1, &blur);
9713 glBindTexture(GL_TEXTURE_2D, blur);
9714 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9715 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9716
9717 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9718 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9719
9720
9721 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
9722 // glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, size, size, 0,
9723 // GL_DEPTH_COMPONENT16, GL_UNSIGNED_SHORT, NULL);
9724
9725 // Attach the RGBA texture to FBO color attachment point
9726 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
9727 GL_TEXTURE_2D, blur, 0);
9728
9729 // Allocate 16-bit depth buffer
9730 /* glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);
9731
9732 // Attach the render buffer as depth buffer - will be ignored
9733 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
9734 GL_RENDERBUFFER, rbo_blur);
9735 */
9736 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
9737 OS::get_singleton()->print("Status: %x\n",status);
9738 glBindFramebuffer(GL_FRAMEBUFFER, 0);
9739 DEBUG_TEST_ERROR("Shadow Blur Buffer Init");
9740 ERR_FAIL_COND_V( status != GL_FRAMEBUFFER_COMPLETE,false );
9741 #endif
9742
9743 return true;
9744 }
9745
_update_framebuffer()9746 void RasterizerGLES2::_update_framebuffer() {
9747
9748 if (!use_framebuffers)
9749 return;
9750
9751 int scale = GLOBAL_DEF("rasterizer/framebuffer_shrink", 1);
9752 if (scale < 1)
9753 scale = 1;
9754
9755 int dwidth = OS::get_singleton()->get_video_mode().width / scale;
9756 int dheight = OS::get_singleton()->get_video_mode().height / scale;
9757
9758 if (framebuffer.fbo && dwidth == framebuffer.width && dheight == framebuffer.height)
9759 return;
9760
9761 bool use_fbo = true;
9762
9763 if (framebuffer.fbo != 0) {
9764
9765 glDeleteFramebuffers(1, &framebuffer.fbo);
9766 #if 0
9767 glDeleteTextures(1,&framebuffer.depth);
9768 #else
9769 glDeleteRenderbuffers(1, &framebuffer.depth);
9770
9771 #endif
9772 glDeleteTextures(1, &framebuffer.color);
9773
9774 for (int i = 0; i < framebuffer.luminance.size(); i++) {
9775
9776 glDeleteTextures(1, &framebuffer.luminance[i].color);
9777 glDeleteFramebuffers(1, &framebuffer.luminance[i].fbo);
9778 }
9779
9780 for (int i = 0; i < 3; i++) {
9781
9782 glDeleteTextures(1, &framebuffer.blur[i].color);
9783 glDeleteFramebuffers(1, &framebuffer.blur[i].fbo);
9784 }
9785
9786 glDeleteTextures(1, &framebuffer.sample_color);
9787 glDeleteFramebuffers(1, &framebuffer.sample_fbo);
9788 framebuffer.luminance.clear();
9789 framebuffer.blur_size = 0;
9790 framebuffer.fbo = 0;
9791 }
9792
9793 #ifdef TOOLS_ENABLED
9794 framebuffer.active = use_fbo;
9795 #else
9796 framebuffer.active = use_fbo && !low_memory_2d;
9797 #endif
9798 framebuffer.width = dwidth;
9799 framebuffer.height = dheight;
9800 framebuffer.scale = scale;
9801
9802 if (!framebuffer.active)
9803 return;
9804
9805 glGenFramebuffers(1, &framebuffer.fbo);
9806 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.fbo);
9807
9808 //print_line("generating fbo, id: "+itos(framebuffer.fbo));
9809 //depth
9810
9811 // Create a render buffer
9812
9813 #if 0
9814 glGenTextures(1, &framebuffer.depth);
9815 glBindTexture(GL_TEXTURE_2D, framebuffer.depth);
9816 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, framebuffer.width, framebuffer.height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
9817 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9818 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9819 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE );
9820 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, framebuffer.depth, 0);
9821
9822 #else
9823
9824 glGenRenderbuffers(1, &framebuffer.depth);
9825 glBindRenderbuffer(GL_RENDERBUFFER, framebuffer.depth);
9826
9827 glRenderbufferStorage(GL_RENDERBUFFER, use_depth24 ? _DEPTH_COMPONENT24_OES : GL_DEPTH_COMPONENT16, framebuffer.width, framebuffer.height);
9828
9829 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, framebuffer.depth);
9830
9831 #endif
9832 //color
9833
9834 // GLuint format_rgba = use_fp16_fb?_GL_RGBA16F_EXT:GL_RGBA;
9835 GLuint format_rgba = GL_RGBA;
9836 GLuint format_type = use_fp16_fb ? _GL_HALF_FLOAT_OES : GL_UNSIGNED_BYTE;
9837 GLuint format_internal = GL_RGBA;
9838
9839 if (use_16bits_fbo) {
9840 format_type = GL_UNSIGNED_SHORT_5_6_5;
9841 format_rgba = GL_RGB;
9842 format_internal = GL_RGB;
9843 }
9844 /*GLuint format_luminance = use_fp16_fb?GL_RGB16F:GL_RGBA;
9845 GLuint format_luminance_type = use_fp16_fb?(use_fu_GL_HALF_FLOAT_OES):GL_UNSIGNED_BYTE;
9846 GLuint format_luminance_components = use_fp16_fb?GL_RGB:GL_RGBA;*/
9847
9848 GLuint format_luminance = use_fp16_fb ? _GL_RG_EXT : GL_RGBA;
9849 GLuint format_luminance_type = use_fp16_fb ? (full_float_fb_supported ? GL_FLOAT : _GL_HALF_FLOAT_OES) : GL_UNSIGNED_BYTE;
9850 GLuint format_luminance_components = use_fp16_fb ? _GL_RG_EXT : GL_RGBA;
9851
9852 glGenTextures(1, &framebuffer.color);
9853 glBindTexture(GL_TEXTURE_2D, framebuffer.color);
9854 glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, framebuffer.width, framebuffer.height, 0, format_internal, format_type, NULL);
9855 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9856 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9857 // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9858 // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9859 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9860 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9861 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebuffer.color, 0);
9862 #
9863 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
9864 glBindFramebuffer(GL_FRAMEBUFFER, 0);
9865
9866 if (status != GL_FRAMEBUFFER_COMPLETE) {
9867
9868 glDeleteFramebuffers(1, &framebuffer.fbo);
9869 #if 0
9870 glDeleteTextures(1,&framebuffer.depth);
9871 #else
9872 glDeleteRenderbuffers(1, &framebuffer.depth);
9873
9874 #endif
9875 glDeleteTextures(1, &framebuffer.color);
9876 framebuffer.fbo = 0;
9877 framebuffer.active = false;
9878 //print_line("**************** NO FAMEBUFFEEEERRRR????");
9879 WARN_PRINT(String("Could not create framebuffer!!, code: " + itos(status)).ascii().get_data());
9880 }
9881
9882 //sample
9883
9884 glGenFramebuffers(1, &framebuffer.sample_fbo);
9885 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.sample_fbo);
9886 glGenTextures(1, &framebuffer.sample_color);
9887 glBindTexture(GL_TEXTURE_2D, framebuffer.sample_color);
9888 glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, framebuffer.width, framebuffer.height, 0, format_internal, format_type, NULL);
9889 if (bool(GLOBAL_DEF("rasterizer/texscreen_filtered", false))) {
9890 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9891 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9892 } else {
9893 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9894 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9895 }
9896 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9897 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9898 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebuffer.sample_color, 0);
9899 #
9900 status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
9901 glBindFramebuffer(GL_FRAMEBUFFER, 0);
9902
9903 if (status != GL_FRAMEBUFFER_COMPLETE) {
9904
9905 glDeleteFramebuffers(1, &framebuffer.fbo);
9906 #if 0
9907 glDeleteTextures(1,&framebuffer.depth);
9908 #else
9909 glDeleteRenderbuffers(1, &framebuffer.depth);
9910
9911 #endif
9912 glDeleteTextures(1, &framebuffer.color);
9913 glDeleteTextures(1, &framebuffer.sample_color);
9914 glDeleteFramebuffers(1, &framebuffer.sample_fbo);
9915 framebuffer.fbo = 0;
9916 framebuffer.active = false;
9917 //print_line("**************** NO FAMEBUFFEEEERRRR????");
9918 WARN_PRINT("Could not create framebuffer!!");
9919 }
9920 //blur
9921
9922 int size = GLOBAL_DEF("rasterizer/blur_buffer_size", 256);
9923
9924 if (size != framebuffer.blur_size) {
9925
9926 for (int i = 0; i < 3; i++) {
9927
9928 if (framebuffer.blur[i].fbo) {
9929 glDeleteFramebuffers(1, &framebuffer.blur[i].fbo);
9930 glDeleteTextures(1, &framebuffer.blur[i].color);
9931 framebuffer.blur[i].fbo = 0;
9932 framebuffer.blur[i].color = 0;
9933 }
9934 }
9935
9936 framebuffer.blur_size = size;
9937
9938 for (int i = 0; i < 3; i++) {
9939
9940 glGenFramebuffers(1, &framebuffer.blur[i].fbo);
9941 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.blur[i].fbo);
9942
9943 glGenTextures(1, &framebuffer.blur[i].color);
9944 glBindTexture(GL_TEXTURE_2D, framebuffer.blur[i].color);
9945 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
9946 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
9947 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9948 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9949 glTexImage2D(GL_TEXTURE_2D, 0, format_rgba, size, size, 0,
9950 format_internal, format_type, NULL);
9951 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
9952 GL_TEXTURE_2D, framebuffer.blur[i].color, 0);
9953
9954 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
9955
9956 glBindFramebuffer(GL_FRAMEBUFFER, 0);
9957 DEBUG_TEST_ERROR("Shadow Buffer Init");
9958 ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
9959 }
9960 }
9961
9962 // luminance
9963
9964 int base_size = GLOBAL_DEF("rasterizer/luminance_buffer_size", 81);
9965
9966 if (framebuffer.luminance.empty() || framebuffer.luminance[0].size != base_size) {
9967
9968 for (int i = 0; i < framebuffer.luminance.size(); i++) {
9969
9970 glDeleteFramebuffers(1, &framebuffer.luminance[i].fbo);
9971 glDeleteTextures(1, &framebuffer.luminance[i].color);
9972 }
9973
9974 framebuffer.luminance.clear();
9975
9976 while (base_size > 0) {
9977
9978 FrameBuffer::Luminance lb;
9979 lb.size = base_size;
9980
9981 glGenFramebuffers(1, &lb.fbo);
9982 glBindFramebuffer(GL_FRAMEBUFFER, lb.fbo);
9983
9984 glGenTextures(1, &lb.color);
9985 glBindTexture(GL_TEXTURE_2D, lb.color);
9986 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
9987 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
9988 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
9989 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
9990 glTexImage2D(GL_TEXTURE_2D, 0, format_luminance, lb.size, lb.size, 0,
9991 format_luminance_components, format_luminance_type, NULL);
9992 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
9993 GL_TEXTURE_2D, lb.color, 0);
9994
9995 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
9996
9997 glBindFramebuffer(GL_FRAMEBUFFER, 0);
9998
9999 base_size /= 3;
10000
10001 DEBUG_TEST_ERROR("Shadow Buffer Init");
10002 ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
10003
10004 framebuffer.luminance.push_back(lb);
10005 }
10006 }
10007 }
10008
set_base_framebuffer(GLuint p_id,Vector2 p_size)10009 void RasterizerGLES2::set_base_framebuffer(GLuint p_id, Vector2 p_size) {
10010
10011 base_framebuffer = p_id;
10012
10013 if (p_size.x != 0) {
10014 window_size = p_size;
10015 };
10016 }
10017
10018 #if 0
10019 void RasterizerGLES2::_update_blur_buffer() {
10020
10021 int size = GLOBAL_DEF("rasterizer/blur_buffer_size",256);
10022 if (size!=framebuffer.blur_size) {
10023
10024 for(int i=0;i<3;i++) {
10025
10026 if (framebuffer.blur[i].fbo) {
10027 glDeleteFramebuffers(1,&framebuffer.blur[i].fbo);
10028 glDeleteTextures(1,&framebuffer.blur[i].color);
10029 framebuffer.blur[i].fbo=0;
10030 framebuffer.blur[i].color=0;
10031 }
10032 }
10033
10034 framebuffer.blur_size=size;
10035
10036 for(int i=0;i<3;i++) {
10037
10038 glGenFramebuffers(1, &framebuffer.blur[i].fbo);
10039 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.blur[i].fbo);
10040
10041 glGenTextures(1, &framebuffer.blur[i].color);
10042 glBindTexture(GL_TEXTURE_2D, framebuffer.blur[i].color);
10043 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10044 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10045 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
10046 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
10047 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0,
10048 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
10049 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
10050 GL_TEXTURE_2D, framebuffer.blur[i].color, 0);
10051
10052
10053 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
10054
10055 glBindFramebuffer(GL_FRAMEBUFFER, 0);
10056 DEBUG_TEST_ERROR("Shadow Buffer Init");
10057 ERR_CONTINUE( status != GL_FRAMEBUFFER_COMPLETE );
10058
10059
10060 }
10061
10062 }
10063
10064
10065
10066
10067
10068 }
10069 #endif
10070
_test_depth_shadow_buffer()10071 bool RasterizerGLES2::_test_depth_shadow_buffer() {
10072
10073 int size = 16;
10074
10075 GLuint fbo;
10076 GLuint rbo;
10077 GLuint depth;
10078
10079 glActiveTexture(GL_TEXTURE0);
10080
10081 glGenFramebuffers(1, &fbo);
10082 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
10083
10084 // Create a render buffer
10085 glGenRenderbuffers(1, &rbo);
10086 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
10087
10088 // Create a texture for storing the depth
10089 glGenTextures(1, &depth);
10090 glBindTexture(GL_TEXTURE_2D, depth);
10091 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10092 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10093
10094 // Remove artifact on the edges of the shadowmap
10095 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
10096 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
10097
10098 // We'll use a depth texture to store the depths in the shadow map
10099 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, size, size, 0,
10100 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
10101
10102 #ifdef GLEW_ENABLED
10103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
10104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
10105 #endif
10106
10107 // Attach the depth texture to FBO depth attachment point
10108 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
10109 GL_TEXTURE_2D, depth, 0);
10110
10111 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
10112
10113 glDeleteFramebuffers(1, &fbo);
10114 glDeleteRenderbuffers(1, &rbo);
10115 glDeleteTextures(1, &depth);
10116
10117 return status == GL_FRAMEBUFFER_COMPLETE;
10118 }
10119
init()10120 void RasterizerGLES2::init() {
10121
10122 if (OS::get_singleton()->is_stdout_verbose()) {
10123 print_line("Using GLES2 video driver");
10124 }
10125
10126 #ifdef GLEW_ENABLED
10127 GLuint res = glewInit();
10128 ERR_FAIL_COND(res != GLEW_OK);
10129 if (OS::get_singleton()->is_stdout_verbose()) {
10130 print_line(String("GLES2: Using GLEW ") + (const char *)glewGetString(GLEW_VERSION));
10131 }
10132
10133 // Godot makes use of functions from ARB_framebuffer_object extension which is not implemented by all drivers.
10134 // On the other hand, these drivers might implement the older EXT_framebuffer_object extension
10135 // with which current source code is backward compatible.
10136
10137 bool framebuffer_object_is_supported = glewIsSupported("GL_ARB_framebuffer_object");
10138
10139 if (!framebuffer_object_is_supported) {
10140 WARN_PRINT("GL_ARB_framebuffer_object not supported by your graphics card.");
10141
10142 if (glewIsSupported("GL_EXT_framebuffer_object")) {
10143 // falling-back to the older EXT function if present
10144 WARN_PRINT("Falling-back to GL_EXT_framebuffer_object.");
10145
10146 glIsRenderbuffer = glIsRenderbufferEXT;
10147 glBindRenderbuffer = glBindRenderbufferEXT;
10148 glDeleteRenderbuffers = glDeleteRenderbuffersEXT;
10149 glGenRenderbuffers = glGenRenderbuffersEXT;
10150 glRenderbufferStorage = glRenderbufferStorageEXT;
10151 glGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT;
10152 glIsFramebuffer = glIsFramebufferEXT;
10153 glBindFramebuffer = glBindFramebufferEXT;
10154 glDeleteFramebuffers = glDeleteFramebuffersEXT;
10155 glGenFramebuffers = glGenFramebuffersEXT;
10156 glCheckFramebufferStatus = glCheckFramebufferStatusEXT;
10157 glFramebufferTexture1D = glFramebufferTexture1DEXT;
10158 glFramebufferTexture2D = glFramebufferTexture2DEXT;
10159 glFramebufferTexture3D = glFramebufferTexture3DEXT;
10160 glFramebufferRenderbuffer = glFramebufferRenderbufferEXT;
10161 glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
10162 glGenerateMipmap = glGenerateMipmapEXT;
10163
10164 framebuffer_object_is_supported = true;
10165 } else {
10166 ERR_PRINT("Framebuffer Object is not supported by your graphics card.");
10167 }
10168 }
10169
10170 // Check for GL 2.1 compatibility, if not bail out
10171 if (!(glewIsSupported("GL_VERSION_2_1") && framebuffer_object_is_supported)) {
10172 ERR_PRINT("Your system's graphic drivers seem not to support OpenGL 2.1 / GLES 2.0, sorry :(\n"
10173 "Try a drivers update, buy a new GPU or try software rendering on Linux; Godot is now going to terminate.");
10174 OS::get_singleton()->alert("Your system's graphic drivers seem not to support OpenGL 2.1 / GLES 2.0, sorry :(\n"
10175 "Godot Engine will self-destruct as soon as you acknowledge this error message.",
10176 "Fatal error: Insufficient OpenGL / GLES drivers");
10177 exit(1);
10178 }
10179 #endif
10180
10181 scene_pass = 1;
10182
10183 if (extensions.size() == 0) {
10184
10185 set_extensions((const char *)glGetString(GL_EXTENSIONS));
10186 }
10187
10188 GLint tmp = 0;
10189 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &tmp);
10190 //print_line("GL_MAX_VERTEX_ATTRIBS "+itos(tmp));
10191
10192 glEnable(GL_DEPTH_TEST);
10193 glDepthFunc(GL_LEQUAL);
10194 glFrontFace(GL_CW);
10195 //glEnable(GL_TEXTURE_2D);
10196
10197 default_material = create_default_material();
10198
10199 material_shader.init();
10200 canvas_shader.init();
10201 copy_shader.init();
10202 canvas_shadow_shader.init();
10203
10204 #ifdef GLEW_ENABLED
10205 material_shader.set_conditional(MaterialShaderGLES2::USE_GLES_OVER_GL, true);
10206 canvas_shader.set_conditional(CanvasShaderGLES2::USE_GLES_OVER_GL, true);
10207 canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES2::USE_GLES_OVER_GL, true);
10208 copy_shader.set_conditional(CopyShaderGLES2::USE_GLES_OVER_GL, true);
10209 #endif
10210
10211 shadow = NULL;
10212 shadow_pass = 0;
10213
10214 #ifdef ANGLE_ENABLED
10215 // Fix for ANGLE
10216 material_shader.set_conditional(MaterialShaderGLES2::DISABLE_FRONT_FACING, true);
10217 #endif
10218
10219 framebuffer.fbo = 0;
10220 framebuffer.width = 0;
10221 framebuffer.height = 0;
10222 // framebuffer.buff16=false;
10223 // framebuffer.blur[0].fbo=false;
10224 // framebuffer.blur[1].fbo=false;
10225 framebuffer.active = false;
10226
10227 //do a single initial clear
10228 glClearColor(0, 0, 0, 1);
10229 //glClearDepth(1.0);
10230 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
10231
10232 glGenTextures(1, &white_tex);
10233 unsigned char whitetexdata[8 * 8 * 3];
10234 for (int i = 0; i < 8 * 8 * 3; i++) {
10235 whitetexdata[i] = 255;
10236 }
10237 glActiveTexture(GL_TEXTURE0);
10238 glBindTexture(GL_TEXTURE_2D, white_tex);
10239 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, whitetexdata);
10240 glGenerateMipmap(GL_TEXTURE_2D);
10241 glBindTexture(GL_TEXTURE_2D, 0);
10242
10243 #ifdef GLEW_ENABLED
10244
10245 pvr_supported = false;
10246 etc_supported = false;
10247 use_depth24 = true;
10248 s3tc_supported = true;
10249 atitc_supported = false;
10250 // use_texture_instancing=false;
10251 // use_attribute_instancing=true;
10252 use_texture_instancing = false;
10253 use_attribute_instancing = true;
10254 full_float_fb_supported = true;
10255 srgb_supported = true;
10256 latc_supported = true;
10257 s3tc_srgb_supported = true;
10258 use_anisotropic_filter = true;
10259 float_linear_supported = true;
10260
10261 GLint vtf;
10262 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &vtf);
10263 float_supported = extensions.has("GL_OES_texture_float") || extensions.has("GL_ARB_texture_float");
10264 use_hw_skeleton_xform = vtf > 0 && float_supported;
10265
10266 read_depth_supported = _test_depth_shadow_buffer();
10267 use_rgba_shadowmaps = !read_depth_supported;
10268 //print_line("read depth support? "+itos(read_depth_supported));
10269
10270 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic_level);
10271 anisotropic_level = MIN(anisotropic_level, float(GLOBAL_DEF("rasterizer/anisotropic_filter_level", 4.0)));
10272 #ifdef OSX_ENABLED
10273 use_rgba_shadowmaps = true;
10274 use_fp16_fb = false;
10275 #else
10276
10277 #endif
10278 use_half_float = true;
10279
10280 #else
10281
10282 for (Set<String>::Element *E = extensions.front(); E; E = E->next()) {
10283 print_line(E->get());
10284 }
10285 read_depth_supported = extensions.has("GL_OES_depth_texture");
10286 use_rgba_shadowmaps = !read_depth_supported;
10287 if (shadow_filter >= SHADOW_FILTER_ESM && !extensions.has("GL_EXT_frag_depth")) {
10288 use_rgba_shadowmaps = true; //no other way, go back to rgba
10289 }
10290 pvr_supported = extensions.has("GL_IMG_texture_compression_pvrtc");
10291 pvr_srgb_supported = extensions.has("GL_EXT_pvrtc_sRGB");
10292 etc_supported = extensions.has("GL_OES_compressed_ETC1_RGB8_texture");
10293 use_depth24 = extensions.has("GL_OES_depth24");
10294 s3tc_supported = extensions.has("GL_EXT_texture_compression_dxt1") || extensions.has("GL_EXT_texture_compression_s3tc") || extensions.has("WEBGL_compressed_texture_s3tc");
10295 use_half_float = extensions.has("GL_OES_vertex_half_float");
10296 atitc_supported = extensions.has("GL_AMD_compressed_ATC_texture");
10297 srgb_supported = extensions.has("GL_EXT_sRGB");
10298 #ifndef ANGLE_ENABLED
10299 s3tc_srgb_supported = s3tc_supported && extensions.has("GL_EXT_texture_compression_s3tc");
10300 #else
10301 s3tc_srgb_supported = s3tc_supported;
10302 #endif
10303 latc_supported = extensions.has("GL_EXT_texture_compression_latc");
10304 anisotropic_level = 1.0;
10305 use_anisotropic_filter = extensions.has("GL_EXT_texture_filter_anisotropic");
10306 if (use_anisotropic_filter) {
10307 glGetFloatv(_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &anisotropic_level);
10308 anisotropic_level = MIN(anisotropic_level, float(GLOBAL_DEF("rasterizer/anisotropic_filter_level", 4.0)));
10309 }
10310
10311 print_line("S3TC: " + itos(s3tc_supported) + " ATITC: " + itos(atitc_supported));
10312
10313 GLint vtf;
10314 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &vtf);
10315 float_supported = extensions.has("GL_OES_texture_float") || extensions.has("GL_ARB_texture_float");
10316 use_hw_skeleton_xform = vtf > 0 && float_supported;
10317 float_linear_supported = extensions.has("GL_OES_texture_float_linear");
10318
10319 //if (extensions.has("GL_QCOM_tiled_rendering"))
10320 // use_hw_skeleton_xform=false;
10321 GLint mva;
10322 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mva);
10323 if (vtf == 0 && mva > 8) {
10324 //tegra 3, mali 400
10325 use_attribute_instancing = true;
10326 use_texture_instancing = false;
10327 } else if (vtf > 0 && extensions.has("GL_OES_texture_float")) {
10328 //use_texture_instancing=true;
10329 use_texture_instancing = false; // i don't get it, uniforms are faster.
10330 use_attribute_instancing = false;
10331
10332 } else {
10333
10334 use_texture_instancing = false;
10335 use_attribute_instancing = false;
10336 }
10337
10338 if (use_fp16_fb) {
10339 use_fp16_fb = extensions.has("GL_OES_texture_half_float") && extensions.has("GL_EXT_color_buffer_half_float") && extensions.has("GL_EXT_texture_rg");
10340 }
10341
10342 full_float_fb_supported = extensions.has("GL_EXT_color_buffer_float");
10343
10344 //etc_supported=false;
10345
10346 #endif
10347
10348 //use_rgba_shadowmaps=true;
10349
10350 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_units);
10351 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
10352 //read_depth_supported=false;
10353
10354 canvas_shadow_blur = canvas_light_shadow_buffer_create(max_texture_size);
10355
10356 {
10357 //shadowmaps
10358
10359 //don't use a shadowbuffer too big in GLES, this should be the maximum
10360 int max_shadow_size = GLOBAL_DEF("rasterizer/max_shadow_buffer_size", 1024);
10361 int smsize = max_shadow_size;
10362 while (smsize >= 16) {
10363
10364 ShadowBuffer sb;
10365 bool s = sb.init(smsize, !use_rgba_shadowmaps);
10366 if (s)
10367 near_shadow_buffers.push_back(sb);
10368 smsize /= 2;
10369 }
10370
10371 blur_shadow_buffer.init(max_shadow_size, !use_rgba_shadowmaps);
10372
10373 //material_shader
10374 material_shader.set_conditional(MaterialShaderGLES2::USE_DEPTH_SHADOWS, !use_rgba_shadowmaps);
10375 canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES2::USE_DEPTH_SHADOWS, !use_rgba_shadowmaps);
10376 }
10377
10378 shadow_material = material_create(); //empty with nothing
10379 shadow_mat_ptr = material_owner.get(shadow_material);
10380
10381 // Now create a second shadow material for double-sided shadow instances
10382 shadow_material_double_sided = material_create();
10383 shadow_mat_double_sided_ptr = material_owner.get(shadow_material_double_sided);
10384 shadow_mat_double_sided_ptr->flags[VS::MATERIAL_FLAG_DOUBLE_SIDED] = true;
10385
10386 overdraw_material = create_overdraw_debug_material();
10387 copy_shader.set_conditional(CopyShaderGLES2::USE_8BIT_HDR, !use_fp16_fb);
10388 canvas_shader.set_conditional(CanvasShaderGLES2::USE_DEPTH_SHADOWS, read_depth_supported);
10389
10390 canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("display/use_2d_pixel_snap", false));
10391
10392 npo2_textures_available = true;
10393 //fragment_lighting=false;
10394 _rinfo.texture_mem = 0;
10395 current_env = NULL;
10396 current_rt = NULL;
10397 current_vd = NULL;
10398 current_debug = VS::SCENARIO_DEBUG_DISABLED;
10399 camera_ortho = false;
10400
10401 glGenBuffers(1, &gui_quad_buffer);
10402 glBindBuffer(GL_ARRAY_BUFFER, gui_quad_buffer);
10403 #ifdef GLES_NO_CLIENT_ARRAYS //WebGL specific implementation.
10404 glBufferData(GL_ARRAY_BUFFER, 8 * MAX_POLYGON_VERTICES, NULL, GL_DYNAMIC_DRAW);
10405 #else
10406 glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
10407 #endif
10408 glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
10409
10410 #ifdef GLES_NO_CLIENT_ARRAYS //webgl indices buffer
10411 glGenBuffers(1, &indices_buffer);
10412 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer);
10413 glBufferData(GL_ELEMENT_ARRAY_BUFFER, 16 * 1024, NULL, GL_DYNAMIC_DRAW);
10414 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // unbind
10415 #endif
10416
10417 shader_time_rollback = GLOBAL_DEF("rasterizer/shader_time_rollback", 300);
10418 time_scale = 1.0f;
10419
10420 using_canvas_bg = false;
10421 _update_framebuffer();
10422 DEBUG_TEST_ERROR("Initializing");
10423 }
10424
finish()10425 void RasterizerGLES2::finish() {
10426
10427 free(default_material);
10428 free(shadow_material);
10429 free(shadow_material_double_sided);
10430 free(canvas_shadow_blur);
10431 free(overdraw_material);
10432 }
10433
get_render_info(VS::RenderInfo p_info)10434 int RasterizerGLES2::get_render_info(VS::RenderInfo p_info) {
10435
10436 switch (p_info) {
10437
10438 case VS::INFO_OBJECTS_IN_FRAME: {
10439
10440 return _rinfo.object_count;
10441 } break;
10442 case VS::INFO_VERTICES_IN_FRAME: {
10443
10444 return _rinfo.vertex_count;
10445 } break;
10446 case VS::INFO_MATERIAL_CHANGES_IN_FRAME: {
10447
10448 return _rinfo.mat_change_count;
10449 } break;
10450 case VS::INFO_SHADER_CHANGES_IN_FRAME: {
10451
10452 return _rinfo.shader_change_count;
10453 } break;
10454 case VS::INFO_DRAW_CALLS_IN_FRAME: {
10455
10456 return _rinfo.draw_calls;
10457 } break;
10458 case VS::INFO_SURFACE_CHANGES_IN_FRAME: {
10459
10460 return _rinfo.surface_count;
10461 } break;
10462 case VS::INFO_USAGE_VIDEO_MEM_TOTAL: {
10463
10464 return 0;
10465 } break;
10466 case VS::INFO_VIDEO_MEM_USED: {
10467
10468 return get_render_info(VS::INFO_TEXTURE_MEM_USED) + get_render_info(VS::INFO_VERTEX_MEM_USED);
10469 } break;
10470 case VS::INFO_TEXTURE_MEM_USED: {
10471
10472 return _rinfo.texture_mem;
10473 } break;
10474 case VS::INFO_VERTEX_MEM_USED: {
10475
10476 return 0;
10477 } break;
10478 }
10479
10480 return 0;
10481 }
10482
set_extensions(const char * p_strings)10483 void RasterizerGLES2::set_extensions(const char *p_strings) {
10484
10485 Vector<String> strings = String(p_strings).split(" ", false);
10486 for (int i = 0; i < strings.size(); i++) {
10487
10488 extensions.insert(strings[i]);
10489 // print_line(strings[i]);
10490 }
10491 }
10492
needs_to_draw_next_frame() const10493 bool RasterizerGLES2::needs_to_draw_next_frame() const {
10494
10495 return draw_next_frame;
10496 }
10497
has_feature(VS::Features p_feature) const10498 bool RasterizerGLES2::has_feature(VS::Features p_feature) const {
10499
10500 switch (p_feature) {
10501 case VS::FEATURE_SHADERS: return true;
10502 case VS::FEATURE_NEEDS_RELOAD_HOOK: return use_reload_hooks;
10503 default: return false;
10504 }
10505 }
10506
reload_vram()10507 void RasterizerGLES2::reload_vram() {
10508
10509 glEnable(GL_DEPTH_TEST);
10510 glDepthFunc(GL_LEQUAL);
10511 glFrontFace(GL_CW);
10512
10513 //do a single initial clear
10514 glClearColor(0, 0, 0, 1);
10515 //glClearDepth(1.0);
10516 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
10517
10518 glGenTextures(1, &white_tex);
10519 unsigned char whitetexdata[8 * 8 * 3];
10520 for (int i = 0; i < 8 * 8 * 3; i++) {
10521 whitetexdata[i] = 255;
10522 }
10523 glActiveTexture(GL_TEXTURE0);
10524 glBindTexture(GL_TEXTURE_2D, white_tex);
10525 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, whitetexdata);
10526 glGenerateMipmap(GL_TEXTURE_2D);
10527 glBindTexture(GL_TEXTURE_2D, 0);
10528
10529 List<RID> textures;
10530 texture_owner.get_owned_list(&textures);
10531 keep_copies = false;
10532 for (List<RID>::Element *E = textures.front(); E; E = E->next()) {
10533
10534 RID tid = E->get();
10535 Texture *t = texture_owner.get(tid);
10536 ERR_CONTINUE(!t);
10537 t->tex_id = 0;
10538 t->data_size = 0;
10539 glGenTextures(1, &t->tex_id);
10540 t->active = false;
10541 if (t->render_target)
10542 continue;
10543 texture_allocate(tid, t->width, t->height, t->format, t->flags);
10544 bool had_image = false;
10545 for (int i = 0; i < 6; i++) {
10546 if (!t->image[i].empty()) {
10547 texture_set_data(tid, t->image[i], VS::CubeMapSide(i));
10548 had_image = true;
10549 }
10550 }
10551
10552 if (!had_image && t->reloader) {
10553 Object *rl = ObjectDB::get_instance(t->reloader);
10554 if (rl)
10555 rl->call(t->reloader_func, tid);
10556 }
10557 }
10558 keep_copies = true;
10559
10560 List<RID> render_targets;
10561 render_target_owner.get_owned_list(&render_targets);
10562 for (List<RID>::Element *E = render_targets.front(); E; E = E->next()) {
10563 RenderTarget *rt = render_target_owner.get(E->get());
10564
10565 int w = rt->width;
10566 int h = rt->height;
10567 rt->width = 0;
10568 rt->height = 0;
10569 render_target_set_size(E->get(), w, h);
10570 }
10571
10572 List<RID> meshes;
10573 mesh_owner.get_owned_list(&meshes);
10574 for (List<RID>::Element *E = meshes.front(); E; E = E->next()) {
10575
10576 Mesh *mesh = mesh_owner.get(E->get());
10577 Vector<Surface *> surfaces = mesh->surfaces;
10578 mesh->surfaces.clear();
10579 for (int i = 0; i < surfaces.size(); i++) {
10580 mesh_add_surface(E->get(), surfaces[i]->primitive, surfaces[i]->data, surfaces[i]->morph_data, surfaces[i]->alpha_sort);
10581 mesh_surface_set_material(E->get(), i, surfaces[i]->material);
10582
10583 if (surfaces[i]->array_local != 0) {
10584 memfree(surfaces[i]->array_local);
10585 };
10586 if (surfaces[i]->index_array_local != 0) {
10587 memfree(surfaces[i]->index_array_local);
10588 };
10589
10590 memdelete(surfaces[i]);
10591 }
10592 }
10593
10594 List<RID> skeletons;
10595 skeleton_owner.get_owned_list(&skeletons);
10596 for (List<RID>::Element *E = skeletons.front(); E; E = E->next()) {
10597
10598 Skeleton *sk = skeleton_owner.get(E->get());
10599 if (!sk->tex_id)
10600 continue; //does not use hw transform, leave alone
10601
10602 Vector<Skeleton::Bone> bones = sk->bones;
10603 sk->bones.clear();
10604 sk->tex_id = 0;
10605 sk->pixel_size = 1.0;
10606 skeleton_resize(E->get(), bones.size());
10607 sk->bones = bones;
10608 }
10609
10610 List<RID> multimeshes;
10611 multimesh_owner.get_owned_list(&multimeshes);
10612 for (List<RID>::Element *E = multimeshes.front(); E; E = E->next()) {
10613
10614 MultiMesh *mm = multimesh_owner.get(E->get());
10615 if (!mm->tex_id)
10616 continue; //does not use hw transform, leave alone
10617
10618 Vector<MultiMesh::Element> elements = mm->elements;
10619 mm->elements.clear();
10620
10621 mm->tw = 1;
10622 mm->th = 1;
10623 mm->tex_id = 0;
10624 mm->last_pass = 0;
10625 mm->visible = -1;
10626
10627 multimesh_set_instance_count(E->get(), elements.size());
10628 mm->elements = elements;
10629 }
10630
10631 if (framebuffer.fbo != 0) {
10632
10633 framebuffer.fbo = 0;
10634 framebuffer.depth = 0;
10635 framebuffer.color = 0;
10636
10637 for (int i = 0; i < 3; i++) {
10638 framebuffer.blur[i].fbo = 0;
10639 framebuffer.blur[i].color = 0;
10640 }
10641
10642 framebuffer.luminance.clear();
10643 }
10644
10645 for (int i = 0; i < near_shadow_buffers.size(); i++) {
10646 near_shadow_buffers[i].init(near_shadow_buffers[i].size, !use_rgba_shadowmaps);
10647 }
10648
10649 blur_shadow_buffer.init(near_shadow_buffers[0].size, !use_rgba_shadowmaps);
10650
10651 canvas_shader.clear_caches();
10652 material_shader.clear_caches();
10653 blur_shader.clear_caches();
10654 copy_shader.clear_caches();
10655
10656 List<RID> shaders;
10657 shader_owner.get_owned_list(&shaders);
10658 for (List<RID>::Element *E = shaders.front(); E; E = E->next()) {
10659
10660 Shader *s = shader_owner.get(E->get());
10661 s->custom_code_id = 0;
10662 s->version = 1;
10663 s->valid = false;
10664 shader_set_mode(E->get(), s->mode);
10665 }
10666
10667 List<RID> materials;
10668 material_owner.get_owned_list(&materials);
10669 for (List<RID>::Element *E = materials.front(); E; E = E->next()) {
10670
10671 Material *m = material_owner.get(E->get());
10672 RID shader = m->shader;
10673 m->shader_version = 0;
10674 material_set_shader(E->get(), shader);
10675 }
10676 }
10677
set_use_framebuffers(bool p_use)10678 void RasterizerGLES2::set_use_framebuffers(bool p_use) {
10679
10680 use_framebuffers = p_use;
10681 }
10682
get_singleton()10683 RasterizerGLES2 *RasterizerGLES2::get_singleton() {
10684
10685 return _singleton;
10686 };
10687
10688 int RasterizerGLES2::RenderList::max_elements = RenderList::DEFAULT_MAX_ELEMENTS;
10689
set_force_16_bits_fbo(bool p_force)10690 void RasterizerGLES2::set_force_16_bits_fbo(bool p_force) {
10691
10692 use_16bits_fbo = p_force;
10693 }
10694
RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,bool p_default_fragment_lighting,bool p_use_reload_hooks)10695 RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays, bool p_keep_ram_copy, bool p_default_fragment_lighting, bool p_use_reload_hooks) {
10696
10697 _singleton = this;
10698 shrink_textures_x2 = false;
10699 RenderList::max_elements = GLOBAL_DEF("rasterizer/max_render_elements", (int)RenderList::DEFAULT_MAX_ELEMENTS);
10700 if (RenderList::max_elements > 64000)
10701 RenderList::max_elements = 64000;
10702 if (RenderList::max_elements < 1024)
10703 RenderList::max_elements = 1024;
10704
10705 opaque_render_list.init();
10706 alpha_render_list.init();
10707
10708 skinned_buffer_size = GLOBAL_DEF("rasterizer/skeleton_buffer_size_kb", DEFAULT_SKINNED_BUFFER_SIZE);
10709 if (skinned_buffer_size < 256)
10710 skinned_buffer_size = 256;
10711 if (skinned_buffer_size > 16384)
10712 skinned_buffer_size = 16384;
10713 skinned_buffer_size *= 1024;
10714 skinned_buffer = memnew_arr(uint8_t, skinned_buffer_size);
10715
10716 keep_copies = p_keep_ram_copy;
10717 use_reload_hooks = p_use_reload_hooks;
10718 pack_arrays = p_compress_arrays;
10719 p_default_fragment_lighting = false;
10720 fragment_lighting = GLOBAL_DEF("rasterizer/use_fragment_lighting", true);
10721 read_depth_supported = true; //todo check for extension
10722 shadow_filter = ShadowFilterTechnique((int)(GLOBAL_DEF("rasterizer/shadow_filter", SHADOW_FILTER_PCF5)));
10723 Globals::get_singleton()->set_custom_property_info("rasterizer/shadow_filter", PropertyInfo(Variant::INT, "rasterizer/shadow_filter", PROPERTY_HINT_ENUM, "None,PCF5,PCF13,ESM"));
10724 use_fp16_fb = bool(GLOBAL_DEF("rasterizer/fp16_framebuffer", true));
10725 use_shadow_mapping = true;
10726 use_fast_texture_filter = !bool(GLOBAL_DEF("rasterizer/trilinear_mipmap_filter", true));
10727 low_memory_2d = bool(GLOBAL_DEF("rasterizer/low_memory_2d_mode", false));
10728 skel_default.resize(1024 * 4);
10729 for (int i = 0; i < 1024 / 3; i++) {
10730
10731 float *ptr = skel_default.ptr();
10732 ptr += i * 4 * 4;
10733 ptr[0] = 1.0;
10734 ptr[1] = 0.0;
10735 ptr[2] = 0.0;
10736 ptr[3] = 0.0;
10737
10738 ptr[4] = 0.0;
10739 ptr[5] = 1.0;
10740 ptr[6] = 0.0;
10741 ptr[7] = 0.0;
10742
10743 ptr[8] = 0.0;
10744 ptr[9] = 0.0;
10745 ptr[10] = 1.0;
10746 ptr[12] = 0.0;
10747 }
10748
10749 base_framebuffer = 0;
10750 frame = 0;
10751 scaled_time = 0.0;
10752 draw_next_frame = false;
10753 use_framebuffers = true;
10754 framebuffer.active = false;
10755 tc0_id_cache = 0;
10756 tc0_idx = 0;
10757 use_16bits_fbo = false;
10758 };
10759
restore_framebuffer()10760 void RasterizerGLES2::restore_framebuffer() {
10761
10762 glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
10763 }
10764
~RasterizerGLES2()10765 RasterizerGLES2::~RasterizerGLES2() {
10766
10767 memdelete_arr(skinned_buffer);
10768 };
10769
10770 #endif
10771