mutter/examples/cogl-emscripten-hello.c
Robert Bragg 0e7a632e13 Adds initial Emscripten support to Cogl
This enables basic Emscripten support in Cogl via the SDL winsys.
Assuming you have setup an emscripten toolchain you can configure Cogl
like this:

 emconfigure ./configure --enable-debug --enable-emscripten

Building the examples will build .html files that can be loaded directly
by a WebGL enabled browser.

Note: at this point the emscripten support has just barely been smoke
tested so it's expected that as we continue to build on this we will
learn about more things we need to change in Cogl to full support this
environment.

Reviewed-by: Neil Roberts <neil@linux.intel.com>

(cherry picked from commit a3bc2e7539391b074e697839dfae60b69c37cf10)
2013-05-29 19:30:44 +01:00

136 lines
3.0 KiB
C

#include <cogl/cogl.h>
#include <stdio.h>
#include <SDL.h>
#include <emscripten.h>
/* This short example is just to demonstrate mixing SDL with Cogl as a
simple way to get portable support for events */
typedef struct Data
{
CoglPrimitive *triangle;
CoglPipeline *pipeline;
float center_x, center_y;
CoglFramebuffer *fb;
CoglBool redraw_queued;
CoglBool ready_to_draw;
} Data;
static Data data;
static CoglContext *ctx;
static void
redraw (Data *data)
{
CoglFramebuffer *fb = data->fb;
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_translate (fb, data->center_x, -data->center_y, 0.0f);
cogl_framebuffer_draw_primitive (fb, data->pipeline, data->triangle);
cogl_framebuffer_pop_matrix (fb);
cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
}
static void
handle_event (Data *data, SDL_Event *event)
{
switch (event->type)
{
case SDL_VIDEOEXPOSE:
data->redraw_queued = TRUE;
break;
case SDL_MOUSEMOTION:
{
int width =
cogl_framebuffer_get_width (COGL_FRAMEBUFFER (data->fb));
int height =
cogl_framebuffer_get_height (COGL_FRAMEBUFFER (data->fb));
data->center_x = event->motion.x * 2.0f / width - 1.0f;
data->center_y = event->motion.y * 2.0f / height - 1.0f;
data->redraw_queued = TRUE;
}
break;
}
}
static void
frame_cb (CoglOnscreen *onscreen,
CoglFrameEvent event,
CoglFrameInfo *info,
void *user_data)
{
Data *data = user_data;
if (event == COGL_FRAME_EVENT_SYNC)
data->ready_to_draw = TRUE;
}
static void
mainloop (void)
{
SDL_Event event;
while (SDL_PollEvent (&event))
{
handle_event (&data, &event);
cogl_sdl_handle_event (ctx, &event);
}
redraw (&data);
data.redraw_queued = FALSE;
data.ready_to_draw = FALSE;
cogl_sdl_idle (ctx);
}
int
main (int argc, char **argv)
{
CoglOnscreen *onscreen;
CoglError *error = NULL;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0xff},
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
};
ctx = cogl_sdl_context_new (SDL_USEREVENT, &error);
if (!ctx)
{
fprintf (stderr, "Failed to create context: %s\n", error->message);
return 1;
}
onscreen = cogl_onscreen_new (ctx, 800, 600);
data.fb = COGL_FRAMEBUFFER (onscreen);
cogl_onscreen_add_frame_callback (onscreen,
frame_cb,
&data,
NULL /* destroy callback */);
data.center_x = 0.0f;
data.center_y = 0.0f;
cogl_onscreen_show (onscreen);
data.triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
data.pipeline = cogl_pipeline_new (ctx);
data.redraw_queued = TRUE;
data.ready_to_draw = TRUE;
emscripten_set_main_loop (mainloop, -1, TRUE);
cogl_object_unref (ctx);
return 0;
}