216ded5e5fc886322f013e1f2305b163828c8e80
[framework/uifw/elementary.git] / src / bin / test_glview_simple.c
1 #include <Elementary.h>
2 #ifdef HAVE_CONFIG_H
3 # include "elementary_config.h"
4 #endif
5 #ifndef ELM_LIB_QUICKLAUNCH
6
7 typedef struct _GLData GLData;
8
9 // GL related data here..
10 struct _GLData
11 {
12    Evas_GL_API *glapi;
13    GLuint       program;
14    GLuint       vtx_shader;
15    GLuint       fgmt_shader;
16    GLuint       vbo;
17    int          initialized : 1;
18 };
19
20
21 static float red = 1.0;
22
23 //--------------------------------//
24 static GLuint
25 load_shader( GLData *gld, GLenum type, const char *shader_src )
26 {
27    Evas_GL_API *gl = gld->glapi;
28    GLuint shader;
29    GLint compiled;
30
31    // Create the shader object
32    shader = gl->glCreateShader(type);
33    if (shader==0)
34       return 0;
35
36    // Load/Compile shader source
37    gl->glShaderSource(shader, 1, &shader_src, NULL);
38    gl->glCompileShader(shader);
39    gl->glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
40
41    if (!compiled)
42      {
43         GLint info_len = 0;
44         gl->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len);
45         if (info_len > 1)
46           {
47              char* info_log = malloc(sizeof(char) * info_len);
48
49              gl->glGetShaderInfoLog(shader, info_len, NULL, info_log);
50              printf("Error compiling shader:\n%s\n", info_log );
51              free(info_log);
52           }
53         gl->glDeleteShader(shader);
54         return 0;
55      }
56
57    return shader;
58 }
59
60 // Initialize the shader and program object
61 static int
62 init_shaders(GLData *gld)
63 {
64    Evas_GL_API *gl = gld->glapi;
65    GLbyte vShaderStr[] =
66       "attribute vec4 vPosition;    \n"
67       "void main()                  \n"
68       "{                            \n"
69       "   gl_Position = vPosition;  \n"
70       "}                            \n";
71
72    GLbyte fShaderStr[] =
73       "precision mediump float;\n"\
74       "void main()                                  \n"
75       "{                                            \n"
76       "  gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n"
77       "}                                            \n";
78
79    GLint linked;
80
81    // Load the vertex/fragment shaders
82    gld->vtx_shader  = load_shader(gld, GL_VERTEX_SHADER, (const char*)vShaderStr);
83    gld->fgmt_shader = load_shader(gld, GL_FRAGMENT_SHADER, (const char*)fShaderStr);
84
85    // Create the program object
86    gld->program = gl->glCreateProgram( );
87    if (gld->program==0)
88       return 0;
89
90    gl->glAttachShader(gld->program, gld->vtx_shader);
91    gl->glAttachShader(gld->program, gld->fgmt_shader);
92
93    gl->glBindAttribLocation(gld->program, 0, "vPosition");
94    gl->glLinkProgram(gld->program);
95    gl->glGetProgramiv(gld->program, GL_LINK_STATUS, &linked);
96
97    if (!linked)
98      {
99         GLint info_len = 0;
100         gl->glGetProgramiv(gld->program, GL_INFO_LOG_LENGTH, &info_len);
101         if (info_len > 1)
102           {
103              char* info_log = malloc(sizeof(char) * info_len);
104
105              gl->glGetProgramInfoLog(gld->program, info_len, NULL, info_log);
106              printf("Error linking program:\n%s\n", info_log);
107              free(info_log);
108           }
109         gl->glDeleteProgram(gld->program);
110         return 0;
111      }
112    return 1;
113 }
114
115
116
117 // Callbacks
118 static void
119 _init_gl(Evas_Object *obj)
120 {
121    GLData *gld = evas_object_data_get(obj, "gld");
122    Evas_GL_API *gl = gld->glapi;
123    GLfloat vVertices[] = {  0.0f,  0.5f, 0.0f,
124                            -0.5f, -0.5f, 0.0f,
125                             0.5f, -0.5f, 0.0f };
126
127    if (!init_shaders(gld))
128      {
129         printf("Error Initializing Shaders\n");
130         return;
131      }
132
133    gl->glGenBuffers(1, &gld->vbo);
134    gl->glBindBuffer(GL_ARRAY_BUFFER, gld->vbo);
135    gl->glBufferData(GL_ARRAY_BUFFER, 3 * 3 * 4, vVertices, GL_STATIC_DRAW);
136 }
137
138 static void
139 _del_gl(Evas_Object *obj)
140 {
141    GLData *gld = evas_object_data_get(obj, "gld");
142    if (!gld)
143      {
144         printf("Unable to get GLData. \n");
145         return;
146      }
147    Evas_GL_API *gl = gld->glapi;
148
149    gl->glDeleteShader(gld->vtx_shader);
150    gl->glDeleteShader(gld->fgmt_shader);
151    gl->glDeleteProgram(gld->program);
152    gl->glDeleteBuffers(1, &gld->vbo);
153
154    evas_object_data_del((Evas_Object*)obj, "..gld");
155    free(gld);
156 }
157
158
159 static void
160 _resize_gl(Evas_Object *obj)
161 {
162    int w, h;
163    GLData *gld = evas_object_data_get(obj, "gld");
164    Evas_GL_API *gl = gld->glapi;
165
166    elm_glview_size_get(obj, &w, &h);
167
168    // GL Viewport stuff. you can avoid doing this if viewport is all the
169    // same as last frame if you want
170    gl->glViewport(0, 0, w, h);
171 }
172
173
174
175 static void
176 _draw_gl(Evas_Object *obj)
177 {
178    Evas_GL_API *gl = elm_glview_gl_api_get(obj);
179    GLData *gld = evas_object_data_get(obj, "gld");
180    if (!gld) return;
181    int w, h;
182
183    elm_glview_size_get(obj, &w, &h);
184
185    gl->glViewport(0, 0, w, h);
186    gl->glClearColor(red,0.8,0.3,1);
187    gl->glClear(GL_COLOR_BUFFER_BIT);
188
189    // Draw a Triangle
190    gl->glEnable(GL_BLEND);
191
192    gl->glUseProgram(gld->program);
193
194    gl->glBindBuffer(GL_ARRAY_BUFFER, gld->vbo);
195    gl->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
196                              0, 0);
197    gl->glEnableVertexAttribArray(0);
198
199    gl->glDrawArrays(GL_TRIANGLES, 0, 3);
200
201    // Optional - Flush the GL pipeline
202    gl->glFinish();
203
204    red -= 0.1;
205    if (red < 0.0) red = 1.0;
206 }
207
208 static Eina_Bool
209 _anim(void *data)
210 {
211    elm_glview_changed_set(data);
212    return EINA_TRUE;
213 }
214
215 static void
216 _on_done(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
217 {
218    evas_object_del((Evas_Object*)data);
219 }
220
221
222 static void
223 _del(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
224 {
225    Ecore_Animator *ani = evas_object_data_get(obj, "ani");
226    ecore_animator_del(ani);
227 }
228
229
230 void
231 test_glview_simple(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
232 {
233    Evas_Object *win, *bg, *bx, *bt, *gl;
234    Ecore_Animator *ani;
235    GLData *gld = NULL;
236
237    if (!(gld = calloc(1, sizeof(GLData)))) return;
238
239    // Set the engine to opengl_x11
240    elm_engine_set("opengl_x11");
241
242    win = elm_win_add(NULL, "glview simple", ELM_WIN_BASIC);
243    elm_win_title_set(win, "GLView Simple");
244    elm_win_autodel_set(win, 1);
245
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);
250
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);
255
256    gl = elm_glview_add(win);
257    evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL);
258    evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
259    elm_glview_mode_set(gl, ELM_GLVIEW_ALPHA | ELM_GLVIEW_DEPTH);
260    elm_glview_resize_policy_set(gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE);
261    elm_glview_render_policy_set(gl, ELM_GLVIEW_RENDER_POLICY_ON_DEMAND);
262    elm_glview_init_func_set(gl, _init_gl);
263    elm_glview_del_func_set(gl, _del_gl);
264    elm_glview_resize_func_set(gl, _resize_gl);
265    elm_glview_render_func_set(gl, _draw_gl);
266    elm_box_pack_end(bx, gl);
267    evas_object_show(gl);
268
269    elm_object_focus(gl);
270
271    ani = ecore_animator_add(_anim, gl);
272    gld->glapi = elm_glview_gl_api_get(gl);
273    evas_object_data_set(gl, "ani", ani);
274    evas_object_data_set(gl, "gld", gld);
275    evas_object_event_callback_add(gl, EVAS_CALLBACK_DEL, _del, gl);
276
277    bt = elm_button_add(win);
278    elm_object_text_set(bt, "OK");
279    evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
280    evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0);
281    elm_box_pack_end(bx, bt);
282    evas_object_show(bt);
283    evas_object_smart_callback_add(bt, "clicked", _on_done, win);
284
285    evas_object_resize(win, 320, 480);
286    evas_object_show(win);
287 }
288 #endif