diff options
Diffstat (limited to 'libraries/elementary/src/bin/test_glview_simple.c')
-rw-r--r-- | libraries/elementary/src/bin/test_glview_simple.c | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/libraries/elementary/src/bin/test_glview_simple.c b/libraries/elementary/src/bin/test_glview_simple.c new file mode 100644 index 0000000..fc21ef4 --- /dev/null +++ b/libraries/elementary/src/bin/test_glview_simple.c | |||
@@ -0,0 +1,286 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include "elementary_config.h" | ||
3 | #endif | ||
4 | #include <Elementary.h> | ||
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======\n%s\n======\n", info_log, shader_src ); | ||
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 | "#ifdef GL_ES \n" | ||
74 | "precision mediump float; \n" | ||
75 | "#endif \n" | ||
76 | "void main() \n" | ||
77 | "{ \n" | ||
78 | " gl_FragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 );\n" | ||
79 | "} \n"; | ||
80 | |||
81 | GLint linked; | ||
82 | |||
83 | // Load the vertex/fragment shaders | ||
84 | gld->vtx_shader = load_shader(gld, GL_VERTEX_SHADER, (const char*)vShaderStr); | ||
85 | gld->fgmt_shader = load_shader(gld, GL_FRAGMENT_SHADER, (const char*)fShaderStr); | ||
86 | |||
87 | // Create the program object | ||
88 | gld->program = gl->glCreateProgram( ); | ||
89 | if (gld->program==0) | ||
90 | return 0; | ||
91 | |||
92 | gl->glAttachShader(gld->program, gld->vtx_shader); | ||
93 | gl->glAttachShader(gld->program, gld->fgmt_shader); | ||
94 | |||
95 | gl->glBindAttribLocation(gld->program, 0, "vPosition"); | ||
96 | gl->glLinkProgram(gld->program); | ||
97 | gl->glGetProgramiv(gld->program, GL_LINK_STATUS, &linked); | ||
98 | |||
99 | if (!linked) | ||
100 | { | ||
101 | GLint info_len = 0; | ||
102 | gl->glGetProgramiv(gld->program, GL_INFO_LOG_LENGTH, &info_len); | ||
103 | if (info_len > 1) | ||
104 | { | ||
105 | char* info_log = malloc(sizeof(char) * info_len); | ||
106 | |||
107 | gl->glGetProgramInfoLog(gld->program, info_len, NULL, info_log); | ||
108 | printf("Error linking program:\n%s\n", info_log); | ||
109 | free(info_log); | ||
110 | } | ||
111 | gl->glDeleteProgram(gld->program); | ||
112 | return 0; | ||
113 | } | ||
114 | return 1; | ||
115 | } | ||
116 | |||
117 | |||
118 | |||
119 | // Callbacks | ||
120 | static void | ||
121 | _init_gl(Evas_Object *obj) | ||
122 | { | ||
123 | GLData *gld = evas_object_data_get(obj, "gld"); | ||
124 | Evas_GL_API *gl = gld->glapi; | ||
125 | GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f, | ||
126 | -0.5f, -0.5f, 0.0f, | ||
127 | 0.5f, -0.5f, 0.0f }; | ||
128 | |||
129 | if (!init_shaders(gld)) | ||
130 | { | ||
131 | printf("Error Initializing Shaders\n"); | ||
132 | return; | ||
133 | } | ||
134 | |||
135 | gl->glGenBuffers(1, &gld->vbo); | ||
136 | gl->glBindBuffer(GL_ARRAY_BUFFER, gld->vbo); | ||
137 | gl->glBufferData(GL_ARRAY_BUFFER, 3 * 3 * 4, vVertices, GL_STATIC_DRAW); | ||
138 | } | ||
139 | |||
140 | static void | ||
141 | _del_gl(Evas_Object *obj) | ||
142 | { | ||
143 | GLData *gld = evas_object_data_get(obj, "gld"); | ||
144 | if (!gld) | ||
145 | { | ||
146 | printf("Unable to get GLData. \n"); | ||
147 | return; | ||
148 | } | ||
149 | Evas_GL_API *gl = gld->glapi; | ||
150 | |||
151 | gl->glDeleteShader(gld->vtx_shader); | ||
152 | gl->glDeleteShader(gld->fgmt_shader); | ||
153 | gl->glDeleteProgram(gld->program); | ||
154 | gl->glDeleteBuffers(1, &gld->vbo); | ||
155 | |||
156 | evas_object_data_del((Evas_Object*)obj, "..gld"); | ||
157 | free(gld); | ||
158 | } | ||
159 | |||
160 | |||
161 | static void | ||
162 | _resize_gl(Evas_Object *obj) | ||
163 | { | ||
164 | int w, h; | ||
165 | GLData *gld = evas_object_data_get(obj, "gld"); | ||
166 | Evas_GL_API *gl = gld->glapi; | ||
167 | |||
168 | elm_glview_size_get(obj, &w, &h); | ||
169 | |||
170 | // GL Viewport stuff. you can avoid doing this if viewport is all the | ||
171 | // same as last frame if you want | ||
172 | gl->glViewport(0, 0, w, h); | ||
173 | } | ||
174 | |||
175 | |||
176 | |||
177 | static void | ||
178 | _draw_gl(Evas_Object *obj) | ||
179 | { | ||
180 | Evas_GL_API *gl = elm_glview_gl_api_get(obj); | ||
181 | GLData *gld = evas_object_data_get(obj, "gld"); | ||
182 | if (!gld) return; | ||
183 | int w, h; | ||
184 | |||
185 | elm_glview_size_get(obj, &w, &h); | ||
186 | |||
187 | gl->glViewport(0, 0, w, h); | ||
188 | gl->glClearColor(red,0.8,0.3,1); | ||
189 | gl->glClear(GL_COLOR_BUFFER_BIT); | ||
190 | |||
191 | // Draw a Triangle | ||
192 | gl->glEnable(GL_BLEND); | ||
193 | |||
194 | gl->glUseProgram(gld->program); | ||
195 | |||
196 | gl->glBindBuffer(GL_ARRAY_BUFFER, gld->vbo); | ||
197 | gl->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, | ||
198 | 0, 0); | ||
199 | gl->glEnableVertexAttribArray(0); | ||
200 | |||
201 | gl->glDrawArrays(GL_TRIANGLES, 0, 3); | ||
202 | |||
203 | // Optional - Flush the GL pipeline | ||
204 | gl->glFinish(); | ||
205 | |||
206 | red -= 0.1; | ||
207 | if (red < 0.0) red = 1.0; | ||
208 | } | ||
209 | |||
210 | static Eina_Bool | ||
211 | _anim(void *data) | ||
212 | { | ||
213 | elm_glview_changed_set(data); | ||
214 | return EINA_TRUE; | ||
215 | } | ||
216 | |||
217 | static void | ||
218 | _on_done(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
219 | { | ||
220 | evas_object_del((Evas_Object*)data); | ||
221 | } | ||
222 | |||
223 | |||
224 | static void | ||
225 | _del(void *data __UNUSED__, Evas *evas __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__) | ||
226 | { | ||
227 | Ecore_Animator *ani = evas_object_data_get(obj, "ani"); | ||
228 | ecore_animator_del(ani); | ||
229 | } | ||
230 | |||
231 | |||
232 | void | ||
233 | test_glview_simple(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) | ||
234 | { | ||
235 | Evas_Object *win, *bx, *bt, *gl; | ||
236 | Ecore_Animator *ani; | ||
237 | GLData *gld = NULL; | ||
238 | |||
239 | if (!(gld = calloc(1, sizeof(GLData)))) return; | ||
240 | |||
241 | // Set the engine to opengl_x11 | ||
242 | elm_config_preferred_engine_set("opengl_x11"); | ||
243 | win = elm_win_util_standard_add("glview simple", "GLView Simple"); | ||
244 | // Set preferred engine back to default from config | ||
245 | elm_config_preferred_engine_set(NULL); | ||
246 | |||
247 | elm_win_autodel_set(win, EINA_TRUE); | ||
248 | |||
249 | bx = elm_box_add(win); | ||
250 | evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); | ||
251 | elm_win_resize_object_add(win, bx); | ||
252 | evas_object_show(bx); | ||
253 | |||
254 | gl = elm_glview_add(win); | ||
255 | evas_object_size_hint_align_set(gl, EVAS_HINT_FILL, EVAS_HINT_FILL); | ||
256 | evas_object_size_hint_weight_set(gl, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); | ||
257 | elm_glview_mode_set(gl, ELM_GLVIEW_ALPHA | ELM_GLVIEW_DEPTH); | ||
258 | elm_glview_resize_policy_set(gl, ELM_GLVIEW_RESIZE_POLICY_RECREATE); | ||
259 | elm_glview_render_policy_set(gl, ELM_GLVIEW_RENDER_POLICY_ON_DEMAND); | ||
260 | elm_glview_init_func_set(gl, _init_gl); | ||
261 | elm_glview_del_func_set(gl, _del_gl); | ||
262 | elm_glview_resize_func_set(gl, _resize_gl); | ||
263 | elm_glview_render_func_set(gl, _draw_gl); | ||
264 | elm_box_pack_end(bx, gl); | ||
265 | evas_object_show(gl); | ||
266 | |||
267 | elm_object_focus_set(gl, EINA_TRUE); | ||
268 | |||
269 | ani = ecore_animator_add(_anim, gl); | ||
270 | gld->glapi = elm_glview_gl_api_get(gl); | ||
271 | evas_object_data_set(gl, "ani", ani); | ||
272 | evas_object_data_set(gl, "gld", gld); | ||
273 | evas_object_event_callback_add(gl, EVAS_CALLBACK_DEL, _del, gl); | ||
274 | |||
275 | bt = elm_button_add(win); | ||
276 | elm_object_text_set(bt, "OK"); | ||
277 | evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL); | ||
278 | evas_object_size_hint_weight_set(bt, EVAS_HINT_EXPAND, 0.0); | ||
279 | elm_box_pack_end(bx, bt); | ||
280 | evas_object_show(bt); | ||
281 | evas_object_smart_callback_add(bt, "clicked", _on_done, win); | ||
282 | |||
283 | evas_object_resize(win, 320, 480); | ||
284 | evas_object_show(win); | ||
285 | } | ||
286 | #endif | ||