mutter/examples/cogl-emscripten-hello.c

150 lines
3.6 KiB
C
Raw Normal View History

#include <cogl/cogl.h>
#include <stdio.h>
#include <SDL.h>
#include <emscripten.h>
#include "emscripten-example-js.h"
/* This short example is just to demonstrate using Cogl with
* Emscripten using SDL to receive input 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);
Add _primitive_draw to replace _framebuffer_draw_primitive When splitting out the CoglPath api we saw that we would be left with inconsistent drawing apis if the drawing apis in core Cogl were lumped into the cogl_framebuffer_ api considering other Cogl sub-libraries or that others will want to create higher level drawing apis outside of Cogl but can't use the same namespace. So that we can aim for a more consistent style this adds a cogl_primitive_draw() api, comparable to cogl_path_fill() or cogl_pango_show_layout() that's intended to replace cogl_framebuffer_draw_primitive() Note: the attribute and rectangle drawing apis are still in the cogl_framebuffer_ namespace and this might potentially change but in these cases there is no single object representing the thing being drawn so it seems a more reasonable they they live in the framebuffer namespace for now. Note: the cogl_framebuffer_draw_primitive() api isn't removed by this patch so it can more conveniently be cherry picked to the 1.16 branch so we can mark it deprecated for a short while. Even though it's marked as experimental api we know that there are people using the api so we'd like to give them a chance to switch to the new api. Reviewed-by: Neil Roberts <neil@linux.intel.com> (cherry picked from commit 418912b93ff81a47f9b38114d05335ab76277c48) Conflicts: cogl-pango/cogl-pango-display-list.c cogl/Makefile.am cogl/cogl-framebuffer.c cogl/cogl-pipeline-layer-state.h cogl/cogl2-path.c cogl/driver/gl/cogl-clip-stack-gl.c
2013-07-09 18:47:29 -04:00
cogl_primitive_draw (data->triangle, fb, data->pipeline);
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_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);
}
if (data.redraw_queued && data.ready_to_draw)
{
data.redraw_queued = FALSE;
data.ready_to_draw = FALSE;
redraw (&data);
}
/* NB: The mainloop will be automatically resumed if user input is received */
if (!data.redraw_queued)
emscripten_pause_main_loop ();
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;
/* The emscripten mainloop isn't event driven, it's periodic and so
* we aim to pause the emscripten mainlooop whenever we don't have a
* redraw queued. What we do instead is hook into the real browser
* mainloop using this javascript binding api to add an input event
* listener that will resume the emscripten mainloop whenever input
* is received.
*/
example_js_add_input_listener ();
emscripten_set_main_loop (mainloop, -1, TRUE);
cogl_object_unref (ctx);
return 0;
}