aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/ClientHamr/extantz/extantz.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2013-01-13 17:51:58 +1000
committerDavid Walter Seikel2013-01-13 17:51:58 +1000
commit4fe55afb81dddb5bec09d1a874c42459ba947847 (patch)
tree5e8f1c834de75cddc2c33509457a00e9a2d1cb33 /ClientHamr/extantz/extantz.c
parentAdded more media, including a link to the Irrlicht media, and some images fro... (diff)
downloadSledjHamr-4fe55afb81dddb5bec09d1a874c42459ba947847.zip
SledjHamr-4fe55afb81dddb5bec09d1a874c42459ba947847.tar.gz
SledjHamr-4fe55afb81dddb5bec09d1a874c42459ba947847.tar.bz2
SledjHamr-4fe55afb81dddb5bec09d1a874c42459ba947847.tar.xz
Major rework of extantz to get Elementary, ePhysics, Evas_GL, and Irrlicht to play nice together.
Diffstat (limited to 'ClientHamr/extantz/extantz.c')
-rw-r--r--ClientHamr/extantz/extantz.c787
1 files changed, 422 insertions, 365 deletions
diff --git a/ClientHamr/extantz/extantz.c b/ClientHamr/extantz/extantz.c
index 796b47a..f0fd4c6 100644
--- a/ClientHamr/extantz/extantz.c
+++ b/ClientHamr/extantz/extantz.c
@@ -1,63 +1,7 @@
1#include <Elementary.h> 1#include "extantz.h"
2#ifndef M_PI
3#define M_PI 3.14159265
4#endif
5 2
6typedef enum 3
7{ 4#define DO_GEARS 0
8 EZP_NONE,
9 EZP_AURORA,
10 EZP_OPENSIM,
11 EZP_SECOND_LIFE,
12 EZP_SLEDJHAMR,
13 EZP_TRITIUM
14} ezPlatform;
15
16typedef struct
17{
18 char *name;
19 char *version; // Version string.
20 char *path; // OS filesystem path to the viewer install.
21 char *icon;
22 uint16_t tag; // The UUID of the texture used in the avatar bake hack.
23 uint8_t r, g, b; // Colour used for the in world tag.
24} ezViewer;
25
26typedef struct
27{
28 Eina_Clist accounts;
29 Eina_Clist landmarks;
30 char *name;
31 char *loginURI;
32 char *splashPage;
33 char *helperURI;
34 char *website;
35 char *supportPage;
36 char *registerPage;
37 char *passwordPage;
38 char *icon;
39 ezPlatform platform;
40 ezViewer *viewer;
41 Elm_Object_Item *item;
42} ezGrid;
43
44typedef struct
45{
46 Eina_Clist grid;
47 char *name;
48 char *password; // Think we need to pass unencrypted passwords to the viewer. B-(
49 char *icon;
50 ezViewer *viewer;
51} ezAccount;
52
53typedef struct
54{
55 Eina_Clist grid;
56 char *name;
57 char *sim;
58 char *screenshot;
59 short x, y, z;
60} ezLandmark;
61 5
62Eina_Hash *grids; 6Eina_Hash *grids;
63Eina_Hash *viewers; 7Eina_Hash *viewers;
@@ -90,51 +34,14 @@ static const char *img2 = PACKAGE_DATA_DIR "/images/sky_01.jpg";
90static const char *img3 = PACKAGE_DATA_DIR "/images/rock_01.jpg"; 34static const char *img3 = PACKAGE_DATA_DIR "/images/rock_01.jpg";
91 35
92 36
93typedef struct _Gear Gear; 37#define EPHYSICS_TEST_THEME "extantz"
94typedef struct _GLData GLData;
95struct _Gear
96{
97 GLfloat *vertices;
98 GLuint vbo;
99 int count;
100};
101 38
102// GL related data here..
103struct _GLData
104{
105 Evas_GL_API *glapi;
106 GLuint program;
107 GLuint vtx_shader;
108 GLuint fgmt_shader;
109 int initialized : 1;
110 int mouse_down : 1;
111
112 // Gear Stuff
113 GLfloat view_rotx;
114 GLfloat view_roty;
115 GLfloat view_rotz;
116
117 Gear *gear1;
118 Gear *gear2;
119 Gear *gear3;
120
121 GLfloat angle;
122
123 GLuint proj_location;
124 GLuint light_location;
125 GLuint color_location;
126
127 GLfloat proj[16];
128 GLfloat light[3];
129};
130 39
131static void gears_init(GLData *gld);
132static void free_gear(Gear *gear); 40static void free_gear(Gear *gear);
133static void gears_reshape(GLData *gld, int width, int height);
134static void render_gears(GLData *gld);
135 41
136//--------------------------------// 42//--------------------------------//
137// Gear Stuff.... 43// Gear Stuff.
44
138static GLfloat *vert(GLfloat *p, GLfloat x, GLfloat y, GLfloat z, GLfloat *n) 45static GLfloat *vert(GLfloat *p, GLfloat x, GLfloat y, GLfloat z, GLfloat *n)
139{ 46{
140 p[0] = x; 47 p[0] = x;
@@ -325,57 +232,22 @@ static void draw_gear(GLData *gld, Gear *gear, GLfloat *m, GLfloat x, GLfloat y,
325 gl->glDrawArrays(GL_TRIANGLE_STRIP, 0, gear->count); 232 gl->glDrawArrays(GL_TRIANGLE_STRIP, 0, gear->count);
326} 233}
327 234
328static void gears_draw(GLData *gld) 235static void gldata_init(GLData *gld)
329{ 236{
330 Evas_GL_API *gl = gld->glapi; 237 gld->useEGL = USE_EGL;
331 238 gld->useIrr = USE_IRR;
332 static const GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
333 static const GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
334 static const GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
335 GLfloat m[16];
336
337 gl->glClearColor(0.8, 0.8, 0.1, 0.5);
338 gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
339 239
340 memcpy(m, gld->proj, sizeof m); 240 gld->view_rotx = -20.0;
341 rotate(m, 2 * M_PI * gld->view_rotx / 360.0, 1, 0, 0); 241 gld->view_roty = -30.0;
342 rotate(m, 2 * M_PI * gld->view_roty / 360.0, 0, 1, 0); 242 gld->view_rotz = 0.0;
343 rotate(m, 2 * M_PI * gld->view_rotz / 360.0, 0, 0, 1); 243 gld->angle = 0.0;
344 244
345 draw_gear(gld, gld->gear1, m, -3.0, -2.0, gld->angle, red); 245 gld->light[0] = 1.0;
346 draw_gear(gld, gld->gear2, m, 3.1, -2.0, -2 * gld->angle - 9.0, green); 246 gld->light[1] = 1.0;
347 draw_gear(gld, gld->gear3, m, -3.1, 4.2, -2 * gld->angle - 25.0, blue); 247 gld->light[2] = -5.0;
348} 248}
349 249
350static void render_gears(GLData *gld) 250//-------------------------//
351{
352 gears_draw(gld);
353
354 gld->angle += 2.0;
355}
356
357/* new window size or exposure */
358static void gears_reshape(GLData *gld, int width, int height)
359{
360 Evas_GL_API *gl = gld->glapi;
361
362 GLfloat ar, m[16] = {
363 1.0, 0.0, 0.0, 0.0,
364 0.0, 1.0, 0.0, 0.0,
365 0.0, 0.0, 0.1, 0.0,
366 0.0, 0.0, 0.0, 1.0
367 };
368
369 if (width < height)
370 ar = width;
371 else
372 ar = height;
373
374 m[0] = 0.1 * ar / width;
375 m[5] = 0.1 * ar / height;
376 memcpy(gld->proj, m, sizeof gld->proj);
377 gl->glViewport(0, 0, (GLint) width, (GLint) height);
378}
379 251
380static const char vertex_shader[] = 252static const char vertex_shader[] =
381 "uniform mat4 proj;\n" 253 "uniform mat4 proj;\n"
@@ -408,207 +280,350 @@ static const char vertex_shader[] =
408 " gl_FragColor = color + white * dot(light_direction, rotated_normal);\n" 280 " gl_FragColor = color + white * dot(light_direction, rotated_normal);\n"
409 "}\n"; 281 "}\n";
410 282
411static void gears_init(GLData *gld) 283static GLuint
284load_shader(GLData *gld, GLenum type, const char *shader_src)
412{ 285{
413 Evas_GL_API *gl = gld->glapi; 286 Evas_GL_API *gl = gld->glapi;
287 GLuint shader;
288 GLint compiled = 0;
414 289
415 const char *p; 290 // Create the shader object
416 char msg[512]; 291 if (!(shader = gl->glCreateShader(type))) return 0;
417 292 gl->glShaderSource(shader, 1, &shader_src, NULL);
418 gl->glEnable(GL_CULL_FACE); 293 // Compile the shader
419 gl->glEnable(GL_DEPTH_TEST); 294 gl->glCompileShader(shader);
420 295 gl->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
421 p = vertex_shader;
422 gld->vtx_shader = gl->glCreateShader(GL_VERTEX_SHADER);
423 gl->glShaderSource(gld->vtx_shader, 1, &p, NULL);
424 gl->glCompileShader(gld->vtx_shader);
425 gl->glGetShaderInfoLog(gld->vtx_shader, sizeof msg, NULL, msg);
426 printf("vertex shader info: %s\n", msg);
427
428 p = fragment_shader;
429 gld->fgmt_shader = gl->glCreateShader(GL_FRAGMENT_SHADER);
430 gl->glShaderSource(gld->fgmt_shader, 1, &p, NULL);
431 gl->glCompileShader(gld->fgmt_shader);
432 gl->glGetShaderInfoLog(gld->fgmt_shader, sizeof msg, NULL, msg);
433 printf("fragment shader info: %s\n", msg);
434
435 gld->program = gl->glCreateProgram();
436 gl->glAttachShader(gld->program, gld->vtx_shader);
437 gl->glAttachShader(gld->program, gld->fgmt_shader);
438 gl->glBindAttribLocation(gld->program, 0, "position");
439 gl->glBindAttribLocation(gld->program, 1, "normal");
440
441 gl->glLinkProgram(gld->program);
442 gl->glGetProgramInfoLog(gld->program, sizeof msg, NULL, msg);
443 printf("info: %s\n", msg);
444
445 gl->glUseProgram(gld->program);
446 gld->proj_location = gl->glGetUniformLocation(gld->program, "proj");
447 gld->light_location = gl->glGetUniformLocation(gld->program, "light");
448 gld->color_location = gl->glGetUniformLocation(gld->program, "color");
449
450 /* make the gears */
451 gld->gear1 = make_gear(gld, 1.0, 4.0, 1.0, 20, 0.7);
452 gld->gear2 = make_gear(gld, 0.5, 2.0, 2.0, 10, 0.7);
453 gld->gear3 = make_gear(gld, 1.3, 2.0, 0.5, 10, 0.7);
454}
455
456static void gldata_init(GLData *gld)
457{
458 gld->initialized = 0;
459 gld->mouse_down = 0;
460
461 gld->view_rotx = -20.0;
462 gld->view_roty = -30.0;
463 gld->view_rotz = 0.0;
464 gld->angle = 0.0;
465 296
466 gld->light[0] = 1.0; 297 if (!compiled)
467 gld->light[1] = 1.0; 298 {
468 gld->light[2] = -5.0; 299 GLint len = 0;
300
301 gl->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
302 if (len > 1)
303 {
304 char *info = malloc(sizeof(char) * len);
305
306 if (info)
307 {
308 gl->glGetShaderInfoLog(shader, len, NULL, info);
309 printf("Error compiling shader:\n"
310 "%s\n", info);
311 free(info);
312 }
313 }
314 gl->glDeleteShader(shader);
315 return 0;
316 }
317 return shader;
469} 318}
470 319
320static void _resize_gears(GLData *gld, int w, int h)
321{
322 Evas_GL_API *gl = gld->glapi;
471 323
472//-------------------------// 324#if DO_GEARS
325 GLfloat ar, m[16] = {
326 1.0, 0.0, 0.0, 0.0,
327 0.0, 1.0, 0.0, 0.0,
328 0.0, 0.0, 0.1, 0.0,
329 0.0, 0.0, 0.0, 1.0
330 };
473 331
474static void _init_gl(Evas_Object *obj) 332 // GL Viewport stuff. you can avoid doing this if viewport is all the
475{ 333 // same as last frame if you want
476 GLData *gld = evas_object_data_get(obj, "gld"); 334 if (w < h)
335 ar = w;
336 else
337 ar = h;
477 338
478 gears_init(gld); 339 m[0] = 0.1 * ar / w;
340 m[5] = 0.1 * ar / h;
341 memcpy(gld->proj, m, sizeof gld->proj);
342#endif
343// gl->glViewport(0, 0, (GLint) w, (GLint) h);
479} 344}
480 345
481static void _del_gl(Evas_Object *obj) 346static void on_pixels(void *data, Evas_Object *obj)
482{ 347{
483 GLData *gld = evas_object_data_get(obj, "gld"); 348 static int count = 0;
484 if (!gld) 349 int w, h;
485 { 350 GLData *gld = data;
486 printf("Unable to get GLData. \n"); 351 if (!gld)
487 return; 352 return;
488 }
489 Evas_GL_API *gl = gld->glapi;
490 353
491 gl->glDeleteShader(gld->vtx_shader); 354 Evas_GL_API *gl = gld->glapi;
492 gl->glDeleteShader(gld->fgmt_shader);
493 gl->glDeleteProgram(gld->program);
494 gl->glDeleteBuffers(1, &gld->gear1->vbo);
495 gl->glDeleteBuffers(1, &gld->gear2->vbo);
496 gl->glDeleteBuffers(1, &gld->gear3->vbo);
497 355
498 free_gear(gld->gear1); 356 // get the image size in case it changed with evas_object_image_size_set()
499 free_gear(gld->gear2); 357 if (gld->r1)
500 free_gear(gld->gear3); 358 evas_object_image_size_get(gld->r1, &w, &h);
501 359
502 evas_object_data_del((Evas_Object*)obj, "..gld"); 360 if (gld->useEGL)
503 free(gld); 361 {
504} 362 // Yes, we DO need to do our own make current, coz aparently the Irrlicht one is useless.
363 evas_gl_make_current(gld->evasgl, gld->sfc, gld->ctx);
364// gl->glViewport(0, 0, (GLint) w/2, (GLint) h);
365 }
505 366
506static void _resize_gl(Evas_Object *obj) 367 if (!gld->doneIrr)
507{ 368 gld->doneIrr = startIrr(gld); // Needs to be after gld->win is shown, and needs to be done in the render thread.
508 int w, h;
509 GLData *gld = evas_object_data_get(obj, "gld");
510 369
511 elm_glview_size_get(obj, &w, &h); 370 drawIrr_start(gld);
512 371
513 // GL Viewport stuff. you can avoid doing this if viewport is all the 372 if (gld->useEGL)
514 // same as last frame if you want 373 {
515 gears_reshape(gld, w, h); 374#if DO_GEARS
375 static const GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
376 static const GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
377 static const GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
378 GLfloat m[16];
379
380 // set up the context and surface as the current one
381// if (!gld->useIrr)
382// evas_gl_make_current(gld->evasgl, gld->sfc, gld->ctx);
383
384 // GL Viewport stuff. you can avoid doing this if viewport is all the
385 // same as last frame if you want
386 // TODO - might want to do this in response to some sort of resize event instead. Looks like it's needed to run once at least anyway.
387// if (count == 0)
388 _resize_gears(gld, w, h/2);
389
390 // Draw the gears.
391// if (!gld->useIrr)
392// gl->glClearColor(0.8, 0.8, 0.1, 0.1);
393// if (!gld->useIrr)
394// gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
395
396 memcpy(m, gld->proj, sizeof m);
397 rotate(m, 2 * M_PI * gld->view_rotx / 360.0, 1, 0, 0);
398 rotate(m, 2 * M_PI * gld->view_roty / 360.0, 0, 1, 0);
399 rotate(m, 2 * M_PI * gld->view_rotz / 360.0, 0, 0, 1);
400
401 draw_gear(gld, gld->gear1, m, -3.0, -2.0, gld->angle, red);
402 draw_gear(gld, gld->gear2, m, 3.1, -2.0, -2 * gld->angle - 9.0, green);
403 draw_gear(gld, gld->gear3, m, -3.1, 4.2, -2 * gld->angle - 25.0, blue);
404 gld->angle += 2.0;
405#endif
406 }
407
408 drawIrr_end(gld);
409 count++;
516} 410}
517 411
518static void _draw_gl(Evas_Object *obj) 412static void
413on_del(void *data, Evas *e, Evas_Object *obj, void *event_info)
519{ 414{
520 Evas_GL_API *gl = elm_glview_gl_api_get(obj); 415 // on delete of our object clean up some things that don't get auto
521 GLData *gld = evas_object_data_get(obj, "gld"); 416 // deleted for us as they are not intrinsically bound to the image
417 // object as such (you could use the same context and surface across
418 // multiple image objects and re-use the evasgl handle too multiple times.
419 // here we bind them to 1 object only though by doing this.
420 GLData *gld = data;
522 if (!gld) return; 421 if (!gld) return;
422 Evas_GL_API *gl = gld->glapi;
523 423
524 render_gears(gld); 424 ecore_animator_del(gld->animator);
525 gl->glFinish();
526}
527 425
528static Eina_Bool _anim(void *data) 426 if (gld->useEGL)
529{ 427 {
530 elm_glview_changed_set(data); 428 // Do a make_current before deleting all the GL stuff.
531 return EINA_TRUE; 429 evas_gl_make_current(gld->evasgl, gld->sfc, gld->ctx);
532}
533 430
534static void _del(void *data , Evas *evas , Evas_Object *obj, void *event_info ) 431#if DO_GEARS
535{ 432 gl->glDeleteShader(gld->vtx_shader);
536 Ecore_Animator *ani = evas_object_data_get(obj, "ani"); 433 gl->glDeleteShader(gld->fgmt_shader);
537 ecore_animator_del(ani); 434 gl->glDeleteProgram(gld->program);
538}
539 435
540static void _key_down(void *data , Evas *e , Evas_Object *obj, void *event_info) 436 gl->glDeleteBuffers(1, &gld->gear1->vbo);
541{ 437 gl->glDeleteBuffers(1, &gld->gear2->vbo);
542 Evas_Event_Key_Down *ev; 438 gl->glDeleteBuffers(1, &gld->gear3->vbo);
543 ev = (Evas_Event_Key_Down *)event_info;
544 GLData *gld = evas_object_data_get(obj, "gld");
545 439
546 if (strcmp(ev->keyname, "Left") == 0) 440 free_gear(gld->gear1);
547 { 441 free_gear(gld->gear2);
548 gld->view_roty += 5.0; 442 free_gear(gld->gear3);
549 return; 443#endif
550 }
551 444
552 if (strcmp(ev->keyname, "Right") == 0) 445 // Irrlicht wants to destroy the context and surface, so only do this if Irrlicht wont.
553 { 446 if (!gld->doneIrr)
554 gld->view_roty -= 5.0; 447 {
555 return; 448 evas_gl_surface_destroy(gld->evasgl, gld->sfc);
556 } 449 evas_gl_context_destroy(gld->evasgl, gld->ctx);
450 }
451 // TODO - hope this is OK, considering the context and surface might get dealt with by Irrlicht.
452 // Might be better to teach Irrlicht to not destroy shit it did not create.
453 evas_gl_config_free(gld->cfg);
454 evas_gl_free(gld->evasgl);
455 }
557 456
558 if (strcmp(ev->keyname, "Up") == 0) 457 // TODO - Since this is created on the render thread, better hope this is being deleted on the render thread.
559 { 458 finishIrr(gld);
560 gld->view_rotx += 5.0;
561 return;
562 }
563 459
564 if (strcmp(ev->keyname, "Down") == 0) 460 free(gld);
565 {
566 gld->view_rotx -= 5.0;
567 return;
568 }
569 if ((strcmp(ev->keyname, "Escape") == 0) ||
570 (strcmp(ev->keyname, "Return") == 0))
571 {
572 //_on_done(data, obj, event_info);
573 return;
574 }
575} 461}
576 462
577static void _mouse_down(void *data , Evas *e , Evas_Object *obj, void *event_info ) 463static Eina_Bool doFrame(void *data)
578{ 464{
579 GLData *gld = evas_object_data_get(obj, "gld"); 465 GLData *gld = data;
580 gld->mouse_down = 1;
581}
582 466
583static void _mouse_move(void *data , Evas *e , Evas_Object *obj, void *event_info ) 467 // Mark the pixels as dirty, so they get rerendered each frame, then Irrlicht can draw it's stuff each frame.
584{ 468 // This causes on_pixel to be triggered by Evas_GL.
585 Evas_Event_Mouse_Move *ev; 469 if (gld->r1)
586 ev = (Evas_Event_Mouse_Move *)event_info; 470 evas_object_image_pixels_dirty_set(gld->r1, EINA_TRUE);
587 GLData *gld = evas_object_data_get(obj, "gld");
588 float dx = 0, dy = 0;
589 471
590 if (gld->mouse_down) 472 // If not using Evas_GL, we need to call on_pixel() manually.
591 { 473 if (!gld->useEGL)
592 dx = ev->cur.canvas.x - ev->prev.canvas.x; 474 on_pixels(gld, gld->r1);
593 dy = ev->cur.canvas.y - ev->prev.canvas.y;
594 475
595 gld->view_roty += -1.0 * dx; 476 return EINA_TRUE;
596 gld->view_rotx += -1.0 * dy;
597 }
598} 477}
599 478
600static void _mouse_up(void *data , Evas *e , Evas_Object *obj, void *event_info ) 479static void init_evas_gl(GLData *gld, int w, int h)
601{ 480{
602 GLData *gld = evas_object_data_get(obj, "gld"); 481 Ecore_Evas *ee;
603 gld->mouse_down = 0; 482 Evas *canvas;
483 Evas_Native_Surface ns;
484
485 if (!gld->useEGL)
486 return;
487
488 w -= 10;
489 h -= 10;
490 h = h / 2;
491
492 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(gld->win));
493 canvas = ecore_evas_get(ee);
494
495 //-//-//-// THIS IS WHERE GL INIT STUFF HAPPENS (ALA EGL)
496 //-//
497 // get the evas gl handle for doing gl things
498 gld->evasgl = evas_gl_new(canvas);
499 gld->glapi = evas_gl_api_get(gld->evasgl);
500
501 // Set a surface config
502 gld->cfg = evas_gl_config_new();
503 gld->cfg->color_format = EVAS_GL_RGBA_8888;
504 gld->cfg->depth_bits = EVAS_GL_DEPTH_BIT_32;
505 gld->cfg->stencil_bits = EVAS_GL_STENCIL_NONE;
506 gld->cfg->options_bits = EVAS_GL_OPTIONS_DIRECT;
507
508 // create a surface and context
509 gld->sfc_w = w;
510 gld->sfc_h = h;
511 gld->sfc = evas_gl_surface_create(gld->evasgl, gld->cfg, w, h);
512 gld->ctx = evas_gl_context_create(gld->evasgl, NULL); // The second NULL is for sharing contexts I think, which might be what we want to do with Irrlicht.
513 //-//
514 //-//-//-// END GL INIT BLOB
515
516 // set up the image object. a filled one by default
517 gld->r1 = evas_object_image_filled_add(canvas);
518 evas_object_size_hint_align_set(gld->r1, EVAS_HINT_FILL, EVAS_HINT_FILL);
519 evas_object_size_hint_weight_set(gld->r1, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
520 // when the object is deleted - call the on_del callback. like the above,
521 // this is just being clean
522 evas_object_event_callback_add(gld->r1, EVAS_CALLBACK_DEL, on_del, gld);
523 // set up an actual pixel size fot the buffer data. it may be different
524 // to the output size. any windowing system has something like this, just
525 // evas has 2 sizes, a pixel size and the output object size
526 evas_object_image_size_set(gld->r1, w, h);
527 // set up the native surface info to use the context and surface created
528 // above
529
530 // The ELM version does these as well.
531// elm_glview_resize_policy_set(gld->gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE); // Destroy the current surface on a resize and create a new one.
532// elm_glview_render_policy_set(gld->gl, ELM_GLVIEW_RENDER_POLICY_ALWAYS); // Always render, even if not visible.
533
534 //-//-//-// THIS IS WHERE GL INIT STUFF HAPPENS (ALA EGL)
535 //-//
536 evas_gl_native_surface_get(gld->evasgl, gld->sfc, &ns);
537 evas_object_image_native_surface_set(gld->r1, &ns);
538 evas_object_image_pixels_get_callback_set(gld->r1, on_pixels, gld);
539 //-//
540 //-//-//-// END GL INIT BLOB
541
542 evas_object_show(gld->r1);
543 elm_box_pack_end(gld->bx, gld->r1);
544
545 evas_gl_make_current(gld->evasgl, gld->sfc, gld->ctx);
546
547 gld->glapi->glEnable(GL_CULL_FACE);
548 gld->glapi->glEnable(GL_DEPTH_TEST);
549 gld->glapi->glEnable(GL_BLEND);
550 gld->glapi->glViewport(0, 0, (GLint) w, (GLint) h);
551
552#if DO_GEARS
553 GLint linked = 0;
554
555 // Load the vertex/fragment shaders
556 gld->vtx_shader = load_shader(gld, GL_VERTEX_SHADER, vertex_shader);
557 gld->fgmt_shader = load_shader(gld, GL_FRAGMENT_SHADER, fragment_shader);
558
559 // Create the program object
560 if (!(gld->program = gld->glapi->glCreateProgram()))
561 return;
562
563 gld->glapi->glAttachShader(gld->program, gld->vtx_shader);
564 gld->glapi->glAttachShader(gld->program, gld->fgmt_shader);
565
566 // Bind shader attributes.
567 gld->glapi->glBindAttribLocation(gld->program, 0, "position");
568 gld->glapi->glBindAttribLocation(gld->program, 1, "normal");
569 // Link the program
570 gld->glapi->glLinkProgram(gld->program);
571 gld->glapi->glGetProgramiv(gld->program, GL_LINK_STATUS, &linked);
572
573 if (!linked)
574 {
575 GLint len = 0;
576
577 gld->glapi->glGetProgramiv(gld->program, GL_INFO_LOG_LENGTH, &len);
578 if (len > 1)
579 {
580 char *info = malloc(sizeof(char) * len);
581
582 if (info)
583 {
584 gld->glapi->glGetProgramInfoLog(gld->program, len, NULL, info);
585 printf("Error linking program:\n%s\n", info);
586 free(info);
587 }
588 }
589 gld->glapi->glDeleteProgram(gld->program);
590 }
591
592 gld->glapi->glUseProgram(gld->program);
593 gld->proj_location = gld->glapi->glGetUniformLocation(gld->program, "proj");
594 gld->light_location = gld->glapi->glGetUniformLocation(gld->program, "light");
595 gld->color_location = gld->glapi->glGetUniformLocation(gld->program, "color");
596
597 /* make the gears */
598 gld->gear1 = make_gear(gld, 1.0, 4.0, 1.0, 20, 0.7);
599 gld->gear2 = make_gear(gld, 0.5, 2.0, 2.0, 10, 0.7);
600 gld->gear3 = make_gear(gld, 1.3, 2.0, 0.5, 10, 0.7);
601#endif
602
603 // NOTE: if you delete r1, this animator will keep running trying to access
604 // r1 so you'd better delete this animator with ecore_animator_del() or
605 // structure how you do animation differently. you can also attach it like
606 // evasgl, sfc, etc. etc. if this animator is specific to this object
607 // only and delete it in the del handler for the obj.
608 //
609 // TODO - apparently the proper way to deal with the new async rendering is to have this animator do the dirty thing, and call the Irrlicht rendering stuff in the on_pixel call set above.
610 // That still leaves the problem of the Irrlicht setup being in the main thread. Which also should be done in on_pixel, as that's done in the correct thread.
611// ecore_animator_frametime_set(1.0);
612 gld->animator = ecore_animator_add(doFrame, gld); // This animator will be called every frame tick, which defaults to 1/30 seconds.
613
614 return;
604} 615}
605 616
617
618//-------------------------//
619
620
606static Evas_Object *_content_image_new(Evas_Object *parent, const char *img) 621static Evas_Object *_content_image_new(Evas_Object *parent, const char *img)
607{ 622{
608 Evas_Object *ic; 623 Evas_Object *ic;
609 624
610 ic = elm_icon_add(parent); 625 ic = elm_icon_add(parent);
611 elm_icon_file_set(ic, img, NULL); 626 elm_image_file_set(ic, img, NULL);
612 return ic; 627 return ic;
613} 628}
614 629
@@ -655,7 +670,7 @@ static Evas_Object *_grid_content_get(void *data, Evas_Object *obj, const char *
655 evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); 670 evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
656 return ic; 671 return ic;
657} 672}
658 673
659static char * _account_label_get(void *data, Evas_Object *obj, const char *part) 674static char * _account_label_get(void *data, Evas_Object *obj, const char *part)
660{ 675{
661 ezAccount *thisAccount = data; 676 ezAccount *thisAccount = data;
@@ -679,7 +694,7 @@ static Evas_Object *_account_content_get(void *data, Evas_Object *obj, const cha
679 evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1); 694 evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
680 return ic; 695 return ic;
681} 696}
682 697
683static void _grid_sel_cb(void *data, Evas_Object *obj, void *event_info) 698static void _grid_sel_cb(void *data, Evas_Object *obj, void *event_info)
684{ 699{
685 ezGrid *thisGrid = data; 700 ezGrid *thisGrid = data;
@@ -691,23 +706,26 @@ static void _grid_sel_cb(void *data, Evas_Object *obj, void *event_info)
691 system(buf); 706 system(buf);
692} 707}
693 708
694
695EAPI_MAIN int elm_main(int argc, char **argv) 709EAPI_MAIN int elm_main(int argc, char **argv)
696{ 710{
697 Evas_Object *win, *bg, *bx, *mn, *tb, *bt, *menu, *gl, *nf, *tab, *list; 711 Evas_Object *bg, *tb, *bt, *menu, *nf, *tab, *list;
698 Elm_Object_Item *tb_it, *menu_it, *tab_it; 712 Elm_Object_Item *tb_it, *menu_it, *tab_it;
699 Ecore_Animator *ani; 713 EPhysics_Body *boundary;
714 EPhysics_World *world;
715 EPhysics_Body *box_body1, *box_body2;
716 Evas_Object *box1, *box2;
700 GLData *gld = NULL; 717 GLData *gld = NULL;
701 int i; 718 int i;
702 Eina_Bool gotWebKit = elm_need_web(); // Initialise ewebkit if it exists, or return EINA_FALSE if it don't. 719 Eina_Bool gotWebKit = elm_need_web(); // Initialise ewebkit if it exists, or return EINA_FALSE if it don't.
703 720
704/* raster says doing this is a good idea... 721/* raster says doing this is a good idea...
705 // if you want efl to handle finding your bin/lib/data dirs for u, you must do this below. 722 // if you want efl to handle finding your bin/lib/data dirs for u, you must do this below.
706 elm_app_info_set(elm_main, "datadir", "some-data-file"); 723 elm_app_info_set(elm_main, "datadir", "some-data-file");
707 elm_app_compile_bin_dir_set(PACKAGE_BIN_DIR); 724 elm_app_compile_bin_dir_set(PACKAGE_BIN_DIR);
708 elm_app_compile_data_dir_set(PACKAGE_DATA_DIR); 725 elm_app_compile_data_dir_set(PACKAGE_DATA_DIR);
709*/ 726*/
710 727
728// Raster says these are set via the elementary_config tool, which is hard to find.
711 elm_config_finger_size_set(0); 729 elm_config_finger_size_set(0);
712 elm_config_scale_set(1.0); 730 elm_config_scale_set(1.0);
713 731
@@ -715,31 +733,39 @@ EAPI_MAIN int elm_main(int argc, char **argv)
715 if (!(gld = calloc(1, sizeof(GLData)))) return; 733 if (!(gld = calloc(1, sizeof(GLData)))) return;
716 gldata_init(gld); 734 gldata_init(gld);
717 735
718 // new window - do the usual and give it a name, title and delete handler
719 // Set the engine to opengl_x11 736 // Set the engine to opengl_x11
720 elm_config_preferred_engine_set("opengl_x11"); 737 if (gld->useEGL)
721 win = elm_win_util_standard_add("extantz", "GLView"); 738 elm_config_preferred_engine_set("opengl_x11");
739 else
740 elm_config_preferred_engine_set("software_x11");
741 gld->win = elm_win_util_standard_add("extantz", "GLView");
722 // Set preferred engine back to default from config 742 // Set preferred engine back to default from config
723 elm_config_preferred_engine_set(NULL); 743 elm_config_preferred_engine_set(NULL);
724 744
725 elm_win_title_set(win, "extantz virtual world manager"); 745 if (!ephysics_init())
726 evas_object_smart_callback_add(win, "delete,request", _on_done, NULL); 746 return 1;
727 747
728 elm_win_screen_size_get(win, &x, &y, &w, &h); 748 elm_win_title_set(gld->win, "extantz virtual world manager");
749 evas_object_smart_callback_add(gld->win, "delete,request", _on_done, NULL);
729 750
730 bg = elm_bg_add(win); 751 elm_win_screen_size_get(gld->win, &x, &y, &w, &h);
731 elm_win_resize_object_add(win, bg); 752 w = w / 5;
753 h = h - 30;
754
755 bg = elm_bg_add(gld->win);
756 elm_win_resize_object_add(gld->win, bg);
732 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 757 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
733 evas_object_show(bg); 758 evas_object_show(bg);
734 759
735 bx = elm_box_add(win); 760
736 elm_win_resize_object_add(win, bx); 761 gld->bx = elm_box_add(gld->win);
737 evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 762 elm_win_resize_object_add(gld->win, gld->bx);
738 evas_object_size_hint_align_set(bx, EVAS_HINT_FILL, EVAS_HINT_FILL); 763 evas_object_size_hint_weight_set(gld->bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
739 evas_object_show(bx); 764 evas_object_size_hint_align_set(gld->bx, EVAS_HINT_FILL, EVAS_HINT_FILL);
765 evas_object_show(gld->bx);
740 766
741 // A tab thingy. 767 // A tab thingy.
742 tb = elm_toolbar_add(win); 768 tb = elm_toolbar_add(gld->win);
743 evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, 0.0); 769 evas_object_size_hint_weight_set(tb, EVAS_HINT_EXPAND, 0.0);
744 evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL); 770 evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
745 evas_object_show(tb); 771 evas_object_show(tb);
@@ -760,10 +786,10 @@ EAPI_MAIN int elm_main(int argc, char **argv)
760 elm_menu_item_separator_add(menu, menu_it); 786 elm_menu_item_separator_add(menu, menu_it);
761 elm_menu_item_add(menu, menu_it, NULL, "about extantz", NULL, NULL); 787 elm_menu_item_add(menu, menu_it, NULL, "about extantz", NULL, NULL);
762 elm_menu_item_separator_add(menu, menu_it); 788 elm_menu_item_separator_add(menu, menu_it);
763 elm_menu_item_add(menu, NULL, NULL, "quit", _on_done, win); 789 elm_menu_item_add(menu, NULL, NULL, "quit", _on_done, gld->win);
764 elm_toolbar_menu_parent_set(tb, win); 790 elm_toolbar_menu_parent_set(tb, gld->win);
765 791
766 nf = elm_naviframe_add(win); 792 nf = elm_naviframe_add(gld->win);
767 evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); 793 evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
768 evas_object_size_hint_align_set(nf, EVAS_HINT_FILL, EVAS_HINT_FILL); 794 evas_object_size_hint_align_set(nf, EVAS_HINT_FILL, EVAS_HINT_FILL);
769 evas_object_show(nf); 795 evas_object_show(nf);
@@ -782,10 +808,10 @@ EAPI_MAIN int elm_main(int argc, char **argv)
782 account_gic->func.state_get = NULL; 808 account_gic->func.state_get = NULL;
783 account_gic->func.del = NULL; 809 account_gic->func.del = NULL;
784 810
785 list = elm_genlist_add(win); 811 list = elm_genlist_add(gld->win);
786 tab = _content_image_new(win, img1); tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Accounts", _promote, tab_it); 812 tab = _content_image_new(gld->win, img1); tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Accounts", _promote, tab_it);
787 tab = _content_image_new(win, img2); tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Viewers", _promote, tab_it); 813 tab = _content_image_new(gld->win, img2); tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Viewers", _promote, tab_it);
788 tab = _content_image_new(win, img3); tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Landmarks", _promote, tab_it); 814 tab = _content_image_new(gld->win, img3); tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Landmarks", _promote, tab_it);
789 tab = list; tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Grids", _promote, tab_it); 815 tab = list; tab_it = elm_naviframe_item_push(nf, NULL, NULL, NULL, tab, NULL); elm_naviframe_item_title_visible_set(tab_it, EINA_FALSE); elm_toolbar_item_append(tb, NULL, "Grids", _promote, tab_it);
790 816
791 grids = eina_hash_stringshared_new(free); 817 grids = eina_hash_stringshared_new(free);
@@ -821,54 +847,85 @@ EAPI_MAIN int elm_main(int argc, char **argv)
821 } 847 }
822 } 848 }
823 849
824 // Add a GLView 850 bt = elm_button_add(gld->win);
825 gl = elm_glview_add(win);
826 evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
827 evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
828 elm_glview_mode_set(gl, ELM_GLVIEW_ALPHA|ELM_GLVIEW_DEPTH);
829 elm_glview_resize_policy_set(gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE);
830 elm_glview_render_policy_set(gl, ELM_GLVIEW_RENDER_POLICY_ALWAYS);
831 elm_glview_init_func_set(gl, _init_gl);
832 elm_glview_del_func_set(gl, _del_gl);
833 elm_glview_resize_func_set(gl, _resize_gl);
834 elm_glview_render_func_set(gl, (Elm_GLView_Func_Cb)_draw_gl);
835 evas_object_show(gl);
836
837 // Add Mouse/Key Event Callbacks
838 elm_object_focus_set(gl, EINA_TRUE);
839 evas_object_event_callback_add(gl, EVAS_CALLBACK_KEY_DOWN, _key_down, gl);
840 evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, gl);
841 evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_UP, _mouse_up, gl);
842 evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, gl);
843
844 // Animator and other vars
845 ani = ecore_animator_add(_anim, gl);
846 gld->glapi = elm_glview_gl_api_get(gl);
847 evas_object_data_set(gl, "ani", ani);
848 evas_object_data_set(gl, "gld", gld);
849 evas_object_event_callback_add(gl, EVAS_CALLBACK_DEL, _del, gl);
850
851 bt = elm_button_add(win);
852 elm_object_text_set(bt, "Login"); 851 elm_object_text_set(bt, "Login");
853 evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); 852 evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
854 evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); 853 evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
855 evas_object_show(bt); 854 evas_object_show(bt);
856// evas_object_smart_callback_add(bt, "clicked", NULL, NULL); 855// evas_object_smart_callback_add(bt, "clicked", NULL, NULL);
857 856
858 elm_box_pack_end(bx, mn); 857#if USE_PHYSICS
859 elm_box_pack_end(bx, tb); 858 // ePhysics stuff.
860 elm_box_pack_end(bx, nf); 859 world = ephysics_world_new();
861 elm_box_pack_end(bx, bt); 860 ephysics_world_render_geometry_set(world, 0, 0, -50, w, h, 100);
862 elm_box_pack_end(bx, gl); 861
862 boundary = ephysics_body_bottom_boundary_add(world);
863 ephysics_body_restitution_set(boundary, 1);
864 ephysics_body_friction_set(boundary, 0);
865
866 boundary = ephysics_body_top_boundary_add(world);
867 ephysics_body_restitution_set(boundary, 1);
868 ephysics_body_friction_set(boundary, 0);
869
870 boundary = ephysics_body_left_boundary_add(world);
871 ephysics_body_restitution_set(boundary, 1);
872 ephysics_body_friction_set(boundary, 0);
873
874 boundary = ephysics_body_right_boundary_add(world);
875 ephysics_body_restitution_set(boundary, 1);
876 ephysics_body_friction_set(boundary, 0);
877
878 box1 = elm_image_add(gld->win);
879 elm_image_file_set(box1, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "blue-cube");
880 evas_object_move(box1, w / 2 - 80, h - 200);
881 evas_object_resize(box1, 70, 70);
882 evas_object_show(box1);
883
884 box_body1 = ephysics_body_box_add(world);
885 ephysics_body_evas_object_set(box_body1, box1, EINA_TRUE);
886 ephysics_body_restitution_set(box_body1, 0.7);
887 ephysics_body_friction_set(box_body1, 0);
888 ephysics_body_linear_velocity_set(box_body1, -150, 200, 0);
889 ephysics_body_angular_velocity_set(box_body1, 0, 0, 36);
890 ephysics_body_sleeping_threshold_set(box_body1, 0.1, 0.1);
891
892 box2 = elm_image_add(gld->win);
893 elm_image_file_set(box2, PACKAGE_DATA_DIR "/" EPHYSICS_TEST_THEME ".edj", "purple-cube");
894 evas_object_move(box2, w / 2 + 10, h - 200);
895 evas_object_resize(box2, 70, 70);
896 evas_object_show(box2);
897
898 box_body2 = ephysics_body_box_add(world);
899 ephysics_body_evas_object_set(box_body2, box2, EINA_TRUE);
900 ephysics_body_restitution_set(box_body2, 0.7);
901 ephysics_body_friction_set(box_body2, 0);
902 ephysics_body_linear_velocity_set(box_body2, 80, -60, 0);
903 ephysics_body_angular_velocity_set(box_body2, 0, 0, 360);
904 ephysics_body_sleeping_threshold_set(box_body2, 0.1, 0.1);
905
906 ephysics_world_gravity_set(world, 0, 0, 0);
907#endif
908
909 elm_box_pack_end(gld->bx, tb);
910 elm_box_pack_end(gld->bx, nf);
911 elm_box_pack_end(gld->bx, bt);
863 912
864 evas_object_move(win, x, y); 913 // This does an elm_box_pack_end(), so needs to be after the others.
865 evas_object_resize(win, w / 5, h - 30); 914 init_evas_gl(gld, w, h);
866 evas_object_show(win); 915
916 evas_object_move(gld->win, x, y);
917 evas_object_resize(gld->win, w, h);
918 evas_object_show(gld->win);
867 919
868 elm_run(); 920 elm_run();
921
922#if USE_PHYSICS
923 ephysics_world_del(world);
924 ephysics_shutdown();
925#endif
926
869 elm_shutdown(); 927 elm_shutdown();
870 928
871 return 0; 929 return 0;
872} 930}
873ELM_MAIN() 931ELM_MAIN()
874