1 /*************************************************************************/
2 /* rasterizer_iphone.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 IPHONE_ENABLED
31
32 #include "rasterizer_iphone.h"
33 #include "globals.h"
34 #include "os/os.h"
35 #include <stdio.h>
36
_gl_load_transform(const Transform & tr)37 _FORCE_INLINE_ static void _gl_load_transform(const Transform &tr) {
38
39 GLfloat matrix[16] = { /* build a 16x16 matrix */
40 tr.basis.elements[0][0],
41 tr.basis.elements[1][0],
42 tr.basis.elements[2][0],
43 0,
44 tr.basis.elements[0][1],
45 tr.basis.elements[1][1],
46 tr.basis.elements[2][1],
47 0,
48 tr.basis.elements[0][2],
49 tr.basis.elements[1][2],
50 tr.basis.elements[2][2],
51 0,
52 tr.origin.x,
53 tr.origin.y,
54 tr.origin.z,
55 1
56 };
57
58 glLoadMatrixf(matrix);
59 };
60
_gl_mult_transform(const Transform & tr)61 _FORCE_INLINE_ static void _gl_mult_transform(const Transform &tr) {
62
63 GLfloat matrix[16] = { /* build a 16x16 matrix */
64 tr.basis.elements[0][0],
65 tr.basis.elements[1][0],
66 tr.basis.elements[2][0],
67 0,
68 tr.basis.elements[0][1],
69 tr.basis.elements[1][1],
70 tr.basis.elements[2][1],
71 0,
72 tr.basis.elements[0][2],
73 tr.basis.elements[1][2],
74 tr.basis.elements[2][2],
75 0,
76 tr.origin.x,
77 tr.origin.y,
78 tr.origin.z,
79 1
80 };
81
82 glMultMatrixf(matrix);
83 };
84
85 static const GLenum prim_type[] = { GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
86
_draw_primitive(int p_points,const float * p_vertices,const float * p_normals,const float * p_colors,const float * p_uvs,const Plane * p_tangents=NULL,int p_instanced=1)87 static void _draw_primitive(int p_points, const float *p_vertices, const float *p_normals, const float *p_colors, const float *p_uvs, const Plane *p_tangents = NULL, int p_instanced = 1) {
88
89 ERR_FAIL_COND(!p_vertices);
90 ERR_FAIL_COND(p_points < 1 || p_points > 4);
91
92 GLenum type = prim_type[p_points - 1];
93
94 if (!p_colors) {
95 glColor4f(1, 1, 1, 1);
96 };
97
98 glEnableClientState(GL_VERTEX_ARRAY);
99 glVertexPointer(3, GL_FLOAT, 0, (GLvoid *)p_vertices);
100
101 if (p_normals) {
102
103 glEnableClientState(GL_NORMAL_ARRAY);
104 glNormalPointer(GL_FLOAT, 0, (GLvoid *)p_normals);
105 };
106
107 if (p_colors) {
108 glEnableClientState(GL_COLOR_ARRAY);
109 glColorPointer(4, GL_FLOAT, 0, p_colors);
110 };
111
112 if (p_uvs) {
113
114 glClientActiveTexture(GL_TEXTURE0);
115 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
116 glTexCoordPointer(2, GL_FLOAT, 0, p_uvs);
117 };
118
119 glDrawArrays(type, 0, p_points);
120
121 glDisableClientState(GL_VERTEX_ARRAY);
122 glDisableClientState(GL_NORMAL_ARRAY);
123 glDisableClientState(GL_COLOR_ARRAY);
124 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
125 };
126
127 /* TEXTURE API */
128
_get_gl_image_and_format(const Image & p_image,Image::Format p_format,uint32_t p_flags,GLenum & r_gl_format,int & r_gl_components,bool & r_has_alpha_cache)129 static Image _get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, int &r_gl_components, bool &r_has_alpha_cache) {
130
131 r_has_alpha_cache = false;
132 Image image = p_image;
133
134 switch (p_format) {
135
136 case Image::FORMAT_GRAYSCALE: {
137 r_gl_components = 1;
138 r_gl_format = GL_LUMINANCE;
139
140 } break;
141 case Image::FORMAT_INTENSITY: {
142
143 image.convert(Image::FORMAT_RGBA);
144 r_gl_components = 4;
145 r_gl_format = GL_RGBA;
146 r_has_alpha_cache = true;
147 } break;
148 case Image::FORMAT_GRAYSCALE_ALPHA: {
149
150 image.convert(Image::FORMAT_RGBA);
151 r_gl_components = 4;
152 r_gl_format = GL_RGBA;
153 r_has_alpha_cache = true;
154 } break;
155
156 case Image::FORMAT_INDEXED: {
157
158 image.convert(Image::FORMAT_RGB);
159 r_gl_components = 3;
160 r_gl_format = GL_RGB;
161
162 } break;
163
164 case Image::FORMAT_INDEXED_ALPHA: {
165
166 image.convert(Image::FORMAT_RGBA);
167 r_gl_components = 4;
168 r_gl_format = GL_RGB;
169 r_has_alpha_cache = true;
170
171 } break;
172 case Image::FORMAT_RGB: {
173
174 r_gl_components = 3;
175 r_gl_format = GL_RGB;
176 } break;
177 case Image::FORMAT_RGBA: {
178
179 r_gl_components = 4;
180 r_gl_format = GL_RGBA;
181 r_has_alpha_cache = true;
182 } break;
183 default: {
184
185 ERR_FAIL_V(Image());
186 }
187 }
188
189 return image;
190 }
191
texture_create()192 RID RasterizerIPhone::texture_create() {
193
194 Texture *texture = memnew(Texture);
195 ERR_FAIL_COND_V(!texture, RID());
196 glGenTextures(1, &texture->tex_id);
197 texture->active = false;
198
199 return texture_owner.make_rid(texture);
200 }
201
texture_allocate(RID p_texture,int p_width,int p_height,Image::Format p_format,uint32_t p_flags)202 void RasterizerIPhone::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
203
204 bool has_alpha_cache;
205 int components;
206 GLenum format;
207
208 Texture *texture = texture_owner.get(p_texture);
209 ERR_FAIL_COND(!texture);
210 texture->width = p_width;
211 texture->height = p_height;
212 texture->format = p_format;
213 texture->flags = p_flags;
214 //texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
215 texture->target = GL_TEXTURE_2D;
216
217 _get_gl_image_and_format(Image(), texture->format, texture->flags, format, components, has_alpha_cache);
218
219 texture->gl_components_cache = components;
220 texture->gl_format_cache = format;
221 texture->format_has_alpha = has_alpha_cache;
222 texture->has_alpha = false; //by default it doesn't have alpha unless something with alpha is blitteds
223
224 glBindTexture(texture->target, texture->tex_id);
225
226 if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) {
227 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
228 }
229
230 if (texture->target == GL_TEXTURE_2D) {
231 glTexImage2D(texture->target, 0, format, texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE, NULL);
232 }
233
234 /*
235 else {
236 //cubemappor
237 for (int i=0;i<6;i++)
238 glTexImage2D(_cube_side_enum[i], 0, format, texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE,NULL);
239 }
240 */
241
242 glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering
243
244 if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
245
246 glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
247 if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) {
248 //glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
249 };
250 }
251
252 if (texture->flags & VS::TEXTURE_FLAG_REPEAT /* && texture->target != GL_TEXTURE_CUBE_MAP*/) {
253
254 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
255 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
256 } else {
257
258 //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
259 glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
260 glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
261 }
262
263 texture->active = true;
264 }
265
texture_blit_rect(RID p_texture,int p_x,int p_y,const Image & p_image,VS::CubeMapSide p_cube_side)266 void RasterizerIPhone::texture_blit_rect(RID p_texture, int p_x, int p_y, const Image &p_image, VS::CubeMapSide p_cube_side) {
267
268 Texture *texture = texture_owner.get(p_texture);
269
270 ERR_FAIL_COND(!texture);
271 ERR_FAIL_COND(!texture->active);
272 ERR_FAIL_COND(texture->format != p_image.get_format());
273
274 int components;
275 GLenum format;
276 bool alpha;
277
278 Image img = _get_gl_image_and_format(p_image, p_image.get_format(), texture->flags, format, components, alpha);
279
280 if (img.detect_alpha())
281 texture->has_alpha = true;
282
283 GLenum blit_target = GL_TEXTURE_2D; //(texture->target == GL_TEXTURE_CUBE_MAP)?_cube_side_enum[p_cube_side]:GL_TEXTURE_2D;
284
285 DVector<uint8_t>::Read read = img.get_data().read();
286
287 glBindTexture(texture->target, texture->tex_id);
288 glTexSubImage2D(blit_target, 0, p_x, p_y, img.get_width(), img.get_height(), format, GL_UNSIGNED_BYTE, read.ptr());
289
290 //glGenerateMipmap( texture->target );
291 }
292
texture_get_rect(RID p_texture,int p_x,int p_y,int p_width,int p_height,VS::CubeMapSide p_cube_side) const293 Image RasterizerIPhone::texture_get_rect(RID p_texture, int p_x, int p_y, int p_width, int p_height, VS::CubeMapSide p_cube_side) const {
294
295 return Image();
296 }
texture_set_flags(RID p_texture,uint32_t p_flags)297 void RasterizerIPhone::texture_set_flags(RID p_texture, uint32_t p_flags) {
298
299 Texture *texture = texture_owner.get(p_texture);
300 ERR_FAIL_COND(!texture);
301
302 glBindTexture(texture->target, texture->tex_id);
303 uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP;
304 texture->flags = p_flags | cube; // can't remove a cube from being a cube
305
306 if (texture->flags & VS::TEXTURE_FLAG_REPEAT /*&& texture->target != GL_TEXTURE_CUBE_MAP*/) {
307
308 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
309 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
310 } else {
311 //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
312 glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
313 glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
314 }
315
316 if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
317
318 glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
319 if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS)
320 glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
321
322 } else {
323
324 glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // nearest
325 }
326 }
texture_get_flags(RID p_texture) const327 uint32_t RasterizerIPhone::texture_get_flags(RID p_texture) const {
328
329 Texture *texture = texture_owner.get(p_texture);
330
331 ERR_FAIL_COND_V(!texture, 0);
332
333 return texture->flags;
334 }
texture_get_format(RID p_texture) const335 Image::Format RasterizerIPhone::texture_get_format(RID p_texture) const {
336
337 Texture *texture = texture_owner.get(p_texture);
338
339 ERR_FAIL_COND_V(!texture, Image::FORMAT_GRAYSCALE);
340
341 return texture->format;
342 }
texture_get_width(RID p_texture) const343 uint32_t RasterizerIPhone::texture_get_width(RID p_texture) const {
344
345 Texture *texture = texture_owner.get(p_texture);
346
347 ERR_FAIL_COND_V(!texture, 0);
348
349 return texture->width;
350 }
texture_get_height(RID p_texture) const351 uint32_t RasterizerIPhone::texture_get_height(RID p_texture) const {
352
353 Texture *texture = texture_owner.get(p_texture);
354
355 ERR_FAIL_COND_V(!texture, 0);
356
357 return texture->height;
358 }
359
texture_has_alpha(RID p_texture) const360 bool RasterizerIPhone::texture_has_alpha(RID p_texture) const {
361
362 Texture *texture = texture_owner.get(p_texture);
363
364 ERR_FAIL_COND_V(!texture, 0);
365
366 return texture->has_alpha;
367 }
368
369 /* SHADER API */
370
shader_create()371 RID RasterizerIPhone::shader_create() {
372
373 return RID();
374 }
375
shader_node_add(RID p_shader,VS::ShaderNodeType p_type,int p_id)376 void RasterizerIPhone::shader_node_add(RID p_shader, VS::ShaderNodeType p_type, int p_id) {
377 }
shader_node_remove(RID p_shader,int p_id)378 void RasterizerIPhone::shader_node_remove(RID p_shader, int p_id) {
379 }
shader_node_change_type(RID p_shader,int p_id,VS::ShaderNodeType p_type)380 void RasterizerIPhone::shader_node_change_type(RID p_shader, int p_id, VS::ShaderNodeType p_type) {
381 }
shader_node_set_param(RID p_shader,int p_id,const Variant & p_value)382 void RasterizerIPhone::shader_node_set_param(RID p_shader, int p_id, const Variant &p_value) {
383 }
384
shader_get_node_list(RID p_shader,List<int> * p_node_list) const385 void RasterizerIPhone::shader_get_node_list(RID p_shader, List<int> *p_node_list) const {
386 }
shader_node_get_type(RID p_shader,int p_id) const387 VS::ShaderNodeType RasterizerIPhone::shader_node_get_type(RID p_shader, int p_id) const {
388
389 return VS::NODE_ADD;
390 }
shader_node_get_param(RID p_shader,int p_id) const391 Variant RasterizerIPhone::shader_node_get_param(RID p_shader, int p_id) const {
392
393 return Variant();
394 }
395
shader_connect(RID p_shader,int p_src_id,int p_src_slot,int p_dst_id,int p_dst_slot)396 void RasterizerIPhone::shader_connect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) {
397 }
shader_is_connected(RID p_shader,int p_src_id,int p_src_slot,int p_dst_id,int p_dst_slot) const398 bool RasterizerIPhone::shader_is_connected(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) const {
399
400 return false;
401 }
402
shader_disconnect(RID p_shader,int p_src_id,int p_src_slot,int p_dst_id,int p_dst_slot)403 void RasterizerIPhone::shader_disconnect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) {
404 }
405
shader_get_connections(RID p_shader,List<VS::ShaderConnection> * p_connections) const406 void RasterizerIPhone::shader_get_connections(RID p_shader, List<VS::ShaderConnection> *p_connections) const {
407 }
408
shader_clear(RID p_shader)409 void RasterizerIPhone::shader_clear(RID p_shader) {
410 }
411
412 /* COMMON MATERIAL API */
413
material_set_param(RID p_material,const StringName & p_param,const Variant & p_value)414 void RasterizerIPhone::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
415 }
material_get_param(RID p_material,const StringName & p_param) const416 Variant RasterizerIPhone::material_get_param(RID p_material, const StringName &p_param) const {
417
418 return Variant();
419 }
material_get_param_list(RID p_material,List<String> * p_param_list) const420 void RasterizerIPhone::material_get_param_list(RID p_material, List<String> *p_param_list) const {
421 }
422
material_set_flag(RID p_material,VS::MaterialFlag p_flag,bool p_enabled)423 void RasterizerIPhone::material_set_flag(RID p_material, VS::MaterialFlag p_flag, bool p_enabled) {
424 }
material_get_flag(RID p_material,VS::MaterialFlag p_flag) const425 bool RasterizerIPhone::material_get_flag(RID p_material, VS::MaterialFlag p_flag) const {
426
427 return false;
428 }
429
material_set_blend_mode(RID p_material,VS::MaterialBlendMode p_mode)430 void RasterizerIPhone::material_set_blend_mode(RID p_material, VS::MaterialBlendMode p_mode) {
431 }
material_get_blend_mode(RID p_material) const432 VS::MaterialBlendMode RasterizerIPhone::material_get_blend_mode(RID p_material) const {
433
434 return VS::MATERIAL_BLEND_MODE_ADD;
435 }
436
material_set_line_width(RID p_material,float p_line_width)437 void RasterizerIPhone::material_set_line_width(RID p_material, float p_line_width) {
438 }
material_get_line_width(RID p_material) const439 float RasterizerIPhone::material_get_line_width(RID p_material) const {
440
441 return 0;
442 }
443
444 /* FIXED MATERIAL */
445
material_create()446 RID RasterizerIPhone::material_create() {
447
448 return material_owner.make_rid(memnew(Material));
449 }
450
fixed_material_set_parameter(RID p_material,VS::FixedMaterialParam p_parameter,const Variant & p_value)451 void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedMaterialParam p_parameter, const Variant &p_value) {
452
453 Material *m = material_owner.get(p_material);
454 ERR_FAIL_COND(!m);
455 ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX);
456
457 m->parameters[p_parameter] = p_value;
458 }
fixed_material_get_parameter(RID p_material,VS::FixedMaterialParam p_parameter) const459 Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material, VS::FixedMaterialParam p_parameter) const {
460
461 Material *m = material_owner.get(p_material);
462 ERR_FAIL_COND_V(!m, Variant());
463 ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, Variant());
464
465 return m->parameters[p_parameter];
466 }
467
fixed_material_set_texture(RID p_material,VS::FixedMaterialParam p_parameter,RID p_texture)468 void RasterizerIPhone::fixed_material_set_texture(RID p_material, VS::FixedMaterialParam p_parameter, RID p_texture) {
469
470 Material *m = material_owner.get(p_material);
471 ERR_FAIL_COND(!m);
472 ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX);
473
474 m->textures[p_parameter] = p_texture;
475 }
fixed_material_get_texture(RID p_material,VS::FixedMaterialParam p_parameter) const476 RID RasterizerIPhone::fixed_material_get_texture(RID p_material, VS::FixedMaterialParam p_parameter) const {
477
478 Material *m = material_owner.get(p_material);
479 ERR_FAIL_COND_V(!m, RID());
480 ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, Variant());
481
482 return m->textures[p_parameter];
483 }
484
fixed_material_set_detail_blend_mode(RID p_material,VS::MaterialBlendMode p_mode)485 void RasterizerIPhone::fixed_material_set_detail_blend_mode(RID p_material, VS::MaterialBlendMode p_mode) {
486
487 Material *m = material_owner.get(p_material);
488 ERR_FAIL_COND(!m);
489
490 m->detail_blend_mode = p_mode;
491 }
fixed_material_get_detail_blend_mode(RID p_material) const492 VS::MaterialBlendMode RasterizerIPhone::fixed_material_get_detail_blend_mode(RID p_material) const {
493
494 Material *m = material_owner.get(p_material);
495 ERR_FAIL_COND_V(!m, VS::MATERIAL_BLEND_MODE_MIX);
496
497 return m->detail_blend_mode;
498 }
499
fixed_material_set_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter,VS::FixedMaterialTexCoordMode p_mode)500 void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material, VS::FixedMaterialParam p_parameter, VS::FixedMaterialTexCoordMode p_mode) {
501
502 Material *m = material_owner.get(p_material);
503 ERR_FAIL_COND(!m);
504 ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX);
505
506 m->texcoord_mode[p_parameter] = p_mode;
507 }
fixed_material_get_texcoord_mode(RID p_material,VS::FixedMaterialParam p_parameter) const508 VS::FixedMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material, VS::FixedMaterialParam p_parameter) const {
509
510 Material *m = material_owner.get(p_material);
511 ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXCOORD_TEXGEN);
512 ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, VS::FIXED_MATERIAL_TEXCOORD_UV);
513
514 return m->texcoord_mode[p_parameter]; // for now
515 }
516
fixed_material_set_texgen_mode(RID p_material,VS::FixedMaterialTexGenMode p_mode)517 void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material, VS::FixedMaterialTexGenMode p_mode) {
518
519 Material *m = material_owner.get(p_material);
520 ERR_FAIL_COND(!m);
521
522 m->texgen_mode = p_mode;
523 };
524
fixed_material_get_texgen_mode(RID p_material) const525 VS::FixedMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const {
526
527 Material *m = material_owner.get(p_material);
528 ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXGEN_SPHERE);
529
530 return m->texgen_mode;
531 };
532
fixed_material_set_uv_transform(RID p_material,const Transform & p_transform)533 void RasterizerIPhone::fixed_material_set_uv_transform(RID p_material, const Transform &p_transform) {
534
535 Material *m = material_owner.get(p_material);
536 ERR_FAIL_COND(!m);
537
538 m->uv_transform = p_transform;
539 }
fixed_material_get_uv_transform(RID p_material) const540 Transform RasterizerIPhone::fixed_material_get_uv_transform(RID p_material) const {
541
542 Material *m = material_owner.get(p_material);
543 ERR_FAIL_COND_V(!m, Transform());
544
545 return m->uv_transform;
546 }
547
548 /* SHADER MATERIAL */
549
shader_material_create() const550 RID RasterizerIPhone::shader_material_create() const {
551
552 return RID();
553 }
554
shader_material_set_vertex_shader(RID p_material,RID p_shader,bool p_owned)555 void RasterizerIPhone::shader_material_set_vertex_shader(RID p_material, RID p_shader, bool p_owned) {
556 }
shader_material_get_vertex_shader(RID p_material) const557 RID RasterizerIPhone::shader_material_get_vertex_shader(RID p_material) const {
558
559 return RID();
560 }
561
shader_material_set_fragment_shader(RID p_material,RID p_shader,bool p_owned)562 void RasterizerIPhone::shader_material_set_fragment_shader(RID p_material, RID p_shader, bool p_owned) {
563 }
shader_material_get_fragment_shader(RID p_material) const564 RID RasterizerIPhone::shader_material_get_fragment_shader(RID p_material) const {
565
566 return RID();
567 }
568
569 /* MESH API */
570
mesh_create()571 RID RasterizerIPhone::mesh_create() {
572
573 return mesh_owner.make_rid(memnew(Mesh));
574 }
575
mesh_add_surface(RID p_mesh,VS::PrimitiveType p_primitive,uint32_t p_format,int p_array_len,int p_index_array_len)576 void RasterizerIPhone::mesh_add_surface(RID p_mesh, VS::PrimitiveType p_primitive, uint32_t p_format, int p_array_len, int p_index_array_len) {
577
578 Mesh *mesh = mesh_owner.get(p_mesh);
579 ERR_FAIL_COND(!mesh);
580
581 ERR_FAIL_COND((p_format & VS::ARRAY_FORMAT_VERTEX) == 0); // mandatory
582 ERR_FAIL_COND(p_array_len <= 0);
583 ERR_FAIL_COND(p_index_array_len == 0);
584 ERR_FAIL_INDEX(p_primitive, VS::PRIMITIVE_MAX);
585
586 Surface *surface = memnew(Surface);
587 ERR_FAIL_COND(!surface);
588
589 int total_elem_size = 0;
590
591 bool use_VBO = true; //glGenBuffersARB!=NULL; // TODO detect if it's in there
592 if (p_format & VS::ARRAY_FORMAT_WEIGHTS) {
593
594 use_VBO = false;
595 }
596
597 for (int i = 0; i < VS::ARRAY_MAX; i++) {
598
599 Surface::ArrayData &ad = surface->array[i];
600 ad.size = 0;
601 ad.configured = false;
602 ad.ofs = 0;
603 int elem_size = 0;
604 int elem_count = 0;
605
606 if (!(p_format & (1 << i))) // no array
607 continue;
608
609 switch (i) {
610
611 case VS::ARRAY_VERTEX:
612 case VS::ARRAY_NORMAL: {
613
614 elem_size = 3 * sizeof(GLfloat); // vertex
615 elem_count = 3;
616 } break;
617 case VS::ARRAY_TANGENT: {
618 elem_size = 4 * sizeof(GLfloat); // vertex
619 elem_count = 4;
620
621 } break;
622 case VS::ARRAY_COLOR: {
623
624 elem_size = 4; /* RGBA */
625 elem_count = 4;
626 } break;
627 case VS::ARRAY_TEX_UV: {
628 elem_size = 2 * sizeof(GLfloat);
629 elem_count = 2;
630
631 } break;
632 case VS::ARRAY_WEIGHTS:
633 case VS::ARRAY_BONES: {
634
635 elem_size = VS::ARRAY_WEIGHTS_SIZE * sizeof(GLfloat);
636 elem_count = VS::ARRAY_WEIGHTS_SIZE;
637
638 } break;
639 case VS::ARRAY_INDEX: {
640
641 if (p_index_array_len <= 0) {
642 ERR_PRINT("p_index_array_len==NO_INDEX_ARRAY");
643 break;
644 }
645 /* determine wether using 8 or 16 bits indices */
646 if (p_index_array_len > (1 << 8)) {
647
648 elem_size = 2;
649 } else {
650 elem_size = 1;
651 }
652
653 if (use_VBO) {
654
655 glGenBuffers(1, &surface->index_id);
656 ERR_FAIL_COND(surface->index_id == 0);
657 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
658 glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_index_array_len * elem_size, NULL, GL_STATIC_DRAW);
659 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
660 } else {
661 surface->index_array_local = (uint8_t *)memalloc(p_index_array_len * elem_size);
662 };
663
664 surface->index_array_len = p_index_array_len; // only way it can exist
665 ad.ofs = 0;
666 ad.size = elem_size;
667 ad.configured = false;
668 ad.components = 1;
669
670 continue;
671 } break;
672 default: {
673 ERR_FAIL();
674 }
675 }
676
677 ad.ofs = total_elem_size;
678 ad.size = elem_size;
679 ad.components = elem_count;
680 total_elem_size += elem_size;
681 ad.configured = false;
682 }
683
684 surface->stride = total_elem_size;
685 surface->array_len = p_array_len;
686 surface->format = p_format;
687 surface->primitive = p_primitive;
688
689 /* bind the bigass buffers */
690 if (use_VBO) {
691
692 glGenBuffers(1, &surface->vertex_id);
693 ERR_FAIL_COND(surface->vertex_id == 0);
694 glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
695 glBufferData(GL_ARRAY_BUFFER, surface->array_len * surface->stride, NULL, GL_STATIC_DRAW);
696 glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
697 } else {
698 surface->array_local = (uint8_t *)memalloc(surface->array_len * surface->stride);
699 };
700
701 mesh->surfaces.push_back(surface);
702 }
703
mesh_surface_set_array(RID p_mesh,int p_surface,VS::ArrayType p_type,const Variant & p_array)704 Error RasterizerIPhone::mesh_surface_set_array(RID p_mesh, int p_surface, VS::ArrayType p_type, const Variant &p_array) {
705
706 ERR_FAIL_INDEX_V(p_type, VS::ARRAY_MAX, ERR_INVALID_PARAMETER);
707
708 Mesh *mesh = mesh_owner.get(p_mesh);
709 ERR_FAIL_COND_V(!mesh, ERR_INVALID_PARAMETER);
710 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), ERR_INVALID_PARAMETER);
711 Surface *surface = mesh->surfaces[p_surface];
712 ERR_FAIL_COND_V(!surface, ERR_INVALID_PARAMETER);
713
714 ERR_FAIL_COND_V(surface->array[p_type].size == 0, ERR_INVALID_PARAMETER);
715
716 Surface::ArrayData &a = surface->array[p_type];
717
718 switch (p_type) {
719
720 case VS::ARRAY_INDEX: {
721 ERR_FAIL_COND_V(surface->index_array_len <= 0, ERR_INVALID_DATA);
722 ERR_FAIL_COND_V(p_array.get_type() != Variant::INT_ARRAY, ERR_INVALID_PARAMETER);
723
724 DVector<int> indices = p_array;
725 ERR_FAIL_COND_V(indices.size() == 0, ERR_INVALID_PARAMETER);
726 ERR_FAIL_COND_V(indices.size() != surface->index_array_len, ERR_INVALID_PARAMETER);
727
728 /* determine wether using 16 or 32 bits indices */
729
730 if (surface->index_array_local == 0) {
731 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
732 };
733
734 DVector<int>::Read read = indices.read();
735 const int *src = read.ptr();
736
737 for (int i = 0; i < surface->index_array_len; i++) {
738
739 if (surface->index_array_local) {
740
741 if (a.size <= (1 << 8)) {
742 uint8_t v = src[i];
743
744 copymem(&surface->array_local[i * a.size], &v, a.size);
745 } else {
746 uint16_t v = src[i];
747
748 copymem(&surface->array_local[i * a.size], &v, a.size);
749 }
750
751 } else {
752 if (a.size <= (1 << 8)) {
753 uint8_t v = src[i];
754
755 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * a.size, a.size, &v);
756 } else {
757 uint16_t v = src[i];
758
759 glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * a.size, a.size, &v);
760 }
761 };
762 }
763 if (surface->index_array_local == 0) {
764 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
765 };
766 a.configured = true;
767 return OK;
768 } break;
769 case VS::ARRAY_VERTEX:
770 case VS::ARRAY_NORMAL: {
771
772 ERR_FAIL_COND_V(p_array.get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER);
773
774 DVector<Vector3> array = p_array;
775 ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER);
776
777 if (surface->array_local == 0) {
778 glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
779 };
780
781 DVector<Vector3>::Read read = array.read();
782 const Vector3 *src = read.ptr();
783
784 // setting vertices means regenerating the AABB
785 if (p_type == VS::ARRAY_VERTEX)
786 surface->aabb = AABB();
787
788 for (int i = 0; i < surface->array_len; i++) {
789
790 GLfloat vector[3] = { src[i].x, src[i].y, src[i].z };
791
792 if (surface->array_local == 0) {
793 glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, vector);
794 } else {
795 copymem(&surface->array_local[a.ofs + i * surface->stride], vector, a.size);
796 }
797
798 if (p_type == VS::ARRAY_VERTEX) {
799
800 if (i == 0) {
801
802 surface->aabb = AABB(src[i], Vector3());
803 } else {
804
805 surface->aabb.expand_to(src[i]);
806 }
807 }
808 }
809
810 if (surface->array_local == 0) {
811 glBindBuffer(GL_ARRAY_BUFFER, 0);
812 };
813
814 } break;
815 case VS::ARRAY_TANGENT: {
816
817 ERR_FAIL_COND_V(p_array.get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER);
818
819 DVector<real_t> array = p_array;
820
821 ERR_FAIL_COND_V(array.size() != surface->array_len * 4, ERR_INVALID_PARAMETER);
822
823 if (surface->array_local == 0) {
824 glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
825 };
826
827 DVector<real_t>::Read read = array.read();
828 const real_t *src = read.ptr();
829
830 for (int i = 0; i < surface->array_len; i++) {
831
832 GLfloat xyzw[4] = {
833 src[i * 4 + 0],
834 src[i * 4 + 1],
835 src[i * 4 + 2],
836 src[i * 4 + 3]
837 };
838
839 if (surface->array_local == 0) {
840
841 glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, xyzw);
842 } else {
843
844 copymem(&surface->array_local[a.ofs + i * surface->stride], xyzw, a.size);
845 };
846 }
847
848 if (surface->array_local == 0) {
849 glBindBuffer(GL_ARRAY_BUFFER, 0);
850 };
851 } break;
852 case VS::ARRAY_COLOR: {
853
854 ERR_FAIL_COND_V(p_array.get_type() != Variant::COLOR_ARRAY, ERR_INVALID_PARAMETER);
855
856 DVector<Color> array = p_array;
857
858 ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER);
859
860 if (surface->array_local == 0)
861 glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
862
863 DVector<Color>::Read read = array.read();
864 const Color *src = read.ptr();
865 surface->has_alpha_cache = false;
866
867 for (int i = 0; i < surface->array_len; i++) {
868
869 if (src[i].a < 0.98) // tolerate alpha a bit, for crappy exporters
870 surface->has_alpha_cache = true;
871 uint8_t colors[4] = { src[i].r * 255.0, src[i].g * 255.0, src[i].b * 255.0, src[i].a * 255.0 };
872 // I'm not sure if this is correct, endianness-wise, i should re-check the GL spec
873
874 if (surface->array_local == 0)
875 glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, colors);
876 else
877 copymem(&surface->array_local[a.ofs + i * surface->stride], colors, a.size);
878 }
879
880 if (surface->array_local == 0)
881 glBindBuffer(GL_ARRAY_BUFFER, 0);
882
883 } break;
884 case VS::ARRAY_TEX_UV: {
885
886 ERR_FAIL_COND_V(p_array.get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER);
887
888 DVector<Vector3> array = p_array;
889
890 ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER);
891
892 if (surface->array_local == 0)
893 glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
894
895 DVector<Vector3>::Read read = array.read();
896
897 const Vector3 *src = read.ptr();
898
899 for (int i = 0; i < surface->array_len; i++) {
900
901 GLfloat uv[2] = { src[i].x, src[i].y };
902
903 if (surface->array_local == 0)
904 glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, uv);
905 else
906 copymem(&surface->array_local[a.ofs + i * surface->stride], uv, a.size);
907 }
908
909 if (surface->array_local == 0)
910 glBindBuffer(GL_ARRAY_BUFFER, 0);
911
912 } break;
913 case VS::ARRAY_BONES:
914 case VS::ARRAY_WEIGHTS: {
915
916 ERR_FAIL_COND_V(p_array.get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER);
917
918 DVector<real_t> array = p_array;
919
920 ERR_FAIL_COND_V(array.size() != surface->array_len * VS::ARRAY_WEIGHTS_SIZE, ERR_INVALID_PARAMETER);
921
922 if (surface->array_local == 0)
923 glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
924
925 DVector<real_t>::Read read = array.read();
926
927 const real_t *src = read.ptr();
928
929 for (int i = 0; i < surface->array_len; i++) {
930
931 GLfloat data[VS::ARRAY_WEIGHTS_SIZE];
932 for (int j = 0; j < VS::ARRAY_WEIGHTS_SIZE; j++)
933 data[j] = src[i * VS::ARRAY_WEIGHTS_SIZE + j];
934
935 if (surface->array_local == 0)
936 glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, data);
937 else
938 copymem(&surface->array_local[a.ofs + i * surface->stride], data, a.size);
939 }
940
941 if (surface->array_local == 0)
942 glBindBuffer(GL_ARRAY_BUFFER, 0);
943 } break;
944 default: { ERR_FAIL_V(ERR_INVALID_PARAMETER); }
945 }
946
947 a.configured = true;
948
949 return OK;
950 }
mesh_surface_get_array(RID p_mesh,int p_surface,VS::ArrayType p_type) const951 Variant RasterizerIPhone::mesh_surface_get_array(RID p_mesh, int p_surface, VS::ArrayType p_type) const {
952
953 return Variant();
954 }
955
mesh_surface_set_material(RID p_mesh,int p_surface,RID p_material,bool p_owned)956 void RasterizerIPhone::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material, bool p_owned) {
957
958 Mesh *mesh = mesh_owner.get(p_mesh);
959 ERR_FAIL_COND(!mesh);
960 ERR_FAIL_INDEX(p_surface, mesh->surfaces.size());
961 Surface *surface = mesh->surfaces[p_surface];
962 ERR_FAIL_COND(!surface);
963
964 if (surface->material_owned && surface->material.is_valid())
965 free(surface->material);
966
967 surface->material_owned = p_owned;
968
969 surface->material = p_material;
970 }
971
mesh_surface_get_material(RID p_mesh,int p_surface) const972 RID RasterizerIPhone::mesh_surface_get_material(RID p_mesh, int p_surface) const {
973
974 Mesh *mesh = mesh_owner.get(p_mesh);
975 ERR_FAIL_COND_V(!mesh, RID());
976 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), RID());
977 Surface *surface = mesh->surfaces[p_surface];
978 ERR_FAIL_COND_V(!surface, RID());
979
980 return surface->material;
981 }
982
mesh_surface_get_array_len(RID p_mesh,int p_surface) const983 int RasterizerIPhone::mesh_surface_get_array_len(RID p_mesh, int p_surface) const {
984
985 Mesh *mesh = mesh_owner.get(p_mesh);
986 ERR_FAIL_COND_V(!mesh, -1);
987 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1);
988 Surface *surface = mesh->surfaces[p_surface];
989 ERR_FAIL_COND_V(!surface, -1);
990
991 return surface->array_len;
992 }
mesh_surface_get_array_index_len(RID p_mesh,int p_surface) const993 int RasterizerIPhone::mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const {
994
995 Mesh *mesh = mesh_owner.get(p_mesh);
996 ERR_FAIL_COND_V(!mesh, -1);
997 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1);
998 Surface *surface = mesh->surfaces[p_surface];
999 ERR_FAIL_COND_V(!surface, -1);
1000
1001 return surface->index_array_len;
1002 }
mesh_surface_get_format(RID p_mesh,int p_surface) const1003 uint32_t RasterizerIPhone::mesh_surface_get_format(RID p_mesh, int p_surface) const {
1004
1005 Mesh *mesh = mesh_owner.get(p_mesh);
1006 ERR_FAIL_COND_V(!mesh, 0);
1007 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), 0);
1008 Surface *surface = mesh->surfaces[p_surface];
1009 ERR_FAIL_COND_V(!surface, 0);
1010
1011 return surface->format;
1012 }
mesh_surface_get_primitive_type(RID p_mesh,int p_surface) const1013 VS::PrimitiveType RasterizerIPhone::mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const {
1014
1015 Mesh *mesh = mesh_owner.get(p_mesh);
1016 ERR_FAIL_COND_V(!mesh, VS::PRIMITIVE_POINTS);
1017 ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), VS::PRIMITIVE_POINTS);
1018 Surface *surface = mesh->surfaces[p_surface];
1019 ERR_FAIL_COND_V(!surface, VS::PRIMITIVE_POINTS);
1020
1021 return surface->primitive;
1022 }
1023
mesh_erase_surface(RID p_mesh,int p_index)1024 void RasterizerIPhone::mesh_erase_surface(RID p_mesh, int p_index) {
1025
1026 Mesh *mesh = mesh_owner.get(p_mesh);
1027 ERR_FAIL_COND(!mesh);
1028 ERR_FAIL_INDEX(p_index, mesh->surfaces.size());
1029 Surface *surface = mesh->surfaces[p_index];
1030 ERR_FAIL_COND(!surface);
1031
1032 memdelete(mesh->surfaces[p_index]);
1033 mesh->surfaces.remove(p_index);
1034 }
mesh_get_surface_count(RID p_mesh) const1035 int RasterizerIPhone::mesh_get_surface_count(RID p_mesh) const {
1036
1037 Mesh *mesh = mesh_owner.get(p_mesh);
1038 ERR_FAIL_COND_V(!mesh, -1);
1039
1040 return mesh->surfaces.size();
1041 }
1042
mesh_get_aabb(RID p_mesh) const1043 AABB RasterizerIPhone::mesh_get_aabb(RID p_mesh) const {
1044
1045 Mesh *mesh = mesh_owner.get(p_mesh);
1046 ERR_FAIL_COND_V(!mesh, AABB());
1047
1048 AABB aabb;
1049
1050 for (int i = 0; i < mesh->surfaces.size(); i++) {
1051
1052 if (i == 0)
1053 aabb = mesh->surfaces[i]->aabb;
1054 else
1055 aabb.merge_with(mesh->surfaces[i]->aabb);
1056 }
1057
1058 return aabb;
1059 }
1060
1061 /* MULTIMESH API */
1062
multimesh_create()1063 RID RasterizerIPhone::multimesh_create() {
1064
1065 return RID();
1066 }
1067
multimesh_set_instance_count(RID p_multimesh,int p_count)1068 void RasterizerIPhone::multimesh_set_instance_count(RID p_multimesh, int p_count) {
1069 }
multimesh_get_instance_count(RID p_multimesh) const1070 int RasterizerIPhone::multimesh_get_instance_count(RID p_multimesh) const {
1071
1072 return 0;
1073 }
1074
multimesh_set_mesh(RID p_multimesh,RID p_mesh)1075 void RasterizerIPhone::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
1076 }
multimesh_set_aabb(RID p_multimesh,const AABB & p_aabb)1077 void RasterizerIPhone::multimesh_set_aabb(RID p_multimesh, const AABB &p_aabb) {
1078 }
multimesh_instance_set_transform(RID p_multimesh,int p_index,const Transform & p_transform)1079 void RasterizerIPhone::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {
1080 }
multimesh_instance_set_color(RID p_multimesh,int p_index,const Color & p_color)1081 void RasterizerIPhone::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
1082 }
1083
multimesh_get_mesh(RID p_multimesh) const1084 RID RasterizerIPhone::multimesh_get_mesh(RID p_multimesh) const {
1085
1086 return RID();
1087 }
multimesh_get_aabb(RID p_multimesh) const1088 AABB RasterizerIPhone::multimesh_get_aabb(RID p_multimesh) const {
1089
1090 return AABB();
1091 }
1092
multimesh_instance_get_transform(RID p_multimesh,int p_index) const1093 Transform RasterizerIPhone::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
1094
1095 return Transform();
1096 }
multimesh_instance_get_color(RID p_multimesh,int p_index) const1097 Color RasterizerIPhone::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
1098
1099 return Color();
1100 }
1101
1102 /* POLY API */
1103
poly_create()1104 RID RasterizerIPhone::poly_create() {
1105
1106 return RID();
1107 }
poly_set_material(RID p_poly,RID p_material,bool p_owned)1108 void RasterizerIPhone::poly_set_material(RID p_poly, RID p_material, bool p_owned) {
1109 }
poly_add_primitive(RID p_poly,const Vector<Vector3> & p_points,const Vector<Vector3> & p_normals,const Vector<Color> & p_colors,const Vector<Vector3> & p_uvs)1110 void RasterizerIPhone::poly_add_primitive(RID p_poly, const Vector<Vector3> &p_points, const Vector<Vector3> &p_normals, const Vector<Color> &p_colors, const Vector<Vector3> &p_uvs) {
1111 }
poly_clear(RID p_poly)1112 void RasterizerIPhone::poly_clear(RID p_poly) {
1113 }
1114
poly_get_aabb(RID p_poly) const1115 AABB RasterizerIPhone::poly_get_aabb(RID p_poly) const {
1116
1117 return AABB();
1118 }
1119
1120 /* PARTICLES API */
1121
particles_create()1122 RID RasterizerIPhone::particles_create() {
1123
1124 return RID();
1125 }
1126
particles_set_amount(RID p_particles,int p_amount)1127 void RasterizerIPhone::particles_set_amount(RID p_particles, int p_amount) {
1128 }
particles_get_amount(RID p_particles) const1129 int RasterizerIPhone::particles_get_amount(RID p_particles) const {
1130
1131 return 0;
1132 }
1133
particles_set_emitting(RID p_particles,bool p_emitting)1134 void RasterizerIPhone::particles_set_emitting(RID p_particles, bool p_emitting) {
1135 }
1136
particles_is_emitting(RID p_particles) const1137 bool RasterizerIPhone::particles_is_emitting(RID p_particles) const {
1138
1139 return false;
1140 }
1141
particles_set_visibility_aabb(RID p_particles,const AABB & p_visibility)1142 void RasterizerIPhone::particles_set_visibility_aabb(RID p_particles, const AABB &p_visibility) {
1143 }
particles_get_visibility_aabb(RID p_particles) const1144 AABB RasterizerIPhone::particles_get_visibility_aabb(RID p_particles) const {
1145
1146 return AABB();
1147 }
1148
particles_set_emission_half_extents(RID p_particles,const Vector3 & p_half_extents)1149 void RasterizerIPhone::particles_set_emission_half_extents(RID p_particles, const Vector3 &p_half_extents) {
1150 }
particles_get_emission_half_extents(RID p_particles) const1151 Vector3 RasterizerIPhone::particles_get_emission_half_extents(RID p_particles) const {
1152
1153 return Vector3();
1154 }
1155
particles_set_gravity_normal(RID p_particles,const Vector3 & p_normal)1156 void RasterizerIPhone::particles_set_gravity_normal(RID p_particles, const Vector3 &p_normal) {
1157 }
particles_get_gravity_normal(RID p_particles) const1158 Vector3 RasterizerIPhone::particles_get_gravity_normal(RID p_particles) const {
1159
1160 return Vector3();
1161 }
1162
particles_set_variable(RID p_particles,VS::ParticleVariable p_variable,float p_value)1163 void RasterizerIPhone::particles_set_variable(RID p_particles, VS::ParticleVariable p_variable, float p_value) {
1164 }
particles_get_variable(RID p_particles,VS::ParticleVariable p_variable) const1165 float RasterizerIPhone::particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const {
1166
1167 return 0;
1168 }
1169
particles_set_randomness(RID p_particles,VS::ParticleVariable p_variable,float p_randomness)1170 void RasterizerIPhone::particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable, float p_randomness) {
1171 }
particles_get_randomness(RID p_particles,VS::ParticleVariable p_variable) const1172 float RasterizerIPhone::particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const {
1173
1174 return 0;
1175 }
1176
particles_set_color_phase_pos(RID p_particles,int p_phase,float p_pos)1177 void RasterizerIPhone::particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos) {
1178 }
particles_get_color_phase_pos(RID p_particles,int p_phase) const1179 float RasterizerIPhone::particles_get_color_phase_pos(RID p_particles, int p_phase) const {
1180
1181 return 0;
1182 }
1183
particles_set_color_phases(RID p_particles,int p_phases)1184 void RasterizerIPhone::particles_set_color_phases(RID p_particles, int p_phases) {
1185 }
particles_get_color_phases(RID p_particles) const1186 int RasterizerIPhone::particles_get_color_phases(RID p_particles) const {
1187
1188 return 0;
1189 }
1190
particles_set_color_phase_color(RID p_particles,int p_phase,const Color & p_color)1191 void RasterizerIPhone::particles_set_color_phase_color(RID p_particles, int p_phase, const Color &p_color) {
1192 }
particles_get_color_phase_color(RID p_particles,int p_phase) const1193 Color RasterizerIPhone::particles_get_color_phase_color(RID p_particles, int p_phase) const {
1194
1195 return Color();
1196 }
1197
particles_set_attractors(RID p_particles,int p_attractors)1198 void RasterizerIPhone::particles_set_attractors(RID p_particles, int p_attractors) {
1199 }
particles_get_attractors(RID p_particles) const1200 int RasterizerIPhone::particles_get_attractors(RID p_particles) const {
1201
1202 return 0;
1203 }
1204
particles_set_attractor_pos(RID p_particles,int p_attractor,const Vector3 & p_pos)1205 void RasterizerIPhone::particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3 &p_pos) {
1206 }
particles_get_attractor_pos(RID p_particles,int p_attractor) const1207 Vector3 RasterizerIPhone::particles_get_attractor_pos(RID p_particles, int p_attractor) const {
1208
1209 return Vector3();
1210 }
1211
particles_set_attractor_strength(RID p_particles,int p_attractor,float p_force)1212 void RasterizerIPhone::particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force) {
1213 }
particles_get_attractor_strength(RID p_particles,int p_attractor) const1214 float RasterizerIPhone::particles_get_attractor_strength(RID p_particles, int p_attractor) const {
1215
1216 return 0;
1217 }
1218
particles_set_material(RID p_particles,RID p_material,bool p_owned)1219 void RasterizerIPhone::particles_set_material(RID p_particles, RID p_material, bool p_owned) {
1220 }
1221
particles_get_material(RID p_particles) const1222 RID RasterizerIPhone::particles_get_material(RID p_particles) const {
1223
1224 return RID();
1225 }
1226
particles_get_aabb(RID p_particles) const1227 AABB RasterizerIPhone::particles_get_aabb(RID p_particles) const {
1228
1229 return AABB();
1230 }
1231 /* BEAM API */
1232
beam_create()1233 RID RasterizerIPhone::beam_create() {
1234
1235 return RID();
1236 }
1237
beam_set_point_count(RID p_beam,int p_count)1238 void RasterizerIPhone::beam_set_point_count(RID p_beam, int p_count) {
1239 }
beam_get_point_count(RID p_beam) const1240 int RasterizerIPhone::beam_get_point_count(RID p_beam) const {
1241
1242 return 0;
1243 }
beam_clear(RID p_beam)1244 void RasterizerIPhone::beam_clear(RID p_beam) {
1245 }
1246
beam_set_point(RID p_beam,int p_point,Vector3 & p_pos)1247 void RasterizerIPhone::beam_set_point(RID p_beam, int p_point, Vector3 &p_pos) {
1248 }
beam_get_point(RID p_beam,int p_point) const1249 Vector3 RasterizerIPhone::beam_get_point(RID p_beam, int p_point) const {
1250
1251 return Vector3();
1252 }
1253
beam_set_primitive(RID p_beam,VS::BeamPrimitive p_primitive)1254 void RasterizerIPhone::beam_set_primitive(RID p_beam, VS::BeamPrimitive p_primitive) {
1255 }
1256
beam_get_primitive(RID p_beam) const1257 VS::BeamPrimitive RasterizerIPhone::beam_get_primitive(RID p_beam) const {
1258
1259 return VS::BEAM_CUBIC;
1260 }
1261
beam_set_material(RID p_beam,RID p_material)1262 void RasterizerIPhone::beam_set_material(RID p_beam, RID p_material) {
1263 }
beam_get_material(RID p_beam) const1264 RID RasterizerIPhone::beam_get_material(RID p_beam) const {
1265
1266 return RID();
1267 }
1268
beam_get_aabb(RID p_particles) const1269 AABB RasterizerIPhone::beam_get_aabb(RID p_particles) const {
1270
1271 return AABB();
1272 }
1273 /* SKELETON API */
1274
skeleton_create()1275 RID RasterizerIPhone::skeleton_create() {
1276
1277 Skeleton *skeleton = memnew(Skeleton);
1278 ERR_FAIL_COND_V(!skeleton, RID());
1279 return skeleton_owner.make_rid(skeleton);
1280 }
skeleton_resize(RID p_skeleton,int p_bones)1281 void RasterizerIPhone::skeleton_resize(RID p_skeleton, int p_bones) {
1282
1283 Skeleton *skeleton = skeleton_owner.get(p_skeleton);
1284 ERR_FAIL_COND(!skeleton);
1285 if (p_bones == skeleton->bones.size()) {
1286 return;
1287 };
1288 ERR_FAIL_COND(p_bones < 0 || p_bones > 256);
1289
1290 skeleton->bones.resize(p_bones);
1291 }
skeleton_get_bone_count(RID p_skeleton) const1292 int RasterizerIPhone::skeleton_get_bone_count(RID p_skeleton) const {
1293
1294 Skeleton *skeleton = skeleton_owner.get(p_skeleton);
1295 ERR_FAIL_COND_V(!skeleton, -1);
1296 return skeleton->bones.size();
1297 }
skeleton_bone_set_transform(RID p_skeleton,int p_bone,const Transform & p_transform)1298 void RasterizerIPhone::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {
1299
1300 Skeleton *skeleton = skeleton_owner.get(p_skeleton);
1301 ERR_FAIL_COND(!skeleton);
1302 ERR_FAIL_INDEX(p_bone, skeleton->bones.size());
1303
1304 skeleton->bones[p_bone] = p_transform;
1305 }
skeleton_bone_get_transform(RID p_skeleton,int p_bone)1306 Transform RasterizerIPhone::skeleton_bone_get_transform(RID p_skeleton, int p_bone) {
1307
1308 Skeleton *skeleton = skeleton_owner.get(p_skeleton);
1309 ERR_FAIL_COND_V(!skeleton, Transform());
1310 ERR_FAIL_INDEX_V(p_bone, skeleton->bones.size(), Transform());
1311
1312 // something
1313 return skeleton->bones[p_bone];
1314 }
1315
1316 /* LIGHT API */
1317
light_create(VS::LightType p_type)1318 RID RasterizerIPhone::light_create(VS::LightType p_type) {
1319
1320 Light *light = memnew(Light);
1321 light->type = p_type;
1322 return light_owner.make_rid(light);
1323 }
1324
light_get_type(RID p_light) const1325 VS::LightType RasterizerIPhone::light_get_type(RID p_light) const {
1326
1327 Light *light = light_owner.get(p_light);
1328 ERR_FAIL_COND_V(!light, VS::LIGHT_OMNI);
1329 return light->type;
1330 }
1331
light_set_color(RID p_light,VS::LightColor p_type,const Color & p_color)1332 void RasterizerIPhone::light_set_color(RID p_light, VS::LightColor p_type, const Color &p_color) {
1333
1334 Light *light = light_owner.get(p_light);
1335 ERR_FAIL_COND(!light);
1336 ERR_FAIL_INDEX(p_type, 3);
1337 light->colors[p_type] = p_color;
1338 }
light_get_color(RID p_light,VS::LightColor p_type) const1339 Color RasterizerIPhone::light_get_color(RID p_light, VS::LightColor p_type) const {
1340
1341 Light *light = light_owner.get(p_light);
1342 ERR_FAIL_COND_V(!light, Color());
1343 ERR_FAIL_INDEX_V(p_type, 3, Color());
1344 return light->colors[p_type];
1345 }
1346
light_set_shadow(RID p_light,bool p_enabled)1347 void RasterizerIPhone::light_set_shadow(RID p_light, bool p_enabled) {
1348
1349 Light *light = light_owner.get(p_light);
1350 ERR_FAIL_COND(!light);
1351 light->shadow_enabled = p_enabled;
1352 }
1353
light_has_shadow(RID p_light) const1354 bool RasterizerIPhone::light_has_shadow(RID p_light) const {
1355
1356 Light *light = light_owner.get(p_light);
1357 ERR_FAIL_COND_V(!light, false);
1358 return light->shadow_enabled;
1359 }
1360
light_set_volumetric(RID p_light,bool p_enabled)1361 void RasterizerIPhone::light_set_volumetric(RID p_light, bool p_enabled) {
1362
1363 Light *light = light_owner.get(p_light);
1364 ERR_FAIL_COND(!light);
1365 light->volumetric_enabled = p_enabled;
1366 }
light_is_volumetric(RID p_light) const1367 bool RasterizerIPhone::light_is_volumetric(RID p_light) const {
1368
1369 Light *light = light_owner.get(p_light);
1370 ERR_FAIL_COND_V(!light, false);
1371 return light->volumetric_enabled;
1372 }
1373
light_set_projector(RID p_light,RID p_texture)1374 void RasterizerIPhone::light_set_projector(RID p_light, RID p_texture) {
1375
1376 Light *light = light_owner.get(p_light);
1377 ERR_FAIL_COND(!light);
1378 light->projector = p_texture;
1379 }
light_get_projector(RID p_light) const1380 RID RasterizerIPhone::light_get_projector(RID p_light) const {
1381
1382 Light *light = light_owner.get(p_light);
1383 ERR_FAIL_COND_V(!light, RID());
1384 return light->projector;
1385 }
1386
light_set_var(RID p_light,VS::LightParam p_var,float p_value)1387 void RasterizerIPhone::light_set_var(RID p_light, VS::LightParam p_var, float p_value) {
1388
1389 Light *light = light_owner.get(p_light);
1390 ERR_FAIL_COND(!light);
1391 ERR_FAIL_INDEX(p_var, VS::LIGHT_PARAM_MAX);
1392
1393 light->vars[p_var] = p_value;
1394 }
light_get_var(RID p_light,VS::LightParam p_var) const1395 float RasterizerIPhone::light_get_var(RID p_light, VS::LightParam p_var) const {
1396
1397 Light *light = light_owner.get(p_light);
1398 ERR_FAIL_COND_V(!light, 0);
1399
1400 ERR_FAIL_INDEX_V(p_var, VS::LIGHT_PARAM_MAX, 0);
1401
1402 return light->vars[p_var];
1403 }
1404
light_get_aabb(RID p_light) const1405 AABB RasterizerIPhone::light_get_aabb(RID p_light) const {
1406
1407 Light *light = light_owner.get(p_light);
1408 ERR_FAIL_COND_V(!light, AABB());
1409
1410 switch (light->type) {
1411
1412 case VS::LIGHT_SPOT: {
1413
1414 float len = light->vars[VS::LIGHT_PARAM_RADIUS];
1415 float size = Math::tan(Math::deg2rad(light->vars[VS::LIGHT_PARAM_SPOT_ANGLE])) * len;
1416 return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
1417 } break;
1418 case VS::LIGHT_OMNI: {
1419
1420 float r = light->vars[VS::LIGHT_PARAM_RADIUS];
1421 return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
1422 } break;
1423 case VS::LIGHT_DIRECTIONAL: {
1424
1425 return AABB();
1426 } break;
1427 default: {}
1428 }
1429
1430 ERR_FAIL_V(AABB());
1431 }
1432
light_instance_create(RID p_light)1433 RID RasterizerIPhone::light_instance_create(RID p_light) {
1434
1435 Light *light = light_owner.get(p_light);
1436 ERR_FAIL_COND_V(!light, RID());
1437
1438 LightInstance *light_instance = memnew(LightInstance);
1439
1440 light_instance->light = p_light;
1441 light_instance->base = light;
1442 light_instance->last_pass = 0;
1443
1444 return light_instance_owner.make_rid(light_instance);
1445 }
light_instance_set_transform(RID p_light_instance,const Transform & p_transform)1446 void RasterizerIPhone::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {
1447
1448 LightInstance *lighti = light_instance_owner.get(p_light_instance);
1449 ERR_FAIL_COND(!lighti);
1450 lighti->transform = p_transform;
1451 }
1452
light_instance_set_active_hint(RID p_light_instance)1453 void RasterizerIPhone::light_instance_set_active_hint(RID p_light_instance) {
1454
1455 LightInstance *lighti = light_instance_owner.get(p_light_instance);
1456 ERR_FAIL_COND(!lighti);
1457 lighti->last_pass = frame;
1458 }
light_instance_has_shadow(RID p_light_instance) const1459 bool RasterizerIPhone::light_instance_has_shadow(RID p_light_instance) const {
1460
1461 return false;
1462 }
light_instance_assign_shadow(RID p_light_instance)1463 bool RasterizerIPhone::light_instance_assign_shadow(RID p_light_instance) {
1464
1465 return false;
1466 }
light_instance_get_shadow_type(RID p_light_instance) const1467 Rasterizer::ShadowType RasterizerIPhone::light_instance_get_shadow_type(RID p_light_instance) const {
1468
1469 return Rasterizer::SHADOW_CUBE;
1470 }
light_instance_get_shadow_passes(RID p_light_instance) const1471 int RasterizerIPhone::light_instance_get_shadow_passes(RID p_light_instance) const {
1472
1473 return 0;
1474 }
light_instance_set_pssm_split_info(RID p_light_instance,int p_split,float p_near,float p_far,const CameraMatrix & p_camera,const Transform & p_transform)1475 void RasterizerIPhone::light_instance_set_pssm_split_info(RID p_light_instance, int p_split, float p_near, float p_far, const CameraMatrix &p_camera, const Transform &p_transform) {
1476 }
1477
1478 /* PARTICLES INSTANCE */
1479
particles_instance_create(RID p_particles)1480 RID RasterizerIPhone::particles_instance_create(RID p_particles) {
1481
1482 return RID();
1483 }
particles_instance_set_transform(RID p_particles_instance,const Transform & p_transform)1484 void RasterizerIPhone::particles_instance_set_transform(RID p_particles_instance, const Transform &p_transform) {
1485 }
1486
1487 /* RENDER API */
1488 /* all calls (inside begin/end shadow) are always warranted to be in the following order: */
1489
1490 static GLfloat rtri; // Angle For The Triangle ( NEW )
1491 static GLfloat rquad; // Angle For The Quad ( NEW )
1492
begin_frame()1493 void RasterizerIPhone::begin_frame() {
1494
1495 window_size = Size2(OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height);
1496
1497 double time = (OS::get_singleton()->get_ticks_usec() / 1000); // get msec
1498 time /= 1000.0; // make secs
1499 time_delta = time - last_time;
1500 last_time = time;
1501 frame++;
1502 glClearColor(0, 0, 1, 1);
1503 glClear(GL_COLOR_BUFFER_BIT);
1504
1505 /* nehe ?*/
1506
1507 #if 0
1508 glViewport(0,0,window_size.width,window_size.height); // Reset The Current Viewport
1509
1510 glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
1511 glLoadIdentity(); // Reset The Projection Matrix
1512
1513 // Calculate The Aspect Ratio Of The Window
1514 gluPerspective(45.0f,(GLfloat)window_size.width/(GLfloat)window_size.height,0.1f,100.0f);
1515
1516 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
1517 glLoadIdentity(); // Reset The Modelview Matrix
1518
1519
1520
1521 glShadeModel(GL_SMOOTH); // Enable Smooth Shading
1522 glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
1523 glClearDepth(1.0f); // Depth Buffer Setup
1524 glEnable(GL_DEPTH_TEST); // Enables Depth Testing
1525 glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
1526 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
1527
1528 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
1529 glLoadIdentity(); // Reset The Current Modelview Matrix
1530 glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
1531 glRotatef(rtri,0.0f,1.0f,0.0f); // Rotate The Triangle On The Y axis ( NEW )
1532 glBegin(GL_TRIANGLES); // Start Drawing A Triangle
1533 glColor3f(1.0f,0.0f,0.0f); // Red
1534 glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
1535 glColor3f(0.0f,1.0f,0.0f); // Green
1536 glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)
1537 glColor3f(0.0f,0.0f,1.0f); // Blue
1538 glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)
1539 glColor3f(1.0f,0.0f,0.0f); // Red
1540 glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
1541 glColor3f(0.0f,0.0f,1.0f); // Blue
1542 glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)
1543 glColor3f(0.0f,1.0f,0.0f); // Green
1544 glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)
1545 glColor3f(1.0f,0.0f,0.0f); // Red
1546 glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
1547 glColor3f(0.0f,1.0f,0.0f); // Green
1548 glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)
1549 glColor3f(0.0f,0.0f,1.0f); // Blue
1550 glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)
1551 glColor3f(1.0f,0.0f,0.0f); // Red
1552 glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
1553 glColor3f(0.0f,0.0f,1.0f); // Blue
1554 glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)
1555 glColor3f(0.0f,1.0f,0.0f); // Green
1556 glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)
1557 glEnd(); // Done Drawing The Pyramid
1558
1559 glLoadIdentity(); // Reset The Current Modelview Matrix
1560 glTranslatef(1.5f,0.0f,-7.0f); // Move Right 1.5 Units And Into The Screen 7.0
1561 glRotatef(rquad,1.0f,1.0f,1.0f); // Rotate The Quad On The X axis ( NEW )
1562 glBegin(GL_QUADS); // Draw A Quad
1563 glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
1564 glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
1565 glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
1566 glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
1567 glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
1568 glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange
1569 glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
1570 glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
1571 glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
1572 glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
1573 glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
1574 glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
1575 glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
1576 glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
1577 glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
1578 glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow
1579 glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back)
1580 glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back)
1581 glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back)
1582 glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back)
1583 glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
1584 glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
1585 glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
1586 glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
1587 glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
1588 glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet
1589 glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
1590 glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
1591 glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
1592 glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
1593 glEnd(); // Done Drawing The Quad
1594
1595 rtri+=0.2f; // Increase The Rotation Variable For The Triangle ( NEW )
1596 rquad-=0.15f; // Decrease The Rotation Variable For The Quad ( NEW )
1597
1598 #endif
1599 }
1600
set_viewport(const VS::ViewportRect & p_viewport)1601 void RasterizerIPhone::set_viewport(const VS::ViewportRect &p_viewport) {
1602
1603 viewport = p_viewport;
1604 canvas_transform = Transform();
1605 canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f);
1606 canvas_transform.scale(Vector3(2.0f / viewport.width, -2.0f / viewport.height, 1.0f));
1607
1608 glViewport(viewport.x, window_size.height - (viewport.height + viewport.y), viewport.width, viewport.height);
1609 }
1610
begin_scene(RID p_fx,VS::ScenarioDebugMode p_debug)1611 void RasterizerIPhone::begin_scene(RID p_fx, VS::ScenarioDebugMode p_debug) {
1612
1613 opaque_render_list.clear();
1614 alpha_render_list.clear();
1615 light_instance_count = 0;
1616 scene_fx = p_fx.is_valid() ? fx_owner.get(p_fx) : NULL;
1617 };
1618
begin_shadow_map(RID p_light_instance,int p_shadow_pass)1619 void RasterizerIPhone::begin_shadow_map(RID p_light_instance, int p_shadow_pass) {
1620 }
1621
set_camera(const Transform & p_world,const CameraMatrix & p_projection)1622 void RasterizerIPhone::set_camera(const Transform &p_world, const CameraMatrix &p_projection) {
1623
1624 camera_transform = p_world;
1625 camera_transform_inverse = camera_transform.inverse();
1626 camera_projection = p_projection;
1627 camera_plane = Plane(camera_transform.origin, camera_transform.basis.get_axis(2));
1628 camera_z_near = camera_projection.get_z_near();
1629 camera_z_far = camera_projection.get_z_far();
1630 camera_projection.get_viewport_size(camera_vp_size.x, camera_vp_size.y);
1631 }
1632
add_light(RID p_light_instance)1633 void RasterizerIPhone::add_light(RID p_light_instance) {
1634
1635 #define LIGHT_FADE_TRESHOLD 0.05
1636
1637 ERR_FAIL_COND(light_instance_count >= MAX_LIGHTS);
1638
1639 LightInstance *li = light_instance_owner.get(p_light_instance);
1640 ERR_FAIL_COND(!li);
1641
1642 /* make light hash */
1643
1644 // actually, not really a hash, but helps to sort the lights
1645 // and avoid recompiling redudant shader versions
1646
1647 li->hash_aux = li->base->type;
1648
1649 if (li->base->shadow_enabled)
1650 li->hash_aux |= (1 << 3);
1651
1652 if (li->base->projector.is_valid())
1653 li->hash_aux |= (1 << 4);
1654
1655 if (li->base->shadow_enabled && li->base->volumetric_enabled)
1656 li->hash_aux |= (1 << 5);
1657
1658 switch (li->base->type) {
1659
1660 case VisualServer::LIGHT_DIRECTIONAL: {
1661
1662 Vector3 dir = li->transform.basis.get_axis(2);
1663 li->light_vector.x = dir.x;
1664 li->light_vector.y = dir.y;
1665 li->light_vector.z = dir.z;
1666
1667 } break;
1668 case VisualServer::LIGHT_OMNI: {
1669
1670 float radius = li->base->vars[VisualServer::LIGHT_PARAM_RADIUS];
1671 if (radius == 0)
1672 radius = 0.0001;
1673 li->linear_att = (1 / LIGHT_FADE_TRESHOLD) / radius;
1674 li->light_vector.x = li->transform.origin.x;
1675 li->light_vector.y = li->transform.origin.y;
1676 li->light_vector.z = li->transform.origin.z;
1677
1678 } break;
1679 case VisualServer::LIGHT_SPOT: {
1680
1681 float radius = li->base->vars[VisualServer::LIGHT_PARAM_RADIUS];
1682 if (radius == 0)
1683 radius = 0.0001;
1684 li->linear_att = (1 / LIGHT_FADE_TRESHOLD) / radius;
1685 li->light_vector.x = li->transform.origin.x;
1686 li->light_vector.y = li->transform.origin.y;
1687 li->light_vector.z = li->transform.origin.z;
1688 Vector3 dir = -li->transform.basis.get_axis(2);
1689 li->spot_vector.x = dir.x;
1690 li->spot_vector.y = dir.y;
1691 li->spot_vector.z = dir.z;
1692
1693 } break;
1694 }
1695
1696 light_instances[light_instance_count++] = li;
1697 }
1698
_add_geometry(const Geometry * p_geometry,const Transform & p_world,uint32_t p_vertex_format,const RID * p_light_instances,int p_light_count,const ParamOverrideMap * p_material_overrides,const Skeleton * p_skeleton,GeometryOwner * p_owner)1699 void RasterizerIPhone::_add_geometry(const Geometry *p_geometry, const Transform &p_world, uint32_t p_vertex_format, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, GeometryOwner *p_owner) {
1700
1701 Material *m = NULL;
1702
1703 if (p_geometry->material.is_valid())
1704 m = material_owner.get(p_geometry->material);
1705
1706 if (!m) {
1707 m = material_owner.get(default_material);
1708 }
1709
1710 ERR_FAIL_COND(!m);
1711
1712 LightInstance *lights[RenderList::MAX_LIGHTS];
1713 int light_count = 0;
1714
1715 RenderList *render_list = &opaque_render_list;
1716 if (p_geometry->has_alpha || m->detail_blend_mode != VS::MATERIAL_BLEND_MODE_MIX) {
1717 render_list = &alpha_render_list;
1718 };
1719
1720 if (!m->flags[VS::MATERIAL_FLAG_UNSHADED]) {
1721
1722 light_count = p_light_count;
1723 for (int i = 0; i < light_count; i++) {
1724 lights[i] = light_instance_owner.get(p_light_instances[i]);
1725 }
1726 }
1727
1728 render_list->add_element(p_geometry, m, p_world, lights, light_count, p_material_overrides, p_skeleton, camera_plane.distance(p_world.origin), p_owner);
1729 }
1730
add_mesh(RID p_mesh,const Transform * p_world,const RID * p_light_instances,int p_light_count,const ParamOverrideMap * p_material_overrides,RID p_skeleton)1731 void RasterizerIPhone::add_mesh(RID p_mesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, RID p_skeleton) {
1732
1733 Mesh *mesh = mesh_owner.get(p_mesh);
1734
1735 int ssize = mesh->surfaces.size();
1736
1737 for (int i = 0; i < ssize; i++) {
1738
1739 Surface *s = mesh->surfaces[i];
1740 Skeleton *sk = p_skeleton.is_valid() ? skeleton_owner.get(p_skeleton) : NULL;
1741
1742 _add_geometry(s, *p_world, s->format, p_light_instances, p_light_count, p_material_overrides, sk, NULL);
1743 }
1744
1745 mesh->last_pass = frame;
1746 }
1747
add_multimesh(RID p_multimesh,const Transform * p_world,const RID * p_light_instances,int p_light_count,const ParamOverrideMap * p_material_overrides)1748 void RasterizerIPhone::add_multimesh(RID p_multimesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
1749 }
1750
add_poly(RID p_poly,const Transform * p_world,const RID * p_light_instances,int p_light_count,const ParamOverrideMap * p_material_overrides)1751 void RasterizerIPhone::add_poly(RID p_poly, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
1752
1753 Poly *p = poly_owner.get(p_poly);
1754 if (!p->primitives.empty()) {
1755 const Poly::Primitive *pp = &p->primitives[0];
1756
1757 uint32_t format = VisualServer::ARRAY_FORMAT_VERTEX;
1758
1759 if (!pp->normals.empty())
1760 format |= VisualServer::ARRAY_FORMAT_NORMAL;
1761 if (!pp->colors.empty())
1762 format |= VisualServer::ARRAY_FORMAT_COLOR;
1763 if (!pp->uvs.empty())
1764 format |= VisualServer::ARRAY_TEX_UV;
1765
1766 _add_geometry(p, *p_world, format, p_light_instances, p_light_count, p_material_overrides, NULL, NULL);
1767 }
1768 }
1769
add_beam(RID p_beam,const Transform * p_world,const RID * p_light_instances,int p_light_count,const ParamOverrideMap * p_material_overrides)1770 void RasterizerIPhone::add_beam(RID p_beam, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
1771 }
1772
add_particles(RID p_particle_instance,const RID * p_light_instances,int p_light_count,const ParamOverrideMap * p_material_overrides)1773 void RasterizerIPhone::add_particles(RID p_particle_instance, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
1774 }
1775
_setup_material(const Geometry * p_geometry,const Material * p_material)1776 void RasterizerIPhone::_setup_material(const Geometry *p_geometry, const Material *p_material) {
1777
1778 if (p_material->flags[VS::MATERIAL_FLAG_DOUBLE_SIDED])
1779 glDisable(GL_CULL_FACE);
1780 else {
1781 glEnable(GL_CULL_FACE);
1782 glCullFace((p_material->flags[VS::MATERIAL_FLAG_INVERT_FACES]) ? GL_FRONT : GL_BACK);
1783 }
1784
1785 glEnable(GL_COLOR_MATERIAL); /* unused, unless color array */
1786 //glColorMaterial( GL_FRONT_AND_BACK, GL_DIFFUSE );
1787 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1788
1789 ///ambient @TODO offer global ambient group option
1790 float ambient_rgba[4] = {
1791 1,
1792 1,
1793 1,
1794 1.0
1795 };
1796 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient_rgba);
1797
1798 ///diffuse
1799 const Color &diffuse_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_DIFFUSE];
1800 float diffuse_rgba[4] = {
1801 (float)diffuse_color.r,
1802 (float)diffuse_color.g,
1803 (float)diffuse_color.b,
1804 (float)diffuse_color.a
1805 };
1806
1807 glColor4f(diffuse_rgba[0], diffuse_rgba[1], diffuse_rgba[2], diffuse_rgba[3]);
1808
1809 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse_rgba);
1810
1811 //specular
1812
1813 const Color &specular_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR];
1814 float specular_rgba[4] = {
1815 (float)specular_color.r,
1816 (float)specular_color.g,
1817 (float)specular_color.b,
1818 1.0
1819 };
1820
1821 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular_rgba);
1822
1823 const Color &emission_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_EMISSION];
1824 float emission_rgba[4] = {
1825 (float)emission_color.r,
1826 (float)emission_color.g,
1827 (float)emission_color.b,
1828 1.0
1829 };
1830
1831 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission_rgba);
1832
1833 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, p_material->parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP]);
1834
1835 if (p_material->flags[VS::MATERIAL_FLAG_UNSHADED]) {
1836 glDisable(GL_LIGHTING);
1837 } else {
1838 glEnable(GL_LIGHTING);
1839 glDisable(GL_LIGHTING);
1840 }
1841
1842 //depth test?
1843 /*
1844 if (p_material->flags[VS::MATERIAL_FLAG_WIREFRAME])
1845 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
1846 else
1847 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
1848 */
1849 if (p_material->textures[VS::FIXED_MATERIAL_PARAM_DIFFUSE]) {
1850
1851 Texture *texture = texture_owner.get(p_material->textures[VS::FIXED_MATERIAL_PARAM_DIFFUSE]);
1852 ERR_FAIL_COND(!texture);
1853 glActiveTexture(GL_TEXTURE0);
1854 glEnable(GL_TEXTURE_2D);
1855 glBindTexture(GL_TEXTURE_2D, texture->tex_id);
1856 };
1857 };
1858
_setup_light(LightInstance * p_instance,int p_idx)1859 void RasterizerIPhone::_setup_light(LightInstance *p_instance, int p_idx) {
1860
1861 Light *ld = p_instance->base;
1862
1863 int glid = GL_LIGHT0 + p_idx;
1864 glLightfv(glid, GL_AMBIENT, ld->colors[VS::LIGHT_COLOR_AMBIENT].components);
1865 glLightfv(glid, GL_DIFFUSE, ld->colors[VS::LIGHT_COLOR_DIFFUSE].components);
1866 glLightfv(glid, GL_SPECULAR, ld->colors[VS::LIGHT_COLOR_SPECULAR].components);
1867
1868 switch (ld->type) {
1869
1870 case VS::LIGHT_DIRECTIONAL: {
1871 /* This doesnt have attenuation */
1872
1873 glMatrixMode(GL_MODELVIEW);
1874 glPushMatrix();
1875 glLoadIdentity();
1876 Vector3 v(0.0, 0.0, -1.0); // directional lights point up by default
1877 v = p_instance->transform.get_basis().xform(v);
1878 v = camera_transform_inverse.get_basis().xform(v);
1879 v.normalize(); // this sucks, so it will be optimized at some point
1880 v = -v;
1881 float lightpos[4] = { v.x, v.y, v.z, 0.0 };
1882
1883 glLightfv(glid, GL_POSITION, lightpos); //at modelview
1884
1885 glPopMatrix();
1886
1887 } break;
1888 case VS::LIGHT_OMNI: {
1889
1890 glLightf(glid, GL_SPOT_CUTOFF, 180.0);
1891 glLightf(glid, GL_CONSTANT_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ATTENUATION]);
1892 glLightf(glid, GL_LINEAR_ATTENUATION, ld->vars[VS::LIGHT_PARAM_RADIUS]);
1893 glLightf(glid, GL_QUADRATIC_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ENERGY]); // wut?
1894
1895 glMatrixMode(GL_MODELVIEW);
1896 glPushMatrix();
1897 glLoadIdentity();
1898 Vector3 pos = p_instance->transform.get_origin();
1899 pos = camera_transform_inverse.xform(pos);
1900 float lightpos[4] = { pos.x, pos.y, pos.z, 1.0 };
1901 glLightfv(glid, GL_POSITION, lightpos); //at modelview
1902
1903 glPopMatrix();
1904
1905 } break;
1906 case VS::LIGHT_SPOT: {
1907
1908 glLightf(glid, GL_SPOT_CUTOFF, ld->vars[VS::LIGHT_PARAM_SPOT_ANGLE]);
1909 glLightf(glid, GL_SPOT_EXPONENT, ld->vars[VS::LIGHT_PARAM_SPOT_ATTENUATION]);
1910 glLightf(glid, GL_CONSTANT_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ATTENUATION]);
1911 glLightf(glid, GL_LINEAR_ATTENUATION, ld->vars[VS::LIGHT_PARAM_RADIUS]);
1912 glLightf(glid, GL_QUADRATIC_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ENERGY]); // wut?
1913
1914 glMatrixMode(GL_MODELVIEW);
1915 glPushMatrix();
1916 glLoadIdentity();
1917
1918 Vector3 v(0.0, 0.0, -1.0); // directional lights point up by default
1919 v = p_instance->transform.get_basis().xform(v);
1920 v = camera_transform_inverse.get_basis().xform(v);
1921 v.normalize(); // this sucks, so it will be optimized at some point
1922 float lightdir[4] = { v.x, v.y, v.z, 1.0 };
1923 glLightfv(glid, GL_SPOT_DIRECTION, lightdir); //at modelview
1924
1925 v = p_instance->transform.get_origin();
1926 v = camera_transform_inverse.xform(v);
1927 float lightpos[4] = { v.x, v.y, v.z, 1.0 };
1928 glLightfv(glid, GL_POSITION, lightpos); //at modelview
1929
1930 glPopMatrix();
1931
1932 } break;
1933 default: break;
1934 }
1935 };
1936
_setup_lights(LightInstance ** p_lights,int p_light_count)1937 void RasterizerIPhone::_setup_lights(LightInstance **p_lights, int p_light_count) {
1938
1939 for (int i = 0; i < MAX_LIGHTS; i++) {
1940
1941 if (i < p_light_count) {
1942 glEnable(GL_LIGHT0 + i);
1943 _setup_light(p_lights[i], i);
1944 } else {
1945 glDisable(GL_LIGHT0 + i);
1946 }
1947 }
1948 }
1949
1950 static const int gl_client_states[] = {
1951
1952 GL_VERTEX_ARRAY,
1953 GL_NORMAL_ARRAY,
1954 -1, // ARRAY_TANGENT
1955 GL_COLOR_ARRAY,
1956 GL_TEXTURE_COORD_ARRAY, // ARRAY_TEX_UV
1957 GL_TEXTURE_COORD_ARRAY, // ARRAY_TEX_UV2
1958 -1, // ARRAY_BONES
1959 -1, // ARRAY_WEIGHTS
1960 -1, // ARRAY_INDEX
1961 };
1962
_setup_geometry(const Geometry * p_geometry,const Material * p_material)1963 void RasterizerIPhone::_setup_geometry(const Geometry *p_geometry, const Material *p_material) {
1964
1965 switch (p_geometry->type) {
1966
1967 case Geometry::GEOMETRY_SURFACE: {
1968
1969 Surface *surf = (Surface *)p_geometry;
1970 uint8_t *base = 0;
1971 bool use_VBO = (surf->array_local == 0);
1972
1973 if (!use_VBO) {
1974
1975 base = surf->array_local;
1976 glBindBuffer(GL_ARRAY_BUFFER, 0);
1977
1978 } else {
1979
1980 glBindBuffer(GL_ARRAY_BUFFER, surf->vertex_id);
1981 };
1982
1983 const Surface::ArrayData *a = surf->array;
1984 for (int i = 0; i < VS::ARRAY_MAX; i++) {
1985
1986 const Surface::ArrayData &ad = surf->array[i];
1987 if (ad.size == 0) {
1988 if (gl_client_states[i] != -1) {
1989 glDisableClientState(gl_client_states[i]);
1990 };
1991 continue; // this one is disabled.
1992 }
1993 ERR_CONTINUE(!ad.configured);
1994
1995 if (gl_client_states[i] != -1) {
1996 glEnableClientState(gl_client_states[i]);
1997 };
1998
1999 switch (i) {
2000
2001 case VS::ARRAY_VERTEX:
2002 if (!use_VBO)
2003 glVertexPointer(3, GL_FLOAT, surf->stride, (GLvoid *)&base[a->ofs]);
2004 else if (surf->array[VS::ARRAY_BONES].size)
2005 glVertexPointer(3, GL_FLOAT, 0, skinned_buffer);
2006 else
2007 glVertexPointer(3, GL_FLOAT, surf->stride, (GLvoid *)a->ofs);
2008 break;
2009
2010 case VS::ARRAY_NORMAL:
2011 if (use_VBO)
2012 glNormalPointer(GL_FLOAT, surf->stride, (GLvoid *)a->ofs);
2013 else
2014 glNormalPointer(GL_FLOAT, surf->stride, (GLvoid *)&base[a->ofs]);
2015 break;
2016 case VS::ARRAY_TANGENT:
2017 break;
2018 case VS::ARRAY_COLOR:
2019 if (use_VBO)
2020 glColorPointer(4, GL_UNSIGNED_BYTE, surf->stride, (GLvoid *)a->ofs);
2021 else
2022 glColorPointer(4, GL_UNSIGNED_BYTE, surf->stride, (GLvoid *)&base[a->ofs]);
2023 break;
2024 case VS::ARRAY_TEX_UV:
2025 case VS::ARRAY_TEX_UV2:
2026 if (use_VBO)
2027 glTexCoordPointer(2, GL_FLOAT, surf->stride, (GLvoid *)a->ofs);
2028 else
2029 glTexCoordPointer(2, GL_FLOAT, surf->stride, &base[a->ofs]);
2030 break;
2031 case VS::ARRAY_BONES:
2032 case VS::ARRAY_WEIGHTS:
2033 case VS::ARRAY_INDEX:
2034 break;
2035 };
2036 }
2037
2038 // process skeleton here
2039
2040 } break;
2041
2042 default: break;
2043 };
2044 };
2045
2046 static const GLenum gl_primitive[] = {
2047 GL_POINTS,
2048 GL_LINES,
2049 GL_LINE_STRIP,
2050 GL_LINE_LOOP,
2051 GL_TRIANGLES,
2052 GL_TRIANGLE_STRIP,
2053 GL_TRIANGLE_FAN
2054 };
2055
_render(const Geometry * p_geometry,const Material * p_material,const Skeleton * p_skeleton)2056 void RasterizerIPhone::_render(const Geometry *p_geometry, const Material *p_material, const Skeleton *p_skeleton) {
2057
2058 switch (p_geometry->type) {
2059
2060 case Geometry::GEOMETRY_SURFACE: {
2061
2062 Surface *s = (Surface *)p_geometry;
2063
2064 if (s->index_array_len > 0) {
2065
2066 if (s->index_array_local) {
2067
2068 glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->index_array_len > (1 << 8)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, s->index_array_local);
2069
2070 } else {
2071
2072 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
2073 glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->index_array_len > (1 << 8)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, 0);
2074 }
2075
2076 } else {
2077
2078 glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
2079 };
2080 } break;
2081
2082 default: break;
2083 };
2084 };
2085
_render_list_forward(RenderList * p_render_list)2086 void RasterizerIPhone::_render_list_forward(RenderList *p_render_list) {
2087
2088 const Material *prev_material = NULL;
2089 uint64_t prev_light_hash = 0;
2090 const Skeleton *prev_skeleton = NULL;
2091 const Geometry *prev_geometry = NULL;
2092 const ParamOverrideMap *prev_overrides = NULL; // make it diferent than NULL
2093
2094 Geometry::Type prev_geometry_type = Geometry::GEOMETRY_INVALID;
2095
2096 glMatrixMode(GL_PROJECTION);
2097 glLoadMatrixf(&camera_projection.matrix[0][0]);
2098
2099 for (int i = 0; i < p_render_list->element_count; i++) {
2100
2101 RenderList::Element *e = p_render_list->elements[i];
2102 const Material *material = e->material;
2103 uint64_t light_hash = e->light_hash;
2104 const Skeleton *skeleton = e->skeleton;
2105 const Geometry *geometry = e->geometry;
2106 const ParamOverrideMap *material_overrides = e->material_overrides;
2107
2108 if (material != prev_material || geometry->type != prev_geometry_type) {
2109 _setup_material(e->geometry, material);
2110 //_setup_material_overrides(e->material,NULL,material_overrides);
2111 //_setup_material_skeleton(material,skeleton);
2112 } else {
2113
2114 if (material_overrides != prev_overrides) {
2115
2116 //_setup_material_overrides(e->material,prev_overrides,material_overrides);
2117 }
2118
2119 if (prev_skeleton != skeleton) {
2120 //_setup_material_skeleton(material,skeleton);
2121 };
2122 }
2123
2124 if (geometry != prev_geometry || geometry->type != prev_geometry_type) {
2125
2126 _setup_geometry(geometry, material);
2127 };
2128
2129 if (i == 0 || light_hash != prev_light_hash)
2130 _setup_lights(e->lights, e->light_count);
2131
2132 glMatrixMode(GL_MODELVIEW);
2133 _gl_load_transform(camera_transform_inverse);
2134 _gl_mult_transform(e->transform);
2135
2136 _render(geometry, material, skeleton);
2137
2138 prev_material = material;
2139 prev_skeleton = skeleton;
2140 prev_geometry = geometry;
2141 prev_light_hash = e->light_hash;
2142 prev_geometry_type = geometry->type;
2143 prev_overrides = material_overrides;
2144 }
2145 };
2146
end_scene()2147 void RasterizerIPhone::end_scene() {
2148
2149 glEnable(GL_BLEND);
2150 glDepthMask(GL_FALSE);
2151
2152 opaque_render_list.sort_mat_light();
2153 _render_list_forward(&opaque_render_list);
2154
2155 glDisable(GL_BLEND);
2156 glDepthMask(GL_TRUE);
2157
2158 alpha_render_list.sort_z();
2159 _render_list_forward(&alpha_render_list);
2160 }
end_shadow_map()2161 void RasterizerIPhone::end_shadow_map() {
2162 }
2163
end_frame()2164 void RasterizerIPhone::end_frame() {
2165
2166 //ContextGL::get_singleton()->swap_buffers();
2167 }
2168
2169 /* CANVAS API */
2170
canvas_begin()2171 void RasterizerIPhone::canvas_begin() {
2172
2173 glDisable(GL_CULL_FACE);
2174 glDisable(GL_DEPTH_TEST);
2175 glEnable(GL_BLEND);
2176 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2177 glLineWidth(1.0);
2178 glDisable(GL_LIGHTING);
2179
2180 glMatrixMode(GL_PROJECTION);
2181 glLoadIdentity();
2182 }
canvas_set_transparency(float p_transparency)2183 void RasterizerIPhone::canvas_set_transparency(float p_transparency) {
2184 }
2185
canvas_set_rect(const Rect2 & p_rect,bool p_clip)2186 void RasterizerIPhone::canvas_set_rect(const Rect2 &p_rect, bool p_clip) {
2187
2188 glMatrixMode(GL_MODELVIEW);
2189 glLoadIdentity();
2190 glScalef(2.0 / window_size.x, -2.0 / window_size.y, 0);
2191 glTranslatef((-(window_size.x / 2.0)) + p_rect.pos.x, (-(window_size.y / 2.0)) + p_rect.pos.y, 0);
2192
2193 if (p_clip) {
2194
2195 glEnable(GL_SCISSOR_TEST);
2196 glScissor(viewport.x + p_rect.pos.x, viewport.y + (viewport.height - (p_rect.pos.y + p_rect.size.height)),
2197 p_rect.size.width, p_rect.size.height);
2198 } else {
2199
2200 glDisable(GL_SCISSOR_TEST);
2201 }
2202 }
canvas_draw_line(const Point2 & p_from,const Point2 & p_to,const Color & p_color,float p_width)2203 void RasterizerIPhone::canvas_draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
2204
2205 glColor4f(1, 1, 1, 1);
2206
2207 float verts[6] = {
2208 p_from.x, p_from.y, 0,
2209 p_to.x, p_to.y, 0
2210 };
2211
2212 float colors[] = {
2213 p_color.r,
2214 p_color.g,
2215 p_color.b,
2216 p_color.a,
2217 p_color.r,
2218 p_color.g,
2219 p_color.b,
2220 p_color.a,
2221 };
2222 glLineWidth(p_width);
2223 _draw_primitive(2, verts, 0, colors, 0);
2224 }
2225
_draw_textured_quad(const Rect2 & p_rect,const Rect2 & p_src_region,const Size2 & p_tex_size)2226 static void _draw_textured_quad(const Rect2 &p_rect, const Rect2 &p_src_region, const Size2 &p_tex_size) {
2227
2228 float texcoords[] = {
2229 p_src_region.pos.x / p_tex_size.width,
2230 p_src_region.pos.y / p_tex_size.height,
2231
2232 (p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width,
2233 p_src_region.pos.y / p_tex_size.height,
2234
2235 (p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width,
2236 (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height,
2237
2238 p_src_region.pos.x / p_tex_size.width,
2239 (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height,
2240 };
2241
2242 float coords[] = {
2243 p_rect.pos.x, p_rect.pos.y, 0,
2244 p_rect.pos.x + p_rect.size.width, p_rect.pos.y, 0,
2245 p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height, 0,
2246 p_rect.pos.x, p_rect.pos.y + p_rect.size.height, 0
2247 };
2248
2249 _draw_primitive(4, coords, 0, 0, texcoords);
2250 }
2251
_draw_quad(const Rect2 & p_rect)2252 static void _draw_quad(const Rect2 &p_rect) {
2253
2254 float coords[] = {
2255 p_rect.pos.x, p_rect.pos.y, 0,
2256 p_rect.pos.x + p_rect.size.width, p_rect.pos.y, 0,
2257 p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height, 0,
2258 p_rect.pos.x, p_rect.pos.y + p_rect.size.height, 0
2259 };
2260
2261 _draw_primitive(4, coords, 0, 0, 0);
2262 }
2263
canvas_draw_rect(const Rect2 & p_rect,bool p_region,const Rect2 & p_source,bool p_tile,RID p_texture,const Color & p_modulate)2264 void RasterizerIPhone::canvas_draw_rect(const Rect2 &p_rect, bool p_region, const Rect2 &p_source, bool p_tile, RID p_texture, const Color &p_modulate) {
2265
2266 glColor4f(p_modulate.r, p_modulate.g, p_modulate.b, p_modulate.a);
2267
2268 if (p_texture.is_valid()) {
2269
2270 glEnable(GL_TEXTURE_2D);
2271 Texture *texture = texture_owner.get(p_texture);
2272 ERR_FAIL_COND(!texture);
2273 glActiveTexture(GL_TEXTURE0);
2274 glBindTexture(GL_TEXTURE_2D, texture->tex_id);
2275
2276 if (!p_region) {
2277
2278 Rect2 region = Rect2(0, 0, texture->width, texture->height);
2279 _draw_textured_quad(p_rect, region, region.size);
2280
2281 } else {
2282
2283 _draw_textured_quad(p_rect, p_source, Size2(texture->width, texture->height));
2284 }
2285 } else {
2286
2287 _draw_quad(p_rect);
2288 }
2289 }
canvas_draw_style_box(const Rect2 & p_rect,const Rect2 & p_src_region,RID p_texture,const float * p_margin,bool p_draw_center)2290 void RasterizerIPhone::canvas_draw_style_box(const Rect2 &p_rect, const Rect2 &p_src_region, RID p_texture, const float *p_margin, bool p_draw_center) {
2291
2292 glColor4f(1, 1, 1, 1);
2293
2294 Texture *texture = texture_owner.get(p_texture);
2295 ERR_FAIL_COND(!texture);
2296
2297 glEnable(GL_TEXTURE_2D);
2298 glActiveTexture(GL_TEXTURE0);
2299 glBindTexture(GL_TEXTURE_2D, texture->tex_id);
2300
2301 Rect2 region = p_src_region;
2302 if (region.size.width <= 0)
2303 region.size.width = texture->width;
2304 if (region.size.height <= 0)
2305 region.size.height = texture->height;
2306 /* CORNERS */
2307 _draw_textured_quad( // top left
2308 Rect2(p_rect.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])),
2309 Rect2(region.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])),
2310 Size2(texture->width, texture->height));
2311
2312 _draw_textured_quad( // top right
2313 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])),
2314 Rect2(Point2(region.pos.x + region.size.width - p_margin[MARGIN_RIGHT], region.pos.y), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_TOP])),
2315 Size2(texture->width, texture->height));
2316
2317 _draw_textured_quad( // bottom left
2318 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])),
2319 Rect2(Point2(region.pos.x, region.pos.y + region.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_BOTTOM])),
2320 Size2(texture->width, texture->height));
2321
2322 _draw_textured_quad( // bottom right
2323 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])),
2324 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])),
2325 Size2(texture->width, texture->height));
2326
2327 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]));
2328
2329 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]));
2330
2331 _draw_textured_quad( // top
2332 Rect2(Point2(rect_center.pos.x, p_rect.pos.y), Size2(rect_center.size.width, p_margin[MARGIN_TOP])),
2333 Rect2(Point2(src_center.pos.x, region.pos.y), Size2(src_center.size.width, p_margin[MARGIN_TOP])),
2334 Size2(texture->width, texture->height));
2335
2336 _draw_textured_quad( // bottom
2337 Rect2(Point2(rect_center.pos.x, rect_center.pos.y + rect_center.size.height), Size2(rect_center.size.width, p_margin[MARGIN_BOTTOM])),
2338 Rect2(Point2(src_center.pos.x, src_center.pos.y + src_center.size.height), Size2(src_center.size.width, p_margin[MARGIN_BOTTOM])),
2339 Size2(texture->width, texture->height));
2340
2341 _draw_textured_quad( // left
2342 Rect2(Point2(p_rect.pos.x, rect_center.pos.y), Size2(p_margin[MARGIN_LEFT], rect_center.size.height)),
2343 Rect2(Point2(region.pos.x, region.pos.y + p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_LEFT], src_center.size.height)),
2344 Size2(texture->width, texture->height));
2345
2346 _draw_textured_quad( // right
2347 Rect2(Point2(rect_center.pos.x + rect_center.size.width, rect_center.pos.y), Size2(p_margin[MARGIN_RIGHT], rect_center.size.height)),
2348 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)),
2349 Size2(texture->width, texture->height));
2350
2351 if (p_draw_center) {
2352
2353 _draw_textured_quad(
2354 rect_center,
2355 src_center,
2356 Size2(texture->width, texture->height));
2357 }
2358 }
canvas_draw_primitive(const Vector<Point2> & p_points,const Vector<Color> & p_colors,const Vector<Point2> & p_uvs,RID p_texture)2359 void RasterizerIPhone::canvas_draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) {
2360
2361 ERR_FAIL_COND(p_points.size() < 1);
2362 float verts[12];
2363 float uvs[8];
2364 float colors[16];
2365
2366 glColor4f(1, 1, 1, 1);
2367
2368 int idx = 0;
2369 for (int i = 0; i < p_points.size(); i++) {
2370
2371 verts[idx++] = p_points[i].x;
2372 verts[idx++] = p_points[i].y;
2373 verts[idx++] = 0;
2374 }
2375
2376 idx = 0;
2377 for (int i = 0; i < p_uvs.size(); i++) {
2378
2379 uvs[idx++] = p_uvs[i].x;
2380 uvs[idx++] = p_uvs[i].y;
2381 }
2382
2383 idx = 0;
2384 for (int i = 0; i < p_colors.size(); i++) {
2385
2386 colors[idx++] = p_colors[i].r;
2387 colors[idx++] = p_colors[i].g;
2388 colors[idx++] = p_colors[i].b;
2389 colors[idx++] = p_colors[i].a;
2390 };
2391
2392 if (p_texture.is_valid()) {
2393 glEnable(GL_TEXTURE_2D);
2394 Texture *texture = texture_owner.get(p_texture);
2395 if (texture) {
2396 glActiveTexture(GL_TEXTURE0);
2397 glBindTexture(GL_TEXTURE_2D, texture->tex_id);
2398 }
2399 }
2400
2401 _draw_primitive(p_points.size(), &verts[0], NULL, p_colors.size() ? &colors[0] : NULL, p_uvs.size() ? uvs : NULL);
2402 }
2403
2404 /* FX */
2405
fx_create()2406 RID RasterizerIPhone::fx_create() {
2407
2408 return RID();
2409 }
fx_get_effects(RID p_fx,List<String> * p_effects) const2410 void RasterizerIPhone::fx_get_effects(RID p_fx, List<String> *p_effects) const {
2411 }
fx_set_active(RID p_fx,const String & p_effect,bool p_active)2412 void RasterizerIPhone::fx_set_active(RID p_fx, const String &p_effect, bool p_active) {
2413 }
fx_is_active(RID p_fx,const String & p_effect) const2414 bool RasterizerIPhone::fx_is_active(RID p_fx, const String &p_effect) const {
2415
2416 return false;
2417 }
fx_get_effect_params(RID p_fx,const String & p_effect,List<PropertyInfo> * p_params) const2418 void RasterizerIPhone::fx_get_effect_params(RID p_fx, const String &p_effect, List<PropertyInfo> *p_params) const {
2419 }
fx_get_effect_param(RID p_fx,const String & p_effect,const String & p_param) const2420 Variant RasterizerIPhone::fx_get_effect_param(RID p_fx, const String &p_effect, const String &p_param) const {
2421
2422 return Variant();
2423 }
fx_set_effect_param(RID p_fx,const String & p_effect,const String & p_param,const Variant & p_pvalue)2424 void RasterizerIPhone::fx_set_effect_param(RID p_fx, const String &p_effect, const String &p_param, const Variant &p_pvalue) {
2425 }
2426
2427 /*MISC*/
2428
is_texture(const RID & p_rid) const2429 bool RasterizerIPhone::is_texture(const RID &p_rid) const {
2430
2431 return texture_owner.owns(p_rid);
2432 }
is_material(const RID & p_rid) const2433 bool RasterizerIPhone::is_material(const RID &p_rid) const {
2434
2435 return material_owner.owns(p_rid);
2436 }
is_mesh(const RID & p_rid) const2437 bool RasterizerIPhone::is_mesh(const RID &p_rid) const {
2438
2439 return mesh_owner.owns(p_rid);
2440 }
is_multimesh(const RID & p_rid) const2441 bool RasterizerIPhone::is_multimesh(const RID &p_rid) const {
2442
2443 return false;
2444 }
is_poly(const RID & p_rid) const2445 bool RasterizerIPhone::is_poly(const RID &p_rid) const {
2446
2447 return poly_owner.owns(p_rid);
2448 }
is_particles(const RID & p_beam) const2449 bool RasterizerIPhone::is_particles(const RID &p_beam) const {
2450
2451 return false;
2452 }
2453
is_beam(const RID & p_beam) const2454 bool RasterizerIPhone::is_beam(const RID &p_beam) const {
2455
2456 return false;
2457 }
2458
is_light(const RID & p_rid) const2459 bool RasterizerIPhone::is_light(const RID &p_rid) const {
2460
2461 return light_owner.owns(p_rid);
2462 }
is_light_instance(const RID & p_rid) const2463 bool RasterizerIPhone::is_light_instance(const RID &p_rid) const {
2464
2465 return light_instance_owner.owns(p_rid);
2466 }
is_particles_instance(const RID & p_rid) const2467 bool RasterizerIPhone::is_particles_instance(const RID &p_rid) const {
2468
2469 return false;
2470 }
is_skeleton(const RID & p_rid) const2471 bool RasterizerIPhone::is_skeleton(const RID &p_rid) const {
2472
2473 return skeleton_owner.owns(p_rid);
2474 }
is_fx(const RID & p_rid) const2475 bool RasterizerIPhone::is_fx(const RID &p_rid) const {
2476
2477 return fx_owner.owns(p_rid);
2478 }
is_shader(const RID & p_rid) const2479 bool RasterizerIPhone::is_shader(const RID &p_rid) const {
2480
2481 return false;
2482 }
2483
free(const RID & p_rid) const2484 void RasterizerIPhone::free(const RID &p_rid) const {
2485
2486 if (texture_owner.owns(p_rid)) {
2487
2488 // delete the texture
2489 Texture *texture = texture_owner.get(p_rid);
2490
2491 glDeleteTextures(1, &texture->tex_id);
2492
2493 texture_owner.free(p_rid);
2494 memdelete(texture);
2495
2496 } else if (material_owner.owns(p_rid)) {
2497
2498 Material *material = material_owner.get(p_rid);
2499 ERR_FAIL_COND(!material);
2500
2501 material_owner.free(p_rid);
2502 memdelete(material);
2503
2504 } else if (mesh_owner.owns(p_rid)) {
2505
2506 Mesh *mesh = mesh_owner.get(p_rid);
2507 ERR_FAIL_COND(!mesh);
2508 for (int i = 0; i < mesh->surfaces.size(); i++) {
2509
2510 Surface *surface = mesh->surfaces[i];
2511 if (surface->array_local != 0) {
2512 memfree(surface->array_local);
2513 };
2514 if (surface->index_array_local != 0) {
2515 memfree(surface->index_array_local);
2516 };
2517
2518 if (surface->vertex_id)
2519 glDeleteBuffers(1, &surface->vertex_id);
2520 if (surface->index_id)
2521 glDeleteBuffers(1, &surface->index_id);
2522
2523 memdelete(surface);
2524 };
2525
2526 mesh->surfaces.clear();
2527
2528 mesh_owner.free(p_rid);
2529 memdelete(mesh);
2530
2531 } else if (skeleton_owner.owns(p_rid)) {
2532
2533 Skeleton *skeleton = skeleton_owner.get(p_rid);
2534 ERR_FAIL_COND(!skeleton)
2535
2536 skeleton_owner.free(p_rid);
2537 memdelete(skeleton);
2538
2539 } else if (light_owner.owns(p_rid)) {
2540
2541 Light *light = light_owner.get(p_rid);
2542 ERR_FAIL_COND(!light)
2543
2544 light_owner.free(p_rid);
2545 memdelete(light);
2546
2547 } else if (light_instance_owner.owns(p_rid)) {
2548
2549 LightInstance *light_instance = light_instance_owner.get(p_rid);
2550 ERR_FAIL_COND(!light_instance);
2551
2552 light_instance_owner.free(p_rid);
2553 memdelete(light_instance);
2554
2555 } else if (fx_owner.owns(p_rid)) {
2556
2557 FX *fx = fx_owner.get(p_rid);
2558 ERR_FAIL_COND(!fx);
2559
2560 fx_owner.free(p_rid);
2561 memdelete(fx);
2562 };
2563 }
2564
init()2565 void RasterizerIPhone::init() {
2566
2567 glEnable(GL_DEPTH_TEST);
2568 glDepthFunc(GL_LEQUAL);
2569 glFrontFace(GL_CW);
2570
2571 glEnable(GL_TEXTURE_2D);
2572 }
2573
finish()2574 void RasterizerIPhone::finish() {
2575 }
2576
get_render_info(VS::RenderInfo p_info)2577 int RasterizerIPhone::get_render_info(VS::RenderInfo p_info) {
2578
2579 return false;
2580 }
2581
RasterizerIPhone()2582 RasterizerIPhone::RasterizerIPhone() {
2583
2584 frame = 0;
2585 };
2586
~RasterizerIPhone()2587 RasterizerIPhone::~RasterizerIPhone(){
2588
2589 };
2590
2591 #endif
2592