Merge lp:~vanvugt/mir/egldemo into lp:~mir-team/mir/trunk
- egldemo
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~vanvugt/mir/egldemo |
Merge into: | lp:~mir-team/mir/trunk |
Diff against target: |
653 lines (+598/-9) 7 files modified
debian/libmirclient-demos.install (+3/-0) examples/CMakeLists.txt (+38/-9) examples/eglapp.c (+177/-0) examples/eglapp.h (+37/-0) examples/eglflash.c (+58/-0) examples/eglplasma.c (+149/-0) examples/egltriangle.c (+136/-0) |
To merge this branch: | bzr merge lp:~vanvugt/mir/egldemo |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Alan Griffiths | Needs Fixing | ||
Alexandros Frantzis (community) | Needs Fixing | ||
Review via email: mp+152356@code.launchpad.net |
This proposal has been superseded by a proposal from 2013-03-12.
Commit message
Add some pretty (simple) demo GL client apps for Mir.
Everybody loves plasma!
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
Alexandros Frantzis (afrantzis) wrote : | # |
109 +static EGLBoolean running = EGL_FALSE;
Although it probably won't be a problem in practice, we should be using the standard "volatile sig_atomic_t" for the running variable.
Other than that looks good, and the plasma is quite hypnotic :)
Alan Griffiths (alan-griffiths) wrote : | # |
> 109 +static EGLBoolean running = EGL_FALSE;
>
> Although it probably won't be a problem in practice, we should be using the
> standard "volatile sig_atomic_t" for the running variable.
>
> Other than that looks good, and the plasma is quite hypnotic :)
+1
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:471
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild:
http://
Daniel van Vugt (vanvugt) wrote : | # |
Hmm, yes I guess it's theoretically possible that EGLBoolean could be typedef'd to some large type that is non-atomic at the instruction level. Changed to sig_atomic_t.
Although in reality, I doubt any platform will ever have a non-atomic 'int' that doesn't map directly to the CPU word size.
Preview Diff
1 | === modified file 'debian/libmirclient-demos.install' |
2 | --- debian/libmirclient-demos.install 2013-01-28 21:11:08 +0000 |
3 | +++ debian/libmirclient-demos.install 2013-03-12 04:02:23 +0000 |
4 | @@ -1,3 +1,6 @@ |
5 | usr/bin/mir_demo_client |
6 | usr/bin/mir_demo_client_unaccelerated |
7 | usr/bin/mir_demo_client_accelerated |
8 | +usr/bin/mir_eglflash |
9 | +usr/bin/mir_egltriangle |
10 | +usr/bin/mir_eglplasma |
11 | |
12 | === modified file 'examples/CMakeLists.txt' |
13 | --- examples/CMakeLists.txt 2013-03-06 12:25:34 +0000 |
14 | +++ examples/CMakeLists.txt 2013-03-12 04:02:23 +0000 |
15 | @@ -1,5 +1,32 @@ |
16 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -fno-strict-aliasing -Wextra") |
17 | |
18 | +add_library(eglapp STATIC |
19 | + eglapp.c |
20 | +) |
21 | +target_link_libraries(eglapp |
22 | + mirclient |
23 | + ${EGL_LIBRARIES} |
24 | + ${GLESv2_LIBRARIES} |
25 | +) |
26 | +add_executable(mir_eglflash |
27 | + eglflash.c |
28 | +) |
29 | +target_link_libraries(mir_eglflash |
30 | + eglapp |
31 | +) |
32 | +add_executable(mir_egltriangle |
33 | + egltriangle.c |
34 | +) |
35 | +target_link_libraries(mir_egltriangle |
36 | + eglapp |
37 | +) |
38 | +add_executable(mir_eglplasma |
39 | + eglplasma.c |
40 | +) |
41 | +target_link_libraries(mir_eglplasma |
42 | + eglapp |
43 | +) |
44 | + |
45 | add_executable( |
46 | mir_demo_client |
47 | |
48 | @@ -85,12 +112,14 @@ |
49 | target_link_libraries(mir_demo_client_unaccelerated binder) |
50 | endif() |
51 | |
52 | -install( |
53 | - TARGETS mir_demo_client |
54 | - RUNTIME DESTINATION bin) |
55 | -install( |
56 | - TARGETS mir_demo_client_unaccelerated |
57 | - RUNTIME DESTINATION bin) |
58 | -install( |
59 | - TARGETS mir_demo_client_accelerated |
60 | - RUNTIME DESTINATION bin) |
61 | +set (DEMO_CLIENTS |
62 | + mir_demo_client |
63 | + mir_demo_client_unaccelerated |
64 | + mir_demo_client_accelerated |
65 | + mir_eglflash |
66 | + mir_egltriangle |
67 | + mir_eglplasma |
68 | +) |
69 | + |
70 | +install(TARGETS ${DEMO_CLIENTS} RUNTIME DESTINATION bin) |
71 | + |
72 | |
73 | === added file 'examples/eglapp.c' |
74 | --- examples/eglapp.c 1970-01-01 00:00:00 +0000 |
75 | +++ examples/eglapp.c 2013-03-12 04:02:23 +0000 |
76 | @@ -0,0 +1,177 @@ |
77 | +/* |
78 | + * Copyright © 2013 Canonical Ltd. |
79 | + * |
80 | + * This program is free software: you can redistribute it and/or modify |
81 | + * it under the terms of the GNU General Public License version 3 as |
82 | + * published by the Free Software Foundation. |
83 | + * |
84 | + * This program is distributed in the hope that it will be useful, |
85 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
86 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
87 | + * GNU General Public License for more details. |
88 | + * |
89 | + * You should have received a copy of the GNU General Public License |
90 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
91 | + * |
92 | + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> |
93 | + */ |
94 | + |
95 | +#include "eglapp.h" |
96 | +#include "mir_toolkit/mir_client_library.h" |
97 | +#include <stdio.h> |
98 | +#include <stdlib.h> |
99 | +#include <signal.h> |
100 | +#include <time.h> |
101 | +#include <EGL/egl.h> |
102 | + |
103 | +static const char servername[] = "/tmp/mir_socket"; |
104 | +static const char appname[] = "egldemo"; |
105 | + |
106 | +static MirConnection *connection; |
107 | +static EGLDisplay egldisplay; |
108 | +static EGLSurface eglsurface; |
109 | +static volatile sig_atomic_t running = 0; |
110 | + |
111 | +#define CHECK(_cond, _err) \ |
112 | + if (!(_cond)) \ |
113 | + { \ |
114 | + printf("%s\n", (_err)); \ |
115 | + return 0; \ |
116 | + } |
117 | + |
118 | +static void assign_result(void *result, void **arg) |
119 | +{ |
120 | + *arg = result; |
121 | +} |
122 | + |
123 | +void mir_eglapp_shutdown(void) |
124 | +{ |
125 | + eglTerminate(egldisplay); |
126 | + mir_connection_release(connection); |
127 | + connection = NULL; |
128 | +} |
129 | + |
130 | +static void shutdown(int signum) |
131 | +{ |
132 | + if (running) |
133 | + { |
134 | + running = 0; |
135 | + printf("Signal %d received. Good night.\n", signum); |
136 | + } |
137 | +} |
138 | + |
139 | +mir_eglapp_bool mir_eglapp_running(void) |
140 | +{ |
141 | + return running; |
142 | +} |
143 | + |
144 | +void mir_eglapp_swap_buffers(void) |
145 | +{ |
146 | + static time_t lasttime = 0; |
147 | + static int lastcount = 0; |
148 | + static int count = 0; |
149 | + time_t now = time(NULL); |
150 | + time_t dtime; |
151 | + int dcount; |
152 | + |
153 | + if (!running) |
154 | + return; |
155 | + |
156 | + eglSwapBuffers(egldisplay, eglsurface); |
157 | + |
158 | + count++; |
159 | + dcount = count - lastcount; |
160 | + dtime = now - lasttime; |
161 | + if (dtime) |
162 | + { |
163 | + printf("%d FPS\n", dcount); |
164 | + lasttime = now; |
165 | + lastcount = count; |
166 | + } |
167 | +} |
168 | + |
169 | +mir_eglapp_bool mir_eglapp_init(int *width, int *height) |
170 | +{ |
171 | + EGLint attribs[] = |
172 | + { |
173 | + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
174 | + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
175 | + EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, |
176 | + EGL_NONE |
177 | + }; |
178 | + EGLint ctxattribs[] = |
179 | + { |
180 | + EGL_CONTEXT_CLIENT_VERSION, 2, |
181 | + EGL_NONE |
182 | + }; |
183 | + MirSurfaceParameters surfaceparm = |
184 | + { |
185 | + "eglappsurface", |
186 | + 256, 256, |
187 | + mir_pixel_format_xbgr_8888, |
188 | + mir_buffer_usage_hardware |
189 | + }; |
190 | + MirDisplayInfo dinfo; |
191 | + MirSurface *surface; |
192 | + EGLConfig eglconfig; |
193 | + EGLint neglconfigs; |
194 | + EGLContext eglctx; |
195 | + EGLBoolean ok; |
196 | + |
197 | + mir_wait_for(mir_connect(servername, appname, |
198 | + (mir_connected_callback)assign_result, |
199 | + &connection)); |
200 | + CHECK(mir_connection_is_valid(connection), "Can't get connection"); |
201 | + |
202 | + mir_connection_get_display_info(connection, &dinfo); |
203 | + |
204 | + printf("Connected to display %s: %dx%d, supports %d pixel formats\n", |
205 | + servername, dinfo.width, dinfo.height, |
206 | + dinfo.supported_pixel_format_items); |
207 | + |
208 | + surfaceparm.width = *width > 0 ? *width : dinfo.width; |
209 | + surfaceparm.height = *height > 0 ? *height : dinfo.height; |
210 | + surfaceparm.pixel_format = dinfo.supported_pixel_format[0]; |
211 | + printf("Using pixel format #%d\n", surfaceparm.pixel_format); |
212 | + |
213 | + mir_wait_for(mir_surface_create(connection, &surfaceparm, |
214 | + (mir_surface_lifecycle_callback)assign_result, |
215 | + &surface)); |
216 | + CHECK(mir_surface_is_valid(surface), "Can't create a surface"); |
217 | + |
218 | + egldisplay = eglGetDisplay( |
219 | + mir_connection_get_egl_native_display(connection)); |
220 | + CHECK(egldisplay != EGL_NO_DISPLAY, "Can't eglGetDisplay"); |
221 | + |
222 | + ok = eglInitialize(egldisplay, NULL, NULL); |
223 | + CHECK(ok, "Can't eglInitialize"); |
224 | + |
225 | + ok = eglChooseConfig(egldisplay, attribs, &eglconfig, 1, &neglconfigs); |
226 | + CHECK(ok, "Could not eglChooseConfig"); |
227 | + CHECK(neglconfigs > 0, "No EGL config available"); |
228 | + |
229 | + eglsurface = eglCreateWindowSurface(egldisplay, eglconfig, |
230 | + (EGLNativeWindowType)mir_surface_get_egl_native_window(surface), |
231 | + NULL); |
232 | + CHECK(eglsurface != EGL_NO_SURFACE, "eglCreateWindowSurface failed"); |
233 | + |
234 | + eglctx = eglCreateContext(egldisplay, eglconfig, EGL_NO_CONTEXT, |
235 | + ctxattribs); |
236 | + CHECK(eglctx != EGL_NO_CONTEXT, "eglCreateContext failed"); |
237 | + |
238 | + ok = eglMakeCurrent(egldisplay, eglsurface, eglsurface, eglctx); |
239 | + CHECK(ok, "Can't eglMakeCurrent"); |
240 | + |
241 | + signal(SIGINT, shutdown); |
242 | + signal(SIGTERM, shutdown); |
243 | + |
244 | + *width = surfaceparm.width; |
245 | + *height = surfaceparm.height; |
246 | + |
247 | + eglSwapInterval(egldisplay, 1); |
248 | + |
249 | + running = 1; |
250 | + |
251 | + return 1; |
252 | +} |
253 | + |
254 | |
255 | === added file 'examples/eglapp.h' |
256 | --- examples/eglapp.h 1970-01-01 00:00:00 +0000 |
257 | +++ examples/eglapp.h 2013-03-12 04:02:23 +0000 |
258 | @@ -0,0 +1,37 @@ |
259 | +/* |
260 | + * Copyright © 2013 Canonical Ltd. |
261 | + * |
262 | + * This program is free software: you can redistribute it and/or modify |
263 | + * it under the terms of the GNU General Public License version 3 as |
264 | + * published by the Free Software Foundation. |
265 | + * |
266 | + * This program is distributed in the hope that it will be useful, |
267 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
268 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
269 | + * GNU General Public License for more details. |
270 | + * |
271 | + * You should have received a copy of the GNU General Public License |
272 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
273 | + * |
274 | + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> |
275 | + */ |
276 | + |
277 | +#ifndef __EGLAPP_H__ |
278 | +#define __EGLAPP_H__ |
279 | + |
280 | +#ifdef __cplusplus |
281 | +extern "C" { |
282 | +#endif |
283 | + |
284 | +typedef int mir_eglapp_bool; |
285 | + |
286 | +mir_eglapp_bool mir_eglapp_init(int *width, int *height); |
287 | +void mir_eglapp_swap_buffers(void); |
288 | +mir_eglapp_bool mir_eglapp_running(void); |
289 | +void mir_eglapp_shutdown(void); |
290 | + |
291 | +#ifdef __cplusplus |
292 | +} |
293 | +#endif |
294 | + |
295 | +#endif |
296 | |
297 | === added file 'examples/eglflash.c' |
298 | --- examples/eglflash.c 1970-01-01 00:00:00 +0000 |
299 | +++ examples/eglflash.c 2013-03-12 04:02:23 +0000 |
300 | @@ -0,0 +1,58 @@ |
301 | +/* |
302 | + * Trivial GL demo; flashes the screen. Showing how simple life is with eglapp. |
303 | + * |
304 | + * Copyright © 2013 Canonical Ltd. |
305 | + * |
306 | + * This program is free software: you can redistribute it and/or modify |
307 | + * it under the terms of the GNU General Public License version 3 as |
308 | + * published by the Free Software Foundation. |
309 | + * |
310 | + * This program is distributed in the hope that it will be useful, |
311 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
312 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
313 | + * GNU General Public License for more details. |
314 | + * |
315 | + * You should have received a copy of the GNU General Public License |
316 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
317 | + * |
318 | + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> |
319 | + */ |
320 | + |
321 | +#include "eglapp.h" |
322 | +#include <stdio.h> |
323 | +#include <unistd.h> |
324 | +#include <GLES2/gl2.h> |
325 | + |
326 | +int main(void) |
327 | +{ |
328 | + int width = 0, height = 0; /* Use the full display */ |
329 | + |
330 | + if (!mir_eglapp_init(&width, &height)) |
331 | + { |
332 | + printf("Can't initialize EGL\n"); |
333 | + return 1; |
334 | + } |
335 | + |
336 | + /* This is probably the simplest GL you can do */ |
337 | + while (mir_eglapp_running()) |
338 | + { |
339 | + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); |
340 | + glClear(GL_COLOR_BUFFER_BIT); |
341 | + mir_eglapp_swap_buffers(); |
342 | + sleep(1); |
343 | + |
344 | + glClearColor(0.0f, 1.0f, 0.0f, 1.0f); |
345 | + glClear(GL_COLOR_BUFFER_BIT); |
346 | + mir_eglapp_swap_buffers(); |
347 | + sleep(1); |
348 | + |
349 | + glClearColor(0.0f, 0.0f, 1.0f, 1.0f); |
350 | + glClear(GL_COLOR_BUFFER_BIT); |
351 | + mir_eglapp_swap_buffers(); |
352 | + sleep(1); |
353 | + } |
354 | + |
355 | + mir_eglapp_shutdown(); |
356 | + |
357 | + return 0; |
358 | +} |
359 | |
360 | === added file 'examples/eglplasma.c' |
361 | --- examples/eglplasma.c 1970-01-01 00:00:00 +0000 |
362 | +++ examples/eglplasma.c 2013-03-12 04:02:23 +0000 |
363 | @@ -0,0 +1,149 @@ |
364 | +/* |
365 | + * Copyright © 2013 Canonical Ltd. |
366 | + * |
367 | + * This program is free software: you can redistribute it and/or modify |
368 | + * it under the terms of the GNU General Public License version 3 as |
369 | + * published by the Free Software Foundation. |
370 | + * |
371 | + * This program is distributed in the hope that it will be useful, |
372 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
373 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
374 | + * GNU General Public License for more details. |
375 | + * |
376 | + * You should have received a copy of the GNU General Public License |
377 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
378 | + * |
379 | + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> |
380 | + */ |
381 | + |
382 | +#include "eglapp.h" |
383 | +#include <assert.h> |
384 | +#include <stdio.h> |
385 | +#include <GLES2/gl2.h> |
386 | + |
387 | +static GLuint load_shader(const char *src, GLenum type) |
388 | +{ |
389 | + GLuint shader = glCreateShader(type); |
390 | + if (shader) |
391 | + { |
392 | + GLint compiled; |
393 | + glShaderSource(shader, 1, &src, NULL); |
394 | + glCompileShader(shader); |
395 | + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); |
396 | + if (!compiled) |
397 | + { |
398 | + GLchar log[1024]; |
399 | + glGetShaderInfoLog(shader, sizeof log - 1, NULL, log); |
400 | + log[sizeof log - 1] = '\0'; |
401 | + printf("load_shader compile failed: %s\n", log); |
402 | + glDeleteShader(shader); |
403 | + shader = 0; |
404 | + } |
405 | + } |
406 | + return shader; |
407 | +} |
408 | + |
409 | +/* Colours from http://design.ubuntu.com/brand/colour-palette */ |
410 | +#define DARK_AUBERGINE 0.17254902f, 0.0f, 0.117647059f |
411 | +#define MID_AUBERGINE 0.368627451f, 0.152941176f, 0.31372549f |
412 | +#define ORANGE 0.866666667f, 0.282352941f, 0.141414141f |
413 | + |
414 | +int main(void) |
415 | +{ |
416 | + const char vshadersrc[] = |
417 | + "attribute vec4 vPosition; \n" |
418 | + "varying vec2 texcoord; \n" |
419 | + "void main() \n" |
420 | + "{ \n" |
421 | + " gl_Position = vPosition; \n" |
422 | + " texcoord = vec2(vPosition) * vec2(0.5) + vec2(0.5); \n" |
423 | + "} \n"; |
424 | + |
425 | + const char fshadersrc[] = |
426 | + "precision mediump float; \n" |
427 | + "uniform float theta; \n" |
428 | + "varying vec2 texcoord; \n" |
429 | + "uniform vec4 low_color, high_color; \n" |
430 | + "void main() \n" |
431 | + "{ \n" |
432 | + " const float pi2 = 6.283185308; \n" |
433 | + " float u = texcoord.x * pi2; \n" |
434 | + " float v = texcoord.y * pi2; \n" |
435 | + " float t = mod(theta, pi2); \n" |
436 | + " float us = (cos(1.1 * u + 7.0 * t) + \n" |
437 | + " cos(2.3 * v * cos(1.0 * t)) + \n" |
438 | + " cos(0.3 * u * cos(3.0 * t)) \n" |
439 | + " ) / 3.0; \n" |
440 | + " float vs = (cos(2.3 * v + 8.0 * t) + \n" |
441 | + " cos(1.3 * u * cos(3.0 * t)) + \n" |
442 | + " cos(1.7 * v * cos(2.0 * t)) \n" |
443 | + " ) / 3.0; \n" |
444 | + " float x = (us * vs + 1.0) / 2.0; \n" |
445 | + " gl_FragColor = x * (high_color - low_color) + \n" |
446 | + " low_color; \n" |
447 | + "} \n"; |
448 | + |
449 | + const GLfloat vertices[] = |
450 | + { |
451 | + -1.0f, 1.0f, |
452 | + 1.0f, 1.0f, |
453 | + 1.0f,-1.0f, |
454 | + -1.0f,-1.0f, |
455 | + }; |
456 | + GLuint vshader, fshader, prog; |
457 | + GLint linked, low_color, high_color, vpos, theta; |
458 | + int width = 0, height = 0; |
459 | + GLfloat angle = 0.0f; |
460 | + |
461 | + if (!mir_eglapp_init(&width, &height)) |
462 | + { |
463 | + printf("Can't initialize EGL\n"); |
464 | + return 1; |
465 | + } |
466 | + |
467 | + vshader = load_shader(vshadersrc, GL_VERTEX_SHADER); |
468 | + assert(vshader); |
469 | + fshader = load_shader(fshadersrc, GL_FRAGMENT_SHADER); |
470 | + assert(fshader); |
471 | + prog = glCreateProgram(); |
472 | + assert(prog); |
473 | + glAttachShader(prog, vshader); |
474 | + glAttachShader(prog, fshader); |
475 | + glLinkProgram(prog); |
476 | + |
477 | + glGetProgramiv(prog, GL_LINK_STATUS, &linked); |
478 | + if (!linked) |
479 | + { |
480 | + GLchar log[1024]; |
481 | + glGetProgramInfoLog(prog, sizeof log - 1, NULL, log); |
482 | + log[sizeof log - 1] = '\0'; |
483 | + printf("Link failed: %s\n", log); |
484 | + return 2; |
485 | + } |
486 | + |
487 | + glViewport(0, 0, width, height); |
488 | + |
489 | + glUseProgram(prog); |
490 | + |
491 | + vpos = glGetAttribLocation(prog, "vPosition"); |
492 | + low_color = glGetUniformLocation(prog, "low_color"); |
493 | + high_color = glGetUniformLocation(prog, "high_color"); |
494 | + theta = glGetUniformLocation(prog, "theta"); |
495 | + glUniform4f(low_color, DARK_AUBERGINE, 1.0f); |
496 | + glUniform4f(high_color, ORANGE, 1.0f); |
497 | + |
498 | + glVertexAttribPointer(vpos, 2, GL_FLOAT, GL_FALSE, 0, vertices); |
499 | + glEnableVertexAttribArray(0); |
500 | + |
501 | + while (mir_eglapp_running()) |
502 | + { |
503 | + glUniform1f(theta, angle); |
504 | + angle += 0.005f; |
505 | + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); |
506 | + mir_eglapp_swap_buffers(); |
507 | + } |
508 | + |
509 | + mir_eglapp_shutdown(); |
510 | + |
511 | + return 0; |
512 | +} |
513 | |
514 | === added file 'examples/egltriangle.c' |
515 | --- examples/egltriangle.c 1970-01-01 00:00:00 +0000 |
516 | +++ examples/egltriangle.c 2013-03-12 04:02:23 +0000 |
517 | @@ -0,0 +1,136 @@ |
518 | +/* |
519 | + * Copyright © 2013 Canonical Ltd. |
520 | + * |
521 | + * This program is free software: you can redistribute it and/or modify |
522 | + * it under the terms of the GNU General Public License version 3 as |
523 | + * published by the Free Software Foundation. |
524 | + * |
525 | + * This program is distributed in the hope that it will be useful, |
526 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
527 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
528 | + * GNU General Public License for more details. |
529 | + * |
530 | + * You should have received a copy of the GNU General Public License |
531 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
532 | + * |
533 | + * Author: Daniel van Vugt <daniel.van.vugt@canonical.com> |
534 | + */ |
535 | + |
536 | +#include "eglapp.h" |
537 | +#include <assert.h> |
538 | +#include <stdio.h> |
539 | +#include <GLES2/gl2.h> |
540 | + |
541 | +static GLuint load_shader(const char *src, GLenum type) |
542 | +{ |
543 | + GLuint shader = glCreateShader(type); |
544 | + if (shader) |
545 | + { |
546 | + GLint compiled; |
547 | + glShaderSource(shader, 1, &src, NULL); |
548 | + glCompileShader(shader); |
549 | + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); |
550 | + if (!compiled) |
551 | + { |
552 | + GLchar log[1024]; |
553 | + glGetShaderInfoLog(shader, sizeof log - 1, NULL, log); |
554 | + log[sizeof log - 1] = '\0'; |
555 | + printf("load_shader compile failed: %s\n", log); |
556 | + glDeleteShader(shader); |
557 | + shader = 0; |
558 | + } |
559 | + } |
560 | + return shader; |
561 | +} |
562 | + |
563 | +/* Colours from http://design.ubuntu.com/brand/colour-palette */ |
564 | +#define MID_AUBERGINE 0.368627451f, 0.152941176f, 0.31372549f |
565 | +#define ORANGE 0.866666667f, 0.282352941f, 0.141414141f |
566 | + |
567 | +int main(void) |
568 | +{ |
569 | + const char vshadersrc[] = |
570 | + "attribute vec4 vPosition; \n" |
571 | + "uniform float theta; \n" |
572 | + "void main() \n" |
573 | + "{ \n" |
574 | + " float c = cos(theta); \n" |
575 | + " float s = sin(theta); \n" |
576 | + " mat2 m; \n" |
577 | + " m[0] = vec2(c, s); \n" |
578 | + " m[1] = vec2(-s, c); \n" |
579 | + " vec2 p = m * vec2(vPosition); \n" |
580 | + " gl_Position = vec4(p, 0.0, 1.0); \n" |
581 | + "} \n"; |
582 | + |
583 | + const char fshadersrc[] = |
584 | + "precision mediump float; \n" |
585 | + "uniform vec4 col; \n" |
586 | + "void main() \n" |
587 | + "{ \n" |
588 | + " gl_FragColor = col; \n" |
589 | + "} \n"; |
590 | + |
591 | + const GLfloat vertices[] = |
592 | + { |
593 | + 0.0f, 1.0f, |
594 | + -1.0f,-0.866f, |
595 | + 1.0f,-0.866f, |
596 | + }; |
597 | + GLuint vshader, fshader, prog; |
598 | + GLint linked, col, vpos, theta; |
599 | + int width = 512, height = 512; |
600 | + GLfloat angle = 0.0f; |
601 | + |
602 | + if (!mir_eglapp_init(&width, &height)) |
603 | + { |
604 | + printf("Can't initialize EGL\n"); |
605 | + return 1; |
606 | + } |
607 | + |
608 | + vshader = load_shader(vshadersrc, GL_VERTEX_SHADER); |
609 | + assert(vshader); |
610 | + fshader = load_shader(fshadersrc, GL_FRAGMENT_SHADER); |
611 | + assert(fshader); |
612 | + prog = glCreateProgram(); |
613 | + assert(prog); |
614 | + glAttachShader(prog, vshader); |
615 | + glAttachShader(prog, fshader); |
616 | + glLinkProgram(prog); |
617 | + |
618 | + glGetProgramiv(prog, GL_LINK_STATUS, &linked); |
619 | + if (!linked) |
620 | + { |
621 | + GLchar log[1024]; |
622 | + glGetProgramInfoLog(prog, sizeof log - 1, NULL, log); |
623 | + log[sizeof log - 1] = '\0'; |
624 | + printf("Link failed: %s\n", log); |
625 | + return 2; |
626 | + } |
627 | + |
628 | + glClearColor(MID_AUBERGINE, 1.0); |
629 | + glViewport(0, 0, width, height); |
630 | + |
631 | + glUseProgram(prog); |
632 | + |
633 | + vpos = glGetAttribLocation(prog, "vPosition"); |
634 | + col = glGetUniformLocation(prog, "col"); |
635 | + theta = glGetUniformLocation(prog, "theta"); |
636 | + glUniform4f(col, ORANGE, 1.0f); |
637 | + |
638 | + glVertexAttribPointer(vpos, 2, GL_FLOAT, GL_FALSE, 0, vertices); |
639 | + glEnableVertexAttribArray(0); |
640 | + |
641 | + while (mir_eglapp_running()) |
642 | + { |
643 | + glClear(GL_COLOR_BUFFER_BIT); |
644 | + glUniform1f(theta, angle); |
645 | + angle += 0.02f; |
646 | + glDrawArrays(GL_TRIANGLES, 0, 3); |
647 | + mir_eglapp_swap_buffers(); |
648 | + } |
649 | + |
650 | + mir_eglapp_shutdown(); |
651 | + |
652 | + return 0; |
653 | +} |
PASSED: Continuous integration, rev:469 jenkins. qa.ubuntu. com/job/ mir-ci/ 22/ jenkins. qa.ubuntu. com/job/ mir-quantal- amd64-ci/ 22//console
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild: jenkins. qa.ubuntu. com/job/ mir-ci/ 22//rebuild/?
http://