2011-12-14 09:09:00 -05:00
|
|
|
#include <cogl/cogl.h>
|
|
|
|
#include <glib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <SDL.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
|
|
|
|
{
|
|
|
|
CoglColor black;
|
|
|
|
CoglPrimitive *triangle;
|
|
|
|
float center_x, center_y;
|
|
|
|
CoglFramebuffer *fb;
|
2011-12-19 10:40:55 -05:00
|
|
|
gboolean quit;
|
2011-12-14 09:09:00 -05:00
|
|
|
} Data;
|
|
|
|
|
|
|
|
static void
|
|
|
|
redraw (Data *data)
|
|
|
|
{
|
|
|
|
cogl_clear (&data->black, COGL_BUFFER_BIT_COLOR);
|
|
|
|
|
|
|
|
cogl_push_matrix ();
|
|
|
|
cogl_translate (data->center_x, -data->center_y, 0.0f);
|
|
|
|
|
|
|
|
cogl_primitive_draw (data->triangle);
|
|
|
|
cogl_pop_matrix ();
|
|
|
|
|
|
|
|
cogl_framebuffer_swap_buffers (data->fb);
|
|
|
|
}
|
|
|
|
|
2011-12-19 10:40:55 -05:00
|
|
|
static void
|
|
|
|
handle_event (Data *data, SDL_Event *event)
|
|
|
|
{
|
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case SDL_VIDEOEXPOSE:
|
|
|
|
redraw (data);
|
|
|
|
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;
|
|
|
|
|
|
|
|
redraw (data);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SDL_QUIT:
|
|
|
|
data->quit = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Uint32
|
|
|
|
timer_handler (Uint32 interval, void *user_data)
|
|
|
|
{
|
|
|
|
static const SDL_UserEvent dummy_event =
|
|
|
|
{
|
|
|
|
SDL_USEREVENT
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Post an event to wake up from SDL_WaitEvent */
|
|
|
|
SDL_PushEvent ((SDL_Event *) &dummy_event);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
wait_event_with_timeout (Data *data, SDL_Event *event, gint64 timeout)
|
|
|
|
{
|
|
|
|
if (timeout == -1)
|
|
|
|
{
|
|
|
|
if (SDL_WaitEvent (event))
|
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
data->quit = TRUE;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (timeout == 0)
|
|
|
|
return SDL_PollEvent (event);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gboolean ret;
|
|
|
|
/* Add a timer so that we can wake up the event loop */
|
|
|
|
SDL_TimerID timer_id =
|
|
|
|
SDL_AddTimer (timeout / 1000, timer_handler, data);
|
|
|
|
|
|
|
|
if (SDL_WaitEvent (event))
|
|
|
|
ret = TRUE;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
data->quit = TRUE;
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_RemoveTimer (timer_id);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-14 09:09:00 -05:00
|
|
|
int
|
|
|
|
main (int argc, char **argv)
|
|
|
|
{
|
|
|
|
CoglRenderer *renderer;
|
|
|
|
CoglDisplay *display;
|
|
|
|
CoglContext *ctx;
|
|
|
|
CoglOnscreen *onscreen;
|
|
|
|
GError *error = NULL;
|
|
|
|
CoglVertexP2C4 triangle_vertices[] = {
|
|
|
|
{0, 0.7, 0xff, 0x00, 0x00, 0x80},
|
|
|
|
{-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
|
|
|
|
{0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
|
|
|
|
};
|
|
|
|
Data data;
|
|
|
|
SDL_Event event;
|
|
|
|
|
|
|
|
/* Force the SDL winsys */
|
|
|
|
renderer = cogl_renderer_new ();
|
|
|
|
cogl_renderer_set_winsys_id (renderer, COGL_WINSYS_ID_SDL);
|
|
|
|
display = cogl_display_new (renderer, NULL);
|
|
|
|
ctx = cogl_context_new (display, &error);
|
|
|
|
if (!ctx)
|
|
|
|
{
|
|
|
|
fprintf (stderr, "Failed to create context: %s\n", error->message);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-12-19 10:40:55 -05:00
|
|
|
SDL_InitSubSystem (SDL_INIT_TIMER);
|
|
|
|
|
2011-12-14 09:09:00 -05:00
|
|
|
onscreen = cogl_onscreen_new (ctx, 800, 600);
|
|
|
|
/* Eventually there will be an implicit allocate on first use so this
|
|
|
|
* will become optional... */
|
|
|
|
data.fb = COGL_FRAMEBUFFER (onscreen);
|
|
|
|
if (!cogl_framebuffer_allocate (data.fb, &error))
|
|
|
|
{
|
|
|
|
fprintf (stderr, "Failed to allocate framebuffer: %s\n",
|
|
|
|
error->message);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
cogl_color_set_from_4ub (&data.black, 0, 0, 0, 255);
|
|
|
|
data.center_x = 0.0f;
|
|
|
|
data.center_y = 0.0f;
|
2011-12-19 10:40:55 -05:00
|
|
|
data.quit = FALSE;
|
2011-12-14 09:09:00 -05:00
|
|
|
|
|
|
|
cogl_onscreen_show (onscreen);
|
|
|
|
|
|
|
|
cogl_push_framebuffer (data.fb);
|
|
|
|
|
|
|
|
data.triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
|
|
|
|
3, triangle_vertices);
|
2011-12-19 10:40:55 -05:00
|
|
|
while (!data.quit)
|
2011-12-14 09:09:00 -05:00
|
|
|
{
|
2011-12-19 10:40:55 -05:00
|
|
|
CoglPollFD *poll_fds;
|
|
|
|
int n_poll_fds;
|
|
|
|
gint64 timeout;
|
|
|
|
|
|
|
|
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
|
2011-12-14 09:09:00 -05:00
|
|
|
|
2011-12-19 10:40:55 -05:00
|
|
|
/* It's difficult to wait for file descriptors using the SDL
|
|
|
|
event mechanism, but it the SDL winsys is documented that it
|
|
|
|
will never require this so we can assert that there are no
|
|
|
|
fds */
|
|
|
|
g_assert (n_poll_fds == 0);
|
2011-12-14 09:09:00 -05:00
|
|
|
|
2011-12-19 10:40:55 -05:00
|
|
|
if (wait_event_with_timeout (&data, &event, timeout))
|
|
|
|
do
|
|
|
|
handle_event (&data, &event);
|
|
|
|
while (SDL_PollEvent (&event));
|
|
|
|
|
|
|
|
cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
|
|
|
|
}
|
2011-12-14 09:09:00 -05:00
|
|
|
|
|
|
|
cogl_pop_framebuffer ();
|
|
|
|
|
|
|
|
cogl_object_unref (ctx);
|
|
|
|
cogl_object_unref (display);
|
|
|
|
cogl_object_unref (renderer);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|