summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBogdan Devichev <b.devichev@samsung.com>2015-07-29 12:50:52 +0300
committerBogdan Devichev <b.devichev@samsung.com>2015-07-29 12:50:52 +0300
commit74af4044d09d0644182d61bc42f5b3c0ab93215c (patch)
tree0e2b37e43807c65e42532454a48e953c83d962be
Initial commit
-rw-r--r--src/evas-3d-visual-test.c965
1 files changed, 965 insertions, 0 deletions
diff --git a/src/evas-3d-visual-test.c b/src/evas-3d-visual-test.c
new file mode 100644
index 0000000..47d5b9c
--- /dev/null
+++ b/src/evas-3d-visual-test.c
@@ -0,0 +1,965 @@
1/**
2 * This example is for visual testing of rare combination of different parameters.
3 *
4 * To see help, how to work with this example press 'h' or
5 * @see _show_help()
6 *
7 * Parameters which can be changed in runtime:
8 * ortho/perspective camera and light,
9 * primitive`s type, precision and ratio,
10 * shade mode and blending functions,
11 * color components of material,
12 * textures and their scale.
13 *
14 * @verbatim
15 * gcc -o evas-3d-visual-test evas-3d-visual-test.c evas-3d-primitives.c `pkg-config --libs --cflags efl evas ecore ecore-evas eo eina` -lm
16 * @endverbatim
17 */
18
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#else
22#define PACKAGE_EXAMPLES_DIR "."
23#define EFL_EO_API_SUPPORT
24#define EFL_BETA_API_SUPPORT
25#endif
26
27#include <Eo.h>
28#include <Evas.h>
29#include <Ecore.h>
30#include <Ecore_Evas.h>
31#include <Eina.h>
32#include <math.h>
33#include "evas-3d-primitives.h"
34#include "evas-common.h"
35
36#define WIDTH 1024
37#define HEIGHT 1024
38
39#define STEP 0.1
40#define BG_COLOR 0.2, 0.2, 0.2
41#define AMBIENT_LIGHT 0.2, 0.2, 0.2
42#define DIFFUSE_LIGHT 1.0, 1.0, 1.0
43#define SPECULAR_LIGHT 1.0, 1.0, 1.0
44
45#define DEF_COORD 0.6
46#define CAM_COORD 1.3
47#define OFFSET 0.4
48
49#define PRIMITIVES_COUNT 7
50#define MAX_NUM_SHADE_MODE 7
51#define COLOR_INCR 0.1
52
53#define D_TEX_COUNT 3
54#define N_TEX_COUNT 3
55#define BLEND_M_F_COUNT 15
56
57static const char*
58tex_d_path[D_TEX_COUNT] =
59 {PACKAGE_EXAMPLES_DIR EVAS_IMAGE_FOLDER "/tree_bill.png",
60 NULL,
61 PACKAGE_EXAMPLES_DIR EVAS_IMAGE_FOLDER "/rocks.jpg"};
62
63static const char*
64tex_nh_path[N_TEX_COUNT] =
65 {PACKAGE_EXAMPLES_DIR EVAS_IMAGE_FOLDER "/grid_n.png",
66 NULL,
67 PACKAGE_EXAMPLES_DIR EVAS_IMAGE_FOLDER "/rocks_NM_height.tga"};
68
69Ecore_Evas *ecore_evas = NULL;
70Evas *evas = NULL;
71Eo *background = NULL;
72Eo *image = NULL;
73Evas_3D_Node *choosed_node = NULL;
74Eina_Bool is_camera_perspective = EINA_FALSE;
75Eina_Bool is_light_perspective = EINA_TRUE;
76int current_func = 0;
77int precision = 40;
78int cur_diff = 0;
79int cur_norm = 0;
80char mode = 'f';
81int cur_bm_f1 = EVAS_3D_BLEND_SRC_ALPHA;
82int cur_bm_f2 = EVAS_3D_BLEND_ONE_MINUS_SRC_ALPHA;
83static vec2 tex_scale = {9.0, 9.0};
84int current_shade_mode = 7; //EVAS_3D_SHADE_MODE_PHONG
85float ratio = 0.9;
86
87void (*mesh_func[PRIMITIVES_COUNT])(Eo*, int, float, vec2);
88
89typedef struct _Cell
90{
91 int id;
92 Eo *child_node;
93 Eo *parent_node;
94} Cell;
95
96Evas_Real red = 0.0, green = 0.6, blue = 0.6, transp = 0.7;
97
98typedef struct _Scene_Data
99{
100 Eo *scene;
101 Eo *root_node;
102 Eo *camera_node;
103 Eo *camera;
104 Eo *light_node;
105 Eo *light;
106
107 Eo *light_grey;
108 Eo *dark_grey;
109
110 Eo *current_material;
111 Eo *left_material;
112 Eo *right_material;
113 Eo *up_material;
114 Eo *down_material;
115
116 Eo *light_square_mesh;
117 Eo *dark_square_mesh;
118
119 Eo *current_mesh;
120 Eo *left_mesh;
121 Eo *right_mesh;
122 Eo *up_mesh;
123 Eo *down_mesh;
124
125 Eo *up_parent_node;
126 Eo *down_parent_node;
127 Eo *left_parent_node;
128 Eo *right_parent_node;
129 Eo *center_parent_node;
130 Eo *x_parent_node;
131 Eo *y_parent_node;
132 Eo *z_parent_node;
133
134 Eo *common_parent_node;
135
136 Eo *up_child_node;
137 Eo *down_child_node;
138 Eo *left_child_node;
139 Eo *right_child_node;
140 Eo *center_child_node;
141 Eo *x_child_node;
142 Eo *y_child_node;
143 Eo *z_child_node;
144
145 Eo *diff_tex[D_TEX_COUNT];
146 Eo *norm_tex[N_TEX_COUNT];
147
148 Eina_List *cells;
149} Scene_Data;
150
151static void
152_show_help()
153{
154 printf("\n");
155 printf("Press 'c' to switch ortho/perspective camera\n");
156 printf("Press 'l' to switch ortho/perspective light\n");
157 printf("\n");
158 printf("Another parameters can be changed by pressing arrows\n");
159 printf("that parameters are in pairs.\n");
160 printf("Press 'Left' or 'Right' to change first parameters in pair.\n");
161 printf("Press 'Up' or 'Down' to change second parameters in pair.\n");
162 printf("Press button of mode to change pair.\n");
163 printf("\n");
164 printf("Next lines are in format [what to press,");
165 printf("first parameter, second parameter]:\n");
166 printf("['f', primitive, shade mode]\n");
167 printf("['p', precision, ratio]\n");
168 printf("['t', diffuse and ambiemt texture, normal texture]\n");
169 printf("['s', scale of texture.x, scale of texture.y]\n");
170 printf("['m', blend functions 1 ID, blend functions 2 ID]\n");
171 printf("['r', red, transparency] (material color)\n");
172 printf("['g', green, transparency] (material color)\n");
173 printf("['b', blue, transparency] (material color)\n");
174 printf("\n");
175}
176
177static void
178_on_delete(Ecore_Evas *ee EINA_UNUSED)
179{
180 ecore_main_loop_quit();
181}
182
183static void
184_on_canvas_resize(Ecore_Evas *ee)
185{
186 int w, h;
187
188 ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
189 eo_do(background, efl_gfx_size_set(w, h));
190 eo_do(image, efl_gfx_size_set(w, h));
191}
192
193static Eo*
194_texture_init(const char *path)
195{
196 if (!path) return NULL;
197 Eo *texture = eo_add(EVAS_3D_TEXTURE_CLASS, evas);
198 eo_do(texture, evas_3d_texture_file_set(path, NULL),
199 evas_3d_texture_wrap_set(EVAS_3D_WRAP_MODE_REPEAT,
200 EVAS_3D_WRAP_MODE_REPEAT));
201 return texture;
202}
203
204static int
205_change_from_to(int what, int from, int to, int how_much)
206{
207 int res;
208
209 if (how_much == 0) res = what;
210 else if (how_much > 0)
211 {
212 if (what < to) res = what + how_much;
213 else res = from;
214 }
215 else
216 {
217 if (what > from) res = what + how_much;
218 else res = to;
219 }
220
221 return res;
222}
223
224static void
225_textures_init(Scene_Data *data)
226{
227 int i;
228 for (i = 0; i < D_TEX_COUNT; i++)
229 data->diff_tex[i] = _texture_init(tex_d_path[i]);
230 for (i = 0; i < N_TEX_COUNT; i++)
231 data->norm_tex[i] = _texture_init(tex_nh_path[i]);
232}
233
234static Eo*
235_material_init(Scene_Data *data,
236 float r, float g, float b, float a,
237 int diff_tex_num, int norm_tex_num)
238{
239 Eo *material = eo_add(EVAS_3D_MATERIAL_CLASS, evas);
240
241 eo_do(material,
242 evas_3d_material_enable_set(EVAS_3D_MATERIAL_AMBIENT, EINA_TRUE),
243 evas_3d_material_enable_set(EVAS_3D_MATERIAL_NORMAL, EINA_TRUE),
244 evas_3d_material_enable_set(EVAS_3D_MATERIAL_DIFFUSE, EINA_TRUE),
245 evas_3d_material_enable_set(EVAS_3D_MATERIAL_SPECULAR, EINA_TRUE),
246
247 evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT, r, g, b, a),
248 evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE, r, g, b, a),
249 evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR,
250 1.0, 1.0, 1.0, a),
251 evas_3d_material_shininess_set(100.0),
252
253 evas_3d_material_texture_set(EVAS_3D_MATERIAL_NORMAL,
254 data->norm_tex[norm_tex_num]),
255 evas_3d_material_texture_set(EVAS_3D_MATERIAL_DIFFUSE,
256 data->diff_tex[diff_tex_num]),
257 evas_3d_material_texture_set(EVAS_3D_MATERIAL_AMBIENT,
258 data->diff_tex[diff_tex_num]),
259 evas_3d_material_texture_set(EVAS_3D_MATERIAL_SPECULAR,
260 data->diff_tex[diff_tex_num]));
261 return material;
262}
263
264static Eo*
265_primitive_init_wrapper(int incr_func,
266 int incr_shade,
267 int incr_prec,
268 float incr_ratio,
269 float incr_tex_scale_x,
270 float incr_tex_scale_y,
271 int incr_b_f_1,
272 int incr_b_f_2)
273{
274 vec2 ts = {tex_scale.x * pow(1.1, incr_tex_scale_x),
275 tex_scale.y * pow(1.1, incr_tex_scale_y)};
276
277 Eo *mesh = eo_add(EVAS_3D_MESH_CLASS, evas);
278 mesh_func[_change_from_to(current_func, 0, PRIMITIVES_COUNT, incr_func)]
279 (mesh,
280 _change_from_to(precision, 2, 50, incr_prec),
281 ratio * pow(1.1, incr_ratio),
282 ts);
283
284 eo_do(mesh,
285 evas_3d_mesh_shade_mode_set(
286 _change_from_to(current_shade_mode, 0,
287 MAX_NUM_SHADE_MODE, incr_shade)),
288 evas_3d_mesh_blending_func_set(
289 _change_from_to(cur_bm_f1, 0,
290 BLEND_M_F_COUNT, incr_b_f_1),
291 _change_from_to(cur_bm_f2, 0,
292 BLEND_M_F_COUNT, incr_b_f_2)));
293
294 return mesh;
295}
296
297static vec3
298_shell_func(float lv, float lu)
299{
300 vec3 res;
301 float v = (lv + 1.0) * 4.0 * M_PI;
302 float u = (lu - 5.0) * 21.0;
303 float pow_v = pow(1.16, v);
304 float cos_v = cos(v);
305 float cos_u = cos(u);
306 float sin_v = sin(v);
307 res.x = 0.01 * pow_v * (1 + cos_u) * cos_v;
308 res.y = -0.01 * pow_v * (1 + cos_u) * sin_v;
309 res.z = -0.02 * pow_v * (1 + sin_v);
310 return res;
311}
312
313#define PRIMITIVE_INIT_WRAPPER(name_pub, name_priv, ...) \
314static void \
315_##name_pub##_init_wrapper(Eo *mesh, int l_precision, float ratio, vec2 ts) \
316{ \
317 evas_3d_add_##name_priv##_frame(mesh, __VA_ARGS__); \
318}
319PRIMITIVE_INIT_WRAPPER(shell, func_surface, 0, _shell_func, l_precision, ts)
320PRIMITIVE_INIT_WRAPPER(square, square, 0)
321PRIMITIVE_INIT_WRAPPER(cylinder, cylinder, 0, l_precision, ts)
322PRIMITIVE_INIT_WRAPPER(sphere, sphere, 0, l_precision, ts)
323PRIMITIVE_INIT_WRAPPER(cone, cone, 0, l_precision, ts)
324PRIMITIVE_INIT_WRAPPER(cube, cube, 0)
325PRIMITIVE_INIT_WRAPPER(torus, torus, 0, ratio, l_precision, ts)
326PRIMITIVE_INIT_WRAPPER(terrain, terrain, 0, l_precision, ts)
327#undef PRIMITIVE_INIT_WRAPPER
328
329static Eo*
330_parent_node_setup(Eo *mesh, double x, double y, double z, double size)
331{
332 Eo *node = eo_add(EVAS_3D_NODE_CLASS, evas,
333 evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH));
334 eo_do(node, evas_3d_node_mesh_add(mesh),
335 evas_3d_node_position_set(x, y, z),
336 evas_3d_node_scale_set(size, size, size),
337 evas_3d_node_orientation_angle_axis_set(180.0, 0.0, 1.0, 0.0));
338
339 return node;
340}
341
342static Eo*
343_child_node_setup(Eo *mesh, double x, double y, double z, double alpha)
344{
345 Eo *node = eo_add(EVAS_3D_NODE_CLASS, evas,
346 evas_3d_node_constructor(EVAS_3D_NODE_TYPE_MESH));
347 eo_do(node, evas_3d_node_mesh_add(mesh),
348 evas_3d_node_position_set(0.0, 0.0, -0.5),
349 evas_3d_node_orientation_angle_axis_set(alpha, x, y, z));
350
351 return node;
352}
353
354static void
355_camera_setup(Scene_Data *data)
356{
357 data->camera = eo_add(EVAS_3D_CAMERA_CLASS, evas);
358
359 eo_do(data->camera,
360 evas_3d_camera_projection_ortho_set(-CAM_COORD, CAM_COORD, -CAM_COORD,
361 CAM_COORD, -10.0, 30.0));
362
363 data->camera_node =
364 eo_add(EVAS_3D_NODE_CLASS, evas,
365 evas_3d_node_constructor(EVAS_3D_NODE_TYPE_CAMERA));
366
367 eo_do(data->camera_node,
368 evas_3d_node_camera_set(data->camera),
369 evas_3d_node_position_set(0.0, 0.0, 11.0),
370 evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 0.0, 3.0,
371 EVAS_3D_SPACE_PARENT, 0.0, 1.0, 0.0));
372
373 eo_do(data->root_node, evas_3d_node_member_add(data->camera_node));
374}
375
376static void
377_light_setup(Scene_Data *data)
378{
379 data->light = eo_add(EVAS_3D_LIGHT_CLASS, evas);
380 eo_do(data->light,
381 evas_3d_light_ambient_set(AMBIENT_LIGHT, 1.0),
382 evas_3d_light_diffuse_set(DIFFUSE_LIGHT, 1.0),
383 evas_3d_light_specular_set(SPECULAR_LIGHT, 1.0),
384 evas_3d_light_projection_perspective_set(20.0, 1.0, 8.0, 20.0));
385
386 data->light_node = eo_add(EVAS_3D_NODE_CLASS, evas,
387 evas_3d_node_constructor(EVAS_3D_NODE_TYPE_LIGHT));
388 eo_do(data->light_node,
389 evas_3d_node_light_set(data->light),
390 evas_3d_node_position_set(0.0, 0.0, 9.0),
391 evas_3d_node_look_at_set(EVAS_3D_SPACE_PARENT, 0.0, 0.0, 0.0,
392 EVAS_3D_SPACE_PARENT, 0.0, 1.0, 0.0));
393 eo_do(data->root_node, evas_3d_node_member_add(data->light_node));
394}
395
396static void
397_materials_init(Scene_Data *data)
398{
399 data->dark_grey = _material_init(data, 0.3, 0.3, 0.3, 1.0, 0, 0);
400 data->light_grey = _material_init(data, 0.6, 0.6, 0.6, 1.0, 0, 0);
401 data->current_material =
402 data->left_material =
403 data->right_material =
404 data->up_material =
405 data->down_material =
406 _material_init(data, red, green, blue, transp, 0, 0);
407}
408
409static void
410_set_materials_to_meshes(Scene_Data *data)
411{
412#define SET_MATERIAL_TO_MESH(name) \
413 eo_do(data->name##_mesh, \
414 evas_3d_mesh_frame_material_set(0, data->name##_material), \
415 evas_3d_mesh_blending_enable_set(EINA_TRUE));
416 SET_MATERIAL_TO_MESH(current)
417 SET_MATERIAL_TO_MESH(left)
418 SET_MATERIAL_TO_MESH(right)
419 SET_MATERIAL_TO_MESH(up)
420 SET_MATERIAL_TO_MESH(down)
421#undef SET_MATERIAL_TO_MESH
422}
423
424static void
425_meshes_init(Scene_Data *data)
426{
427 data->light_square_mesh = _primitive_init_wrapper(1, 0, 0, 0, 0, 0, 0, 0);
428 data->dark_square_mesh = _primitive_init_wrapper(1, 0, 0, 0, 0, 0, 0, 0);
429 data->current_mesh = _primitive_init_wrapper(0, 0, 0, 0, 0, 0, 0, 0);
430 data->left_mesh = _primitive_init_wrapper(0, 0, 0, 0, 0, 0, 0, 0);
431 data->right_mesh = _primitive_init_wrapper(0, 0, 0, 0, 0, 0, 0, 0);
432 data->up_mesh = _primitive_init_wrapper(0, 0, 0, 0, 0, 0, 0, 0);
433 data->down_mesh = _primitive_init_wrapper(0, 0, 0, 0, 0, 0, 0, 0);
434
435 eo_do(data->dark_square_mesh,
436 evas_3d_mesh_frame_material_set(0, data->dark_grey));
437 eo_do(data->light_square_mesh,
438 evas_3d_mesh_frame_material_set(0, data->light_grey));
439
440 _set_materials_to_meshes(data);
441}
442
443static void
444_init_parent_nodes(Scene_Data *data)
445{
446#define INIT_PARENT_NODE(parent_name, square_type, x, y, z, size) \
447 data->parent_name##_parent_node = \
448 _parent_node_setup(data->square_type##_square_mesh, \
449 x, y, z, size);
450 INIT_PARENT_NODE(up, dark, DEF_COORD, -DEF_COORD + OFFSET, -0.1, 0.3)
451 INIT_PARENT_NODE(down, dark, DEF_COORD, -DEF_COORD - OFFSET, -0.1, 0.3)
452 INIT_PARENT_NODE(left, dark, DEF_COORD - OFFSET, -DEF_COORD, -0.1, 0.3)
453 INIT_PARENT_NODE(right, dark, DEF_COORD + OFFSET, -DEF_COORD, -0.1, 0.3)
454 INIT_PARENT_NODE(center, dark, DEF_COORD, -DEF_COORD, -0.1, 0.3)
455 INIT_PARENT_NODE(x, dark, DEF_COORD, DEF_COORD, -0.1, 1.0)
456 INIT_PARENT_NODE(y, dark, -DEF_COORD, DEF_COORD, -0.1, 1.0)
457 INIT_PARENT_NODE(z, dark, -DEF_COORD, -DEF_COORD, -0.1, 1.0)
458 INIT_PARENT_NODE(common, light, 0.0, 0.0, -0.2, 2.4)
459#undef INIT_PARENT_NODE
460}
461
462static void
463_init_child_nodes(Scene_Data *data)
464{
465#define INIT_CHILD_NODE(node_name, mesh_name, x, y, z) \
466 data->node_name##_child_node = _child_node_setup(data->mesh_name##_mesh, \
467 x, y, z, -90.0);
468 INIT_CHILD_NODE(up, up, 1.0, 1.0, 1.0)
469 INIT_CHILD_NODE(down, down, 1.0, 1.0, 1.0)
470 INIT_CHILD_NODE(left, left, 1.0, 1.0, 1.0)
471 INIT_CHILD_NODE(right, right, 1.0, 1.0, 1.0)
472 INIT_CHILD_NODE(center, current, 1.0, 1.0, 1.0)
473 INIT_CHILD_NODE(x, current, 1.0, 0.0, 0.0)
474 INIT_CHILD_NODE(y, current, 0.0, 1.0, 0.0)
475 INIT_CHILD_NODE(z, current, 0.0, 0.0, 1.0)
476#undef INIT_CHILD_NODE
477}
478
479static void
480_init_cells(Scene_Data *data)
481{
482 data->cells = NULL;
483 int i;
484 for (i = 0; i < 8; i++)
485 {
486 Cell *tmp;
487 tmp = malloc(sizeof(Cell));
488
489#define SET_TO_CELL(name, num) \
490 if (i == num) \
491 { \
492 tmp->id = i; \
493 tmp->child_node = data->name##_child_node; \
494 tmp->parent_node = data->name##_parent_node; \
495 }
496 SET_TO_CELL(up, 0)
497 SET_TO_CELL(down, 1)
498 SET_TO_CELL(left, 2)
499 SET_TO_CELL(right, 3)
500 SET_TO_CELL(center, 4)
501 SET_TO_CELL(x, 5)
502 SET_TO_CELL(y, 6)
503 SET_TO_CELL(z, 7)
504#undef SET_TO_CELL
505
506 data->cells = eina_list_append(data->cells, tmp);
507 }
508}
509
510static void
511_clear_pointers_to_meshes(Scene_Data *data)
512{
513 Eina_List *l;
514 Cell *item;
515 EINA_LIST_FOREACH(data->cells, l, item)
516 {
517 if (item->id == 0)
518 eo_do(item->child_node, evas_3d_node_mesh_del(data->up_mesh));
519 else if (item->id == 1)
520 eo_do(item->child_node, evas_3d_node_mesh_del(data->down_mesh));
521 else if (item->id == 2)
522 eo_do(item->child_node, evas_3d_node_mesh_del(data->left_mesh));
523 else if (item->id == 3)
524 eo_do(item->child_node, evas_3d_node_mesh_del(data->right_mesh));
525 else
526 eo_do(item->child_node, evas_3d_node_mesh_del(data->current_mesh));
527 }
528}
529
530static void
531_set_pointers_to_meshes(Scene_Data *data)
532{
533 Eina_List *l;
534 Cell *item;
535 EINA_LIST_FOREACH(data->cells, l, item)
536 {
537 if (item->id == 0)
538 eo_do(item->child_node, evas_3d_node_mesh_add(data->up_mesh));
539 else if (item->id == 1)
540 eo_do(item->child_node, evas_3d_node_mesh_add(data->down_mesh));
541 else if (item->id == 2)
542 eo_do(item->child_node, evas_3d_node_mesh_add(data->left_mesh));
543 else if (item->id == 3)
544 eo_do(item->child_node, evas_3d_node_mesh_add(data->right_mesh));
545 else
546 eo_do(item->child_node, evas_3d_node_mesh_add(data->current_mesh));
547 }
548}
549
550static void
551_build_node_tree(Scene_Data *data)
552{
553 Eina_List *l;
554 Cell *item;
555 EINA_LIST_FOREACH(data->cells, l, item)
556 {
557 eo_do(item->parent_node, evas_3d_node_member_add(item->child_node));
558 eo_do(data->root_node, evas_3d_node_member_add(item->parent_node));
559 }
560 eo_do(data->root_node, evas_3d_node_member_add(data->common_parent_node));
561}
562
563static void
564_set_functions_of_primitives()
565{
566 mesh_func[3] = _cylinder_init_wrapper;
567 mesh_func[1] = _square_init_wrapper;
568 mesh_func[2] = _shell_init_wrapper;
569 mesh_func[0] = _sphere_init_wrapper;
570 mesh_func[4] = _cone_init_wrapper;
571 mesh_func[5] = _cube_init_wrapper;
572 mesh_func[6] = _torus_init_wrapper;
573 mesh_func[7] = _terrain_init_wrapper;
574}
575
576static void
577_scene_setup(Scene_Data *data)
578{
579 _set_functions_of_primitives();
580 _textures_init(data);
581
582 data->scene = eo_add(EVAS_3D_SCENE_CLASS, evas);
583
584 eo_do(data->scene,
585 evas_3d_scene_size_set(WIDTH, HEIGHT);
586 evas_3d_scene_background_color_set(BG_COLOR, 1));
587
588 data->root_node = eo_add(EVAS_3D_NODE_CLASS, evas,
589 evas_3d_node_constructor(EVAS_3D_NODE_TYPE_NODE));
590
591 _camera_setup(data);
592 _light_setup(data);
593
594 _materials_init(data);
595 _meshes_init(data);
596
597 _init_parent_nodes(data);
598 _init_child_nodes(data);
599
600 _init_cells(data);
601
602 _build_node_tree(data);
603
604 eo_do(data->scene,
605 evas_3d_scene_root_node_set(data->root_node),
606 evas_3d_scene_camera_node_set(data->camera_node),
607 evas_3d_scene_shadows_enable_set(EINA_TRUE));
608}
609
610static void
611_print_system_parameters()
612{
613 printf("\n");
614 printf("SYSTEM PARAMETERS\n");
615 printf("MODE: %c\n", mode);
616 printf("primitive_func: %d\n", current_func);
617 printf("shade mode: %d\n", current_shade_mode);
618 printf("precision: %d\n", precision);
619 printf("ratio: %f\n", ratio);
620 printf("scale of texture: {%f, %f}\n", tex_scale.x, tex_scale.y);
621 printf("diffuse and ambiemt texture: %d\n", cur_diff);
622 printf("normal texture: %d\n", cur_norm);
623 printf("blend functions ID: {%d, %d}\n", cur_bm_f1, cur_bm_f2);
624 printf("material color: {%f, %f, %f, %f}\n",
625 red, green, blue, transp);
626}
627
628static Evas_Real
629_change_color_component(Evas_Real what, Evas_Real how_much)
630{
631 Evas_Real res = what;
632 if ((what < 1.0) && (what > 0.0)) res = what + how_much;
633 return res;
634}
635
636static void
637_change_parameter(int a, int b)
638{
639 switch (mode)
640 {
641 case 'f':
642 {
643 current_shade_mode = _change_from_to(current_shade_mode, 0,
644 MAX_NUM_SHADE_MODE, b);
645 current_func = _change_from_to(current_func, 0,
646 PRIMITIVES_COUNT, a);
647 break;
648 }
649 case 'p':
650 {
651 precision = _change_from_to(precision, 2, 50, a);
652 ratio *= pow(1.1, b);
653 break;
654 }
655 case 's':
656 {
657 tex_scale.x *= pow(1.1, a);
658 tex_scale.y *= pow(1.1, b);
659 break;
660 }
661 case 't':
662 {
663 cur_diff = _change_from_to(cur_diff, 0, D_TEX_COUNT, a);
664 cur_norm = _change_from_to(cur_norm, 0, N_TEX_COUNT, b);
665 break;
666 }
667 case 'm':
668 {
669 cur_bm_f1 = _change_from_to(cur_bm_f1, 0, BLEND_M_F_COUNT, a);
670 cur_bm_f2 = _change_from_to(cur_bm_f2, 0, BLEND_M_F_COUNT, b);
671 break;
672 }
673 case 'r':
674 {
675 red = _change_color_component(red, COLOR_INCR * a);
676 transp = _change_color_component(transp, COLOR_INCR * b);
677 break;
678 }
679 case 'g':
680 {
681 green = _change_color_component(green, COLOR_INCR * a);
682 transp = _change_color_component(transp, COLOR_INCR * b);
683 break;
684 }
685 case 'b':
686 {
687 blue = _change_color_component(blue, COLOR_INCR * a);
688 transp = _change_color_component(transp, COLOR_INCR * b);
689 break;
690 }
691 default:
692 {
693 printf("Unknown mode: (mode = %c)\n", mode);
694 }
695 }
696 _print_system_parameters();
697}
698
699static Eo*
700_material_init_wrapper(Scene_Data *data,
701 Evas_Real incr_red,
702 Evas_Real incr_green,
703 Evas_Real incr_blue,
704 Evas_Real incr_transp,
705 int incr_tex_diff,
706 int incr_tex_norm)
707{
708 Eo *material =
709 _material_init(data,
710 red + incr_red, green + incr_green, blue + incr_blue,
711 transp + incr_transp,
712 ((cur_diff + incr_tex_diff + D_TEX_COUNT) % D_TEX_COUNT),
713 ((cur_norm + incr_tex_norm + N_TEX_COUNT) % N_TEX_COUNT));
714 return material;
715}
716
717static void
718_materials_update(Scene_Data *data,
719 Evas_Real incr_red,
720 Evas_Real incr_green,
721 Evas_Real incr_blue,
722 Evas_Real incr_transp,
723 int incr_tex_diff,
724 int incr_tex_norm)
725{
726 data->current_material =
727 _material_init_wrapper(data, 0.0, 0.0, 0.0, 0.0,
728 0, 0);
729 data->left_material =
730 _material_init_wrapper(data, -incr_red, -incr_green, -incr_blue, 0.0,
731 -incr_tex_diff, 0);
732 data->right_material =
733 _material_init_wrapper(data, incr_red, incr_green, incr_blue, 0.0,
734 incr_tex_diff, 0);
735 data->up_material =
736 _material_init_wrapper(data, 0.0, 0.0, 0.0, incr_transp,
737 0, incr_tex_norm);
738 data->down_material =
739 _material_init_wrapper(data, 0.0, 0.0, 0.0, incr_transp,
740 0, -incr_tex_norm);
741}
742
743static void
744_meshes_update(Scene_Data *data,
745 int incr_func,
746 int incr_shade,
747 int incr_prec,
748 float incr_ratio,
749 float incr_tex_scale_x,
750 float incr_tex_scale_y,
751 int incr_b_f_1,
752 int incr_b_f_2)
753{
754 data->current_mesh =
755 _primitive_init_wrapper(0, 0, 0, 0.0, 0.0, 0.0, 0, 0);
756 data->left_mesh =
757 _primitive_init_wrapper(-incr_func, 0, -incr_prec, 0.0,
758 -incr_tex_scale_x, 0.0, -incr_b_f_1, 0);
759 data->right_mesh =
760 _primitive_init_wrapper(incr_func, 0, incr_prec, 0.0,
761 incr_tex_scale_x, 0.0, incr_b_f_1, 0);
762 data->up_mesh =
763 _primitive_init_wrapper(0, incr_shade, 0, incr_ratio,
764 0.0, incr_tex_scale_y, 0, incr_b_f_2);
765 data->down_mesh =
766 _primitive_init_wrapper(0, -incr_shade, 0, -incr_ratio,
767 0.0, -incr_tex_scale_y, 0, -incr_b_f_2);
768}
769
770static void
771_scene_update_picker(Scene_Data *data)
772{
773 _clear_pointers_to_meshes(data);
774 switch (mode)
775 {
776 case 'f':
777 {
778 _meshes_update(data, 1, 1, 0, 0.0, 0.0, 0.0, 0, 0);
779 _materials_update(data, 0.0, 0.0, 0.0, 0.0, 0, 0);
780 break;
781 }
782 case 'p':
783 {
784 _meshes_update(data, 0, 0, 1, 1.0, 0.0, 0.0, 0, 0);
785 _materials_update(data, 0.0, 0.0, 0.0, 0.0, 0, 0);
786 break;
787 }
788 case 's':
789 {
790 _meshes_update(data, 0, 0, 0, 0.0, 1.0, 1.0, 0, 0);
791 _materials_update(data, 0.0, 0.0, 0.0, 0.0, 0, 0);
792 break;
793 }
794 case 't':
795 {
796 _meshes_update(data, 0, 0, 0, 0.0, 0.0, 0.0, 0, 0);
797 _materials_update(data, 0.0, 0.0, 0.0, 0.0, 1, 1);
798 break;
799 }
800 case 'm':
801 {
802 _meshes_update(data, 0, 0, 0, 0.0, 0.0, 0.0, 1, 1);
803 _materials_update(data, 0.0, 0.0, 0.0, 0.0, 0, 0);
804 break;
805 }
806 case 'r':
807 {
808 _meshes_update(data, 0, 0, 0, 0.0, 0.0, 0.0, 0, 0);
809 _materials_update(data, (2 * COLOR_INCR), 0.0, 0.0,
810 (2 * COLOR_INCR), 0, 0);
811 break;
812 }
813 case 'g':
814 {
815 _meshes_update(data, 0, 0, 0, 0.0, 0.0, 0.0, 0, 0);
816 _materials_update(data, 0.0, (2 * COLOR_INCR), 0.0,
817 (2 * COLOR_INCR), 0, 0);
818 break;
819 }
820 case 'b':
821 {
822 _meshes_update(data, 0, 0, 0, 0.0, 0.0, 0.0, 0, 0);
823 _materials_update(data, 0.0, 0.0, (2 * COLOR_INCR),
824 (2 * COLOR_INCR), 0, 0);
825 break;
826 }
827 default:
828 {
829 printf("Unknown mode: (mode = %c)\n", mode);
830 }
831 }
832 _set_materials_to_meshes(data);
833 _set_pointers_to_meshes(data);
834}
835
836static void
837_change_camera(Scene_Data *data)
838{
839 if (is_camera_perspective)
840 {
841 eo_do(data->camera,
842 evas_3d_camera_projection_ortho_set(-CAM_COORD, CAM_COORD,
843 -CAM_COORD, CAM_COORD,
844 -10.0, 30.0));
845 eo_do(data->camera_node,
846 evas_3d_node_position_set(0.0, 0.0, 11.0));
847 is_camera_perspective = EINA_FALSE;
848 }
849 else
850 {
851 eo_do(data->camera,
852 evas_3d_camera_projection_perspective_set(75.0, 1.0, 1.0, 10.0));
853 eo_do(data->camera_node,
854 evas_3d_node_position_set(0.0, 0.0, 3.0));
855 is_camera_perspective = EINA_TRUE;
856 }
857}
858
859static void
860_change_light(Scene_Data *data)
861{
862 if (is_light_perspective)
863 {
864 eo_do(data->light,
865 evas_3d_light_projection_ortho_set(-CAM_COORD, CAM_COORD,
866 -CAM_COORD, CAM_COORD,
867 -10.0, 30.0));
868 is_light_perspective = EINA_FALSE;
869 }
870 else
871 {
872 eo_do(data->light,
873 evas_3d_light_projection_perspective_set(20.0, 1.0, 8.0, 30.0));
874 is_light_perspective = EINA_TRUE;
875 }
876}
877
878static void
879_on_key_down(void *data,
880 Evas *e EINA_UNUSED,
881 Evas_Object *eo EINA_UNUSED,
882 void *event_info)
883{
884 Evas_Event_Key_Down *ev = event_info;
885 Scene_Data *scene = (Scene_Data *)data;
886
887 if (!strcmp("f", ev->key)) mode = 'f';
888 else if (!strcmp("r", ev->key)) mode = 'r';
889 else if (!strcmp("g", ev->key)) mode = 'g';
890 else if (!strcmp("b", ev->key)) mode = 'b';
891 else if (!strcmp("p", ev->key)) mode = 'p';
892 else if (!strcmp("t", ev->key)) mode = 't';
893 else if (!strcmp("s", ev->key)) mode = 's';
894 else if (!strcmp("m", ev->key)) mode = 'm';
895 else if (!strcmp("Left", ev->key)) _change_parameter(-1, 0);
896 else if (!strcmp("Right", ev->key)) _change_parameter(1, 0);
897 else if (!strcmp("Up", ev->key)) _change_parameter(0, 1);
898 else if (!strcmp("Down", ev->key)) _change_parameter(0, -1);
899 else if (!strcmp("c", ev->key)) _change_camera(scene);
900 else if (!strcmp("l", ev->key)) _change_light(scene);
901 else if (!strcmp("h", ev->key)) _show_help();
902 else printf("\nPress 'h' to help\n\n");
903
904 _scene_update_picker(scene);
905}
906
907static void
908_scene_fini(Scene_Data *data)
909{
910 Eina_List *l;
911 Cell * item;
912 EINA_LIST_FOREACH(data->cells, l, item)
913 {
914 free(item);
915 }
916 eina_list_free(data->cells);
917}
918
919int
920main(void)
921{
922 Scene_Data data;
923 Ecore_Animator *anim;
924 setenv("ECORE_EVAS_ENGINE", "opengl_x11", 1);
925 if (!ecore_evas_init()) return 0;
926
927 ecore_evas = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL);
928 if (!ecore_evas) return 0;
929
930 ecore_evas_callback_delete_request_set(ecore_evas, _on_delete);
931 ecore_evas_callback_resize_set(ecore_evas, _on_canvas_resize);
932 ecore_evas_show(ecore_evas);
933
934 evas = ecore_evas_get(ecore_evas);
935
936 _scene_setup(&data);
937
938 /* Add a background rectangle objects. */
939 background = eo_add(EVAS_RECTANGLE_CLASS, evas);
940 eo_do(background,
941 efl_gfx_color_set(0, 0, 0, 255),
942 efl_gfx_size_set(WIDTH, HEIGHT),
943 efl_gfx_visible_set(EINA_TRUE));
944
945 /* Add an image object for 3D scene rendering. */
946 image = evas_object_image_filled_add(evas);
947 eo_do(image,
948 efl_gfx_size_set(WIDTH, HEIGHT),
949 efl_gfx_visible_set(EINA_TRUE));
950
951 evas_object_focus_set(image, EINA_TRUE);
952 /* Set the image object as render target for 3D scene. */
953 eo_do(image, evas_obj_image_scene_set(data.scene));
954
955 evas_object_event_callback_add(image, EVAS_CALLBACK_KEY_DOWN,
956 _on_key_down, &data);
957
958 /* Enter main loop. */
959 ecore_main_loop_begin();
960 _scene_fini(&data);
961 ecore_evas_free(ecore_evas);
962 ecore_evas_shutdown();
963
964 return 0;
965}