2 * Tested interface: AtkObject
4 * Tested AtkObject: EailGlview
6 * Description: Test AtkObject interface
8 * Test input: accessible object representing EailGlview
10 * Expected test result: test should return 0 (success)
13 #include <Elementary.h>
18 #include "eail_test_utils.h"
20 INIT_TEST("EailGlview")
22 typedef struct _GLData GLData;
24 // GL related data here..
35 static float red = 1.0;
37 // a helper function to load shaders from a shader source
39 load_shader(GLData *gld, GLenum type, const char *shader_src)
41 Evas_GL_API *gl = gld->glapi;
45 // Create the shader object
46 shader = gl->glCreateShader(type);
50 // Load/Compile shader source
51 gl->glShaderSource(shader, 1, &shader_src, NULL);
52 gl->glCompileShader(shader);
53 gl->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
58 gl->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len);
61 char* info_log = malloc(sizeof(char) * info_len);
63 gl->glGetShaderInfoLog(shader, info_len, NULL, info_log);
64 _printf("Error compiling shader:\n%s\n======\n%s\n======\n", info_log, shader_src);
68 gl->glDeleteShader(shader);
75 // Initialize the shader and program object
77 init_shaders(GLData *gld)
79 Evas_GL_API *gl = gld->glapi;
81 "attribute vec4 vPosition; \n"
84 " gl_Position = vPosition; \n"
89 "precision mediump float; \n"
93 " gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n"
98 // Load the vertex/fragment shaders
99 gld->vtx_shader = load_shader(gld, GL_VERTEX_SHADER, (const char*)vShaderStr);
100 gld->fgmt_shader = load_shader(gld, GL_FRAGMENT_SHADER, (const char*)fShaderStr);
102 // Create the program object
103 gld->program = gl->glCreateProgram( );
104 if (0 == gld->program)
107 gl->glAttachShader(gld->program, gld->vtx_shader);
108 gl->glAttachShader(gld->program, gld->fgmt_shader);
110 gl->glBindAttribLocation(gld->program, 0, "vPosition");
111 gl->glLinkProgram(gld->program);
112 gl->glGetProgramiv(gld->program, GL_LINK_STATUS, &linked);
117 gl->glGetProgramiv(gld->program, GL_INFO_LOG_LENGTH, &info_len);
120 char* info_log = malloc(sizeof(char) * info_len);
122 gl->glGetProgramInfoLog(gld->program, info_len, NULL, info_log);
123 _printf("Error linking program:\n%s\n", info_log);
127 gl->glDeleteProgram(gld->program);
133 // intialize callback that gets called once for intialization
135 _init_gl(Evas_Object *obj)
137 GLData *gld = evas_object_data_get(obj, "gld");
138 Evas_GL_API *gl = gld->glapi;
139 GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f,
143 if (!init_shaders(gld))
145 _printf("Error Initializing Shaders\n");
149 gl->glGenBuffers(1, &gld->vbo);
150 gl->glBindBuffer(GL_ARRAY_BUFFER, gld->vbo);
151 gl->glBufferData(GL_ARRAY_BUFFER, 3 * 3 * 4, vVertices, GL_STATIC_DRAW);
154 // delete callback gets called when glview is deleted
156 _del_gl(Evas_Object *obj)
158 GLData *gld = evas_object_data_get(obj, "gld");
161 printf("Unable to get GLData. \n");
164 Evas_GL_API *gl = gld->glapi;
166 gl->glDeleteShader(gld->vtx_shader);
167 gl->glDeleteShader(gld->fgmt_shader);
168 gl->glDeleteProgram(gld->program);
169 gl->glDeleteBuffers(1, &gld->vbo);
171 evas_object_data_del((Evas_Object*)obj, "..gld");
175 // resize callback gets called every time object is resized
177 _resize_gl(Evas_Object *obj)
180 GLData *gld = evas_object_data_get(obj, "gld");
181 Evas_GL_API *gl = gld->glapi;
183 elm_glview_size_get(obj, &w, &h);
185 // GL Viewport stuff. you can avoid doing this if viewport is all the
186 // same as last frame if you want
187 gl->glViewport(0, 0, w, h);
191 // draw callback is where all the main GL rendering happens
193 _draw_gl(Evas_Object *obj)
195 Evas_GL_API *gl = elm_glview_gl_api_get(obj);
196 GLData *gld = evas_object_data_get(obj, "gld");
201 elm_glview_size_get(obj, &w, &h);
203 gl->glViewport(0, 0, w, h);
204 gl->glClearColor(red, 0.8, 0.3, 1);
205 gl->glClear(GL_COLOR_BUFFER_BIT);
208 gl->glEnable(GL_BLEND);
210 gl->glUseProgram(gld->program);
212 gl->glBindBuffer(GL_ARRAY_BUFFER, gld->vbo);
213 gl->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
214 gl->glEnableVertexAttribArray(0);
216 gl->glDrawArrays(GL_TRIANGLES, 0, 3);
218 // Optional - Flush the GL pipeline
222 if (0.0 > red) red = 1.0;
225 // just need to notify that glview has changed so it can render
229 elm_glview_changed_set(data);
234 _del(void *data, Evas *evas, Evas_Object *obj, void *event_info)
236 Ecore_Animator *ani = evas_object_data_get(obj, "ani");
237 ecore_animator_del(ani);
241 _init_glview(Evas_Object *win, GLData *gld)
243 Evas_Object *bg, *bx, *bt, *gl;
246 bg = elm_bg_add(win);
247 elm_win_resize_object_add(win, bg);
248 evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
249 evas_object_show(bg);
251 bx = elm_box_add(win);
252 evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
253 elm_win_resize_object_add(win, bx);
254 evas_object_show(bx);
256 //-//-//-// THIS IS WHERE GL INIT STUFF HAPPENS (ALA EGL)
258 // create a new glview object
259 gl = elm_glview_add(win);
260 gld->glapi = elm_glview_gl_api_get(gl);
261 evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
262 evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
263 // mode is simply for supporting alpha, depth buffering, and stencil
265 elm_glview_mode_set(gl, ELM_GLVIEW_ALPHA | ELM_GLVIEW_DEPTH);
266 // resize policy tells glview what to do with the surface when it
267 // resizes. ELM_GLVIEW_RESIZE_POLICY_RECREATE will tell it to
268 // destroy the current surface and recreate it to the new size
269 elm_glview_resize_policy_set(gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE);
270 // render policy tells glview how it would like glview to render
271 // gl code. ELM_GLVIEW_RENDER_POLICY_ON_DEMAND will have the gl
272 // calls called in the pixel_get callback, which only gets called
273 // if the object is visible, hence ON_DEMAND. ALWAYS mode renders
274 // it despite the visibility of the object.
275 elm_glview_render_policy_set(gl, ELM_GLVIEW_RENDER_POLICY_ON_DEMAND);
276 // initialize callback function gets registered here
277 elm_glview_init_func_set(gl, _init_gl);
278 // delete callback function gets registered here
279 elm_glview_del_func_set(gl, _del_gl);
280 elm_glview_resize_func_set(gl, _resize_gl);
281 elm_glview_render_func_set(gl, _draw_gl);
283 //-//-//-// END GL INIT BLOB
285 elm_box_pack_end(bx, gl);
286 evas_object_show(gl);
288 elm_object_focus_set(gl, EINA_TRUE);
290 // animating - just a demo. as long as you trigger an update on the image
291 // object via elm_glview_changed_set() it will be updated.
293 // NOTE: if you delete gl, this animator will keep running trying to access
294 // gl so you'd better delete this animator with ecore_animator_del().
295 ani = ecore_animator_add(_anim, gl);
297 evas_object_data_set(gl, "ani", ani);
298 evas_object_data_set(gl, "gld", gld);
299 evas_object_event_callback_add(gl, EVAS_CALLBACK_DEL, _del, gl);
301 // add an 'OK' button to end the program
302 bt = elm_button_add(win);
303 elm_object_text_set(bt, "OK");
304 evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
305 evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
306 elm_box_pack_end(bx, bt);
307 evas_object_show(bt);
308 evas_object_smart_callback_add(bt, "clicked", _on_done, win);
310 evas_object_resize(win, 320, 480);
314 _do_test(AtkObject *obj)
316 g_assert(ATK_IS_OBJECT(obj));
317 g_assert(atk_object_get_role(obj) == ATK_ROLE_ANIMATION);
318 atk_object_set_description(obj, "test");
319 g_assert_cmpstr(atk_object_get_description(obj), ==, "test");
321 atk_object_set_name(obj, "test name");
322 g_assert_cmpstr(atk_object_get_name(obj), ==, "test name");
324 eailu_test_code_called = 1;
328 elm_main(int argc, char **argv)
330 Evas_Object *win = NULL;
331 GLData *gld = calloc(1, sizeof(GLData));
335 // set the preferred engine to opengl_x11. if it isnt' available it
336 // may use another transparently
337 elm_config_preferred_engine_set("opengl_x11");
339 win = (Evas_Object *)eailu_create_test_window_with_glib_init(_on_done, _on_focus_in);
341 _init_glview(win, gld);
342 evas_object_show(win);