-#include <Elementary.h>
#ifdef HAVE_CONFIG_H
# include "elementary_config.h"
#endif
+#include <Elementary.h>
#ifndef ELM_LIB_QUICKLAUNCH
+#include <Elementary.h>
#ifndef M_PI
#define M_PI 3.14159265
#endif
-typedef struct _Gear {
+typedef struct _Gear Gear;
+typedef struct _GLData GLData;
+struct _Gear
+{
GLfloat *vertices;
GLuint vbo;
int count;
-} Gear;
+};
// GL related data here..
-typedef struct _GLData
+struct _GLData
{
Evas_GL_API *glapi;
GLuint program;
GLfloat proj[16];
GLfloat light[3];
-
-} GLData;
-
+};
static void gears_init(GLData *gld);
+static void free_gear(Gear *gear);
static void gears_reshape(GLData *gld, int width, int height);
static void render_gears(GLData *gld);
/* Draw a gear wheel. You'll probably want to call this function when
* building a display list since we do a lot of trig here.
- *
+ *
* Input: inner_radius - radius of hole at center
* outer_radius - radius at center of teeth
* width - width of gear
*/
static Gear *
make_gear(GLData *gld, GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
- GLint teeth, GLfloat tooth_depth)
+ GLint teeth, GLfloat tooth_depth)
{
GLint i;
GLfloat r0, r1, r2;
gear = (Gear*)malloc(sizeof(Gear));
if (gear == NULL)
- return NULL;
+ return NULL;
r0 = inner_radius;
r1 = outer_radius - tooth_depth / 2.0;
s[4] = 0;
c[4] = 1;
v = gear->vertices;
- for (i = 0; i < teeth; i++)
+ for (i = 0; i < teeth; i++)
{
s[0] = s[4];
c[0] = c[4];
gl->glBufferData(GL_ARRAY_BUFFER, gear->count * 6 * 4,
gear->vertices, GL_STATIC_DRAW);
+
return gear;
}
static void
+free_gear(Gear *gear)
+{
+ free(gear->vertices);
+ free(gear);
+ gear = NULL;
+}
+
+static void
multiply(GLfloat *m, const GLfloat *n)
{
GLfloat tmp[16];
div_t d;
int i, j;
- for (i = 0; i < 16; i++)
+ for (i = 0; i < 16; i++)
{
tmp[i] = 0;
d = div(i, 4);
row = n + d.quot * 4;
column = m + d.rem;
for (j = 0; j < 4; j++)
- tmp[i] += row[j] * column[j * 4];
+ tmp[i] += row[j] * column[j * 4];
}
memcpy(m, &tmp, sizeof tmp);
}
s = sin(angle);
c = cos(angle);
- GLfloat r[16] =
+ GLfloat r[16] =
{
x * x * (1 - c) + c, y * x * (1 - c) + z * s, x * z * (1 - c) - y * s, 0,
- x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0,
+ x * y * (1 - c) - z * s, y * y * (1 - c) + c, y * z * (1 - c) + x * s, 0,
x * z * (1 - c) + y * s, y * z * (1 - c) - x * s, z * z * (1 - c) + c, 0,
0, 0, 0, 1
};
static const GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
static const GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
static const GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
- GLfloat m[16];
+ GLfloat m[16];
gl->glClearColor(0.8, 0.8, 0.1, 0.5);
gl->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
draw_gear(gld, gld->gear3, m, -3.1, 4.2, -2 * gld->angle - 25.0, blue);
}
-
static void render_gears(GLData *gld)
{
gears_draw(gld);
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 0.1, 0.0,
- 0.0, 0.0, 0.0, 1.0,
+ 0.0, 0.0, 0.0, 1.0
};
-
+
if (width < height)
- ar = width;
+ ar = width;
else
- ar = height;
+ ar = height;
m[0] = 0.1 * ar / width;
m[5] = 0.1 * ar / height;
"}\n";
static const char fragment_shader[] =
- //"precision mediump float;\n"
+ "#ifdef GL_ES\n"
+ "precision mediump float;\n"
+ "#endif\n"
"uniform vec4 color;\n"
"uniform vec3 light;\n"
"varying vec3 rotated_normal;\n"
"varying vec3 rotated_position;\n"
"vec3 light_direction;\n"
- "vec4 white = vec4(0.3, 0.3, 0.5, 1.0);\n"
+ "vec4 white = vec4(0.5, 0.5, 0.5, 1.0);\n"
"void main()\n"
"{\n"
" light_direction = normalize(light - rotated_position);\n"
gl->glShaderSource(gld->vtx_shader, 1, &p, NULL);
gl->glCompileShader(gld->vtx_shader);
gl->glGetShaderInfoLog(gld->vtx_shader, sizeof msg, NULL, msg);
- //printf("vertex shader info: %s\n", msg);
+ printf("vertex shader info: %s\n", msg);
p = fragment_shader;
gld->fgmt_shader = gl->glCreateShader(GL_FRAGMENT_SHADER);
gl->glShaderSource(gld->fgmt_shader, 1, &p, NULL);
gl->glCompileShader(gld->fgmt_shader);
gl->glGetShaderInfoLog(gld->fgmt_shader, sizeof msg, NULL, msg);
- //printf("fragment shader info: %s\n", msg);
+ printf("fragment shader info: %s\n", msg);
gld->program = gl->glCreateProgram();
gl->glAttachShader(gld->program, gld->vtx_shader);
gl->glLinkProgram(gld->program);
gl->glGetProgramInfoLog(gld->program, sizeof msg, NULL, msg);
- //printf("info: %s\n", msg);
+ printf("info: %s\n", msg);
gl->glUseProgram(gld->program);
gld->proj_location = gl->glGetUniformLocation(gld->program, "proj");
gld->gear3 = make_gear(gld, 1.3, 2.0, 0.5, 10, 0.7);
}
-
static void
gldata_init(GLData *gld)
{
gld->view_rotz = 0.0;
gld->angle = 0.0;
- gld->light[0] = 1.0;
- gld->light[1] = 1.0;
- gld->light[2] = -5.0;
+ gld->light[0] = 1.0;
+ gld->light[1] = 1.0;
+ gld->light[2] = -5.0;
}
//-------------------------//
static void
-_draw_gl(Evas_Object *obj)
+_init_gl(Evas_Object *obj)
{
- int w, h;
- Evas_GL_API *gl = elm_glview_gl_api_get(obj);
GLData *gld = evas_object_data_get(obj, "gld");
- if (!gld) return;
-
- elm_glview_size_get(obj, &w, &h);
- if (!gld->initialized)
+ gears_init(gld);
+}
+
+static void
+_del_gl(Evas_Object *obj)
+{
+ GLData *gld = evas_object_data_get(obj, "gld");
+ if (!gld)
{
- gears_init(gld);
- gld->initialized = 1;
+ printf("Unable to get GLData. \n");
+ return;
}
+ Evas_GL_API *gl = gld->glapi;
+
+ gl->glDeleteShader(gld->vtx_shader);
+ gl->glDeleteShader(gld->fgmt_shader);
+ gl->glDeleteProgram(gld->program);
+ gl->glDeleteBuffers(1, &gld->gear1->vbo);
+ gl->glDeleteBuffers(1, &gld->gear2->vbo);
+ gl->glDeleteBuffers(1, &gld->gear3->vbo);
+
+ free_gear(gld->gear1);
+ free_gear(gld->gear2);
+ free_gear(gld->gear3);
+
+ evas_object_data_del((Evas_Object*)obj, "..gld");
+ free(gld);
+}
+
+static void
+_resize_gl(Evas_Object *obj)
+{
+ int w, h;
+ GLData *gld = evas_object_data_get(obj, "gld");
+
+ elm_glview_size_get(obj, &w, &h);
// GL Viewport stuff. you can avoid doing this if viewport is all the
// same as last frame if you want
gears_reshape(gld, w,h);
+}
+
+static void
+_draw_gl(Evas_Object *obj)
+{
+ Evas_GL_API *gl = elm_glview_gl_api_get(obj);
+ GLData *gld = evas_object_data_get(obj, "gld");
+ if (!gld) return;
render_gears(gld);
gl->glFinish();
evas_object_del((Evas_Object*)data);
}
-
static void
-_del(void *data, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+_del(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- GLData *gld = evas_object_data_get(data, "gld");
- if (!gld)
- {
- printf("Unable to get GLData. \n");
- return;
- }
- Evas_GL_API *gl = gld->glapi;
-
- gl->glDeleteShader(gld->vtx_shader);
- gl->glDeleteShader(gld->fgmt_shader);
- gl->glDeleteProgram(gld->program);
- evas_object_data_del((Evas_Object*)data, "..gld");
- free(gld);
-
Ecore_Animator *ani = evas_object_data_get(obj, "ani");
ecore_animator_del(ani);
}
-
-static void
-_key_down(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
+static void
+_key_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info)
{
Evas_Event_Key_Down *ev;
ev = (Evas_Event_Key_Down *)event_info;
if ((strcmp(ev->keyname, "Escape") == 0) ||
(strcmp(ev->keyname, "Return") == 0))
{
- _on_done(data, obj, event_info);
+ //_on_done(data, obj, event_info);
return;
}
}
-static void
+static void
_mouse_down(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- GLData *gld = evas_object_data_get(obj, "gld");
- gld->mouse_down = 1;
+ GLData *gld = evas_object_data_get(obj, "gld");
+ gld->mouse_down = 1;
}
-static void
+static void
_mouse_move(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- Evas_Event_Mouse_Move *ev;
- ev = (Evas_Event_Mouse_Move *)event_info;
- GLData *gld = evas_object_data_get(obj, "gld");
- float dx = 0, dy = 0;
-
- if (gld->mouse_down)
- {
- dx = ev->cur.canvas.x - ev->prev.canvas.x;
- dy = ev->cur.canvas.y - ev->prev.canvas.y;
-
- gld->view_roty += -1.0 * dx;
- gld->view_rotx += -1.0 * dy;
- }
+ Evas_Event_Mouse_Move *ev;
+ ev = (Evas_Event_Mouse_Move *)event_info;
+ GLData *gld = evas_object_data_get(obj, "gld");
+ float dx = 0, dy = 0;
+
+ if (gld->mouse_down)
+ {
+ dx = ev->cur.canvas.x - ev->prev.canvas.x;
+ dy = ev->cur.canvas.y - ev->prev.canvas.y;
+
+ gld->view_roty += -1.0 * dx;
+ gld->view_rotx += -1.0 * dy;
+ }
}
-static void
+static void
_mouse_up(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
{
- GLData *gld = evas_object_data_get(obj, "gld");
- gld->mouse_down = 0;
+ GLData *gld = evas_object_data_get(obj, "gld");
+ gld->mouse_down = 0;
}
-
void
test_glview(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
- Evas_Object *win, *bg, *bx, *bt, *gl;
+ Evas_Object *win, *bx, *bt, *gl;
Ecore_Animator *ani;
GLData *gld = NULL;
-
+
+ // alloc a data struct to hold our relevant gl info in
if (!(gld = calloc(1, sizeof(GLData)))) return;
gldata_init(gld);
- win = elm_win_add(NULL, "glview", ELM_WIN_BASIC);
- elm_win_title_set(win, "GLView");
- elm_win_autodel_set(win, 1);
+ // new window - do the usual and give it a name, title and delete handler
+ // Set the engine to opengl_x11
+ elm_config_preferred_engine_set("opengl_x11");
+ win = elm_win_util_standard_add("glview", "GLView");
+ // Set preferred engine back to default from config
+ elm_config_preferred_engine_set(NULL);
- bg = elm_bg_add(win);
- elm_win_resize_object_add(win, bg);
- evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- evas_object_show(bg);
+ elm_win_autodel_set(win, EINA_TRUE);
bx = elm_box_add(win);
evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_win_resize_object_add(win, bx);
evas_object_show(bx);
-
+
+ // Add a GLView
gl = elm_glview_add(win);
evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
- elm_glview_mode_set(gl, ELM_GLVIEW_ALPHA | ELM_GLVIEW_DEPTH);
-// elm_glview_scale_policy_set(gl, ELM_GLVIEW_RESIZE_POLICY_SCALE);
-// elm_glview_size_set(gl, 256, 256);
- elm_glview_scale_policy_set(gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE);
+ elm_glview_mode_set(gl, ELM_GLVIEW_ALPHA|ELM_GLVIEW_DEPTH);
+ elm_glview_resize_policy_set(gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE);
elm_glview_render_policy_set(gl, ELM_GLVIEW_RENDER_POLICY_ALWAYS);
- elm_glview_render_func_set(gl, _draw_gl);
+ elm_glview_init_func_set(gl, _init_gl);
+ elm_glview_del_func_set(gl, _del_gl);
+ elm_glview_resize_func_set(gl, _resize_gl);
+ elm_glview_render_func_set(gl, (Elm_GLView_Func_Cb)_draw_gl);
elm_box_pack_end(bx, gl);
evas_object_show(gl);
- elm_object_focus(gl);
+ // Add Mouse/Key Event Callbacks
+ elm_object_focus_set(gl, EINA_TRUE);
evas_object_event_callback_add(gl, EVAS_CALLBACK_KEY_DOWN, _key_down, gl);
evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, gl);
evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_UP, _mouse_up, gl);
evas_object_event_callback_add(gl, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, gl);
+ // Animator and other vars
ani = ecore_animator_add(_anim, gl);
gld->glapi = elm_glview_gl_api_get(gl);
evas_object_data_set(gl, "ani", ani);
evas_object_data_set(gl, "gld", gld);
evas_object_event_callback_add(gl, EVAS_CALLBACK_DEL, _del, gl);
-
+
+ /* add an ok button */
bt = elm_button_add(win);
- elm_button_label_set(bt, "OK");
+ elm_object_text_set(bt, "OK");
evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
elm_box_pack_end(bx, bt);