Exemplo n.º 1
0
static CoglBool
_cogl_winsys_set_gles2_context (CoglGLES2Context *gles2_ctx, CoglError **error)
{
  CoglContext *ctx = gles2_ctx->context;
  CoglDisplayEGL *egl_display = ctx->display->winsys;
  CoglBool status;

  if (gles2_ctx->write_buffer &&
      cogl_is_onscreen (gles2_ctx->write_buffer))
    status =
      bind_onscreen_with_context (COGL_ONSCREEN (gles2_ctx->write_buffer),
                                  gles2_ctx->winsys);
  else
    status = _cogl_winsys_egl_make_current (ctx->display,
                                            egl_display->dummy_surface,
                                            egl_display->dummy_surface,
                                            gles2_ctx->winsys);

  if (!status)
    {
      _cogl_set_error (error,
                   COGL_WINSYS_ERROR,
                   COGL_WINSYS_ERROR_MAKE_CURRENT,
                   "Failed to make gles2 context current");
      return FALSE;
    }

  return TRUE;
}
Exemplo n.º 2
0
static gboolean
paint_cb (void *user_data)
{
    Data *data = user_data;
    CoglError *error = NULL;
    const CoglGLES2Vtable *gles2 = data->gles2_vtable;

    /* Draw scene with GLES2 */
    if (!cogl_push_gles2_context (data->ctx,
                                  data->gles2_ctx,
                                  data->fb,
                                  data->fb,
                                  &error))
    {
        g_error ("Failed to push gles2 context: %s\n", error->message);
    }

    /* Clear offscreen framebuffer with a random color */
    gles2->glClearColor (g_random_double (),
                         g_random_double (),
                         g_random_double (),
                         1.0f);
    gles2->glClear (GL_COLOR_BUFFER_BIT);

    cogl_pop_gles2_context (data->ctx);

    /* Draw scene with Cogl */
    cogl_primitive_draw (data->triangle, data->fb, data->pipeline);

    cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));

    return FALSE; /* remove the callback */
}
Exemplo n.º 3
0
static void
_set_up_pipeline (gpointer instance,
                  gpointer user_data)
{
  Data* data = (Data*) user_data;

  /*
    The cogl-gst sink, depending on the video format, can use up to 3 texture
    layers to render a frame. To avoid overwriting frame data, the first
    free layer in the cogl pipeline needs to be queried before adding any
    additional textures.
  */

  int free_layer = cogl_gst_video_sink_get_free_layer (data->sink);
  data->video_pipeline = cogl_gst_video_sink_get_pipeline (data->sink);

  while (free_layer > 0)
    {
      free_layer--;
      cogl_pipeline_set_layer_filters (data->video_pipeline, free_layer,
                                       COGL_PIPELINE_FILTER_LINEAR_MIPMAP_LINEAR,
                                       COGL_PIPELINE_FILTER_LINEAR);
    }

  /* disable blending... */
  cogl_pipeline_set_blend (data->video_pipeline,
                           "RGBA = ADD (SRC_COLOR, 0)", NULL);

  /* Now that we know the video size we can perform letterboxing */
  _resize_callback (COGL_ONSCREEN (data->fb),
                    data->onscreen_width,
                    data->onscreen_height,
                    data);

  cogl_onscreen_add_frame_callback (COGL_ONSCREEN (data->fb), _frame_callback,
                                    data, NULL);

  /*
     The cogl-gst-new-frame signal is emitted when the cogl-gst sink has
     retrieved a new frame and attached it to the cogl pipeline. This can be
     used to make sure cogl doesn't do any unnecessary drawing i.e. keeps to the
     frame-rate of the video.
  */

  g_signal_connect (data->sink, "new-frame", G_CALLBACK (_new_frame_cb), data);
}
Exemplo n.º 4
0
static void
pre_paint_windows (MetaCompositor *compositor)
{
  GList *l;
  MetaWindowActor *top_window;

  if (compositor->onscreen == NULL)
    {
      compositor->onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ());
      compositor->frame_closure = cogl_onscreen_add_frame_callback (compositor->onscreen,
                                                                    frame_callback,
                                                                    compositor,
                                                                    NULL);
    }

  if (compositor->windows == NULL)
    return;

  top_window = g_list_last (compositor->windows)->data;

  if (meta_window_actor_should_unredirect (top_window) &&
      compositor->disable_unredirect_count == 0)
    set_unredirected_window (compositor, meta_window_actor_get_meta_window (top_window));
  else
    set_unredirected_window (compositor, NULL);

  for (l = compositor->windows; l; l = l->next)
    meta_window_actor_pre_paint (l->data);

  if (compositor->frame_has_updated_xsurfaces)
    {
      /* We need to make sure that any X drawing that happens before
       * the XDamageSubtract() for each window above is visible to
       * subsequent GL rendering; the only standardized way to do this
       * is EXT_x11_sync_object, which isn't yet widely available. For
       * now, we count on details of Xorg and the open source drivers,
       * and hope for the best otherwise.
       *
       * Xorg and open source driver specifics:
       *
       * The X server makes sure to flush drawing to the kernel before
       * sending out damage events, but since we use
       * DamageReportBoundingBox there may be drawing between the last
       * damage event and the XDamageSubtract() that needs to be
       * flushed as well.
       *
       * Xorg always makes sure that drawing is flushed to the kernel
       * before writing events or responses to the client, so any
       * round trip request at this point is sufficient to flush the
       * GLX buffers.
       */
      XSync (compositor->display->xdisplay, False);

      compositor->frame_has_updated_xsurfaces = FALSE;
    }
}
Exemplo n.º 5
0
static CoglBool
paint_cb (void *user_data)
{
    Data *data = user_data;

    cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
    cogl_framebuffer_draw_primitive (data->fb, data->pipeline, data->triangle);
    cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));

    return FALSE; /* remove the callback */
}
Exemplo n.º 6
0
static void handle_allocate(GtkWidget    *widget,
                            GdkRectangle *allocation,
                            gpointer      user_data)
{
    gdk_window_resize(g_GdkWindow,
                      allocation->width, allocation->height);
    g_Callbacks->resize(g_GdkWindow, COGL_ONSCREEN(g_Framebuffer),
                        allocation->width, allocation->height,
                        allocation->x, allocation->y);

}
Exemplo n.º 7
0
static CoglOnscreen *
find_onscreen_for_xid (CoglContext *context, uint32_t xid)
{
  GList *l;

  for (l = context->framebuffers; l; l = l->next)
    {
      CoglFramebuffer *framebuffer = l->data;
      CoglOnscreenEGL *egl_onscreen;
      CoglOnscreenXlib *xlib_onscreen;

      if (!framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
        continue;

      egl_onscreen = COGL_ONSCREEN (framebuffer)->winsys;
      xlib_onscreen = egl_onscreen->platform;
      if (xlib_onscreen->xwin == (Window)xid)
        return COGL_ONSCREEN (framebuffer);
    }

  return NULL;
}
Exemplo n.º 8
0
static gboolean
paint_cb (void *user_data)
{
    Data *data = user_data;
    double elapsed = g_timer_elapsed (data->timer, NULL);
    double dt = elapsed - data->last_elapsed;
    GError *error = NULL;

    /* Draw scene with GLES2 */
    if (!cogl_push_gles2_context (data->ctx,
                                  data->gles2_ctx,
                                  data->fb,
                                  data->fb,
                                  &error))
    {
        g_error ("Failed to push gles2 context: %s\n", error->message);
    }

    gears_draw ();

    cogl_pop_gles2_context (data->ctx);

    cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));

    /* advance rotation for next frame */
    angle += 70.0 * dt;  /* 70 degrees per second */
    if (angle > 3600.0)
        angle -= 3600.0;

    data->frames++;

    if (elapsed > 5.0) {
        GLfloat fps = data->frames / elapsed;
        printf ("%d frames in %3.1f seconds = %6.3f FPS\n",
                data->frames, elapsed, fps);
        g_timer_reset (data->timer);
        data->last_elapsed = 0;
        data->frames = 0;
    }else
      data->last_elapsed = elapsed;

    /* If the driver can deliver swap complete events then we can remove
     * the idle paint callback until we next get a swap complete event
     * otherwise we keep the idle paint callback installed and simply
     * paint as fast as the driver will allow... */
    if (cogl_has_feature (data->ctx, COGL_FEATURE_ID_SWAP_BUFFERS_EVENT))
      return FALSE; /* remove the callback */
    else
      return TRUE;
}
Exemplo n.º 9
0
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_primitive_draw (data->triangle, fb, data->pipeline);
  cogl_framebuffer_pop_matrix (fb);

  cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
}
Exemplo n.º 10
0
static CoglBool
paint_cb (void *user_data)
{
  CoglandCompositor *compositor = user_data;
  GList *l;

  for (l = compositor->outputs; l; l = l->next)
    {
      CoglandOutput *output = l->data;
      CoglFramebuffer *fb = COGL_FRAMEBUFFER (output->onscreen);
      GList *l2;

      cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);

      cogl_framebuffer_draw_primitive (fb, compositor->triangle_pipeline,
                                       compositor->triangle);

      for (l2 = compositor->surfaces; l2; l2 = l2->next)
        {
          CoglandSurface *surface = l2->data;

          if (surface->buffer)
            {
              CoglTexture2D *texture = surface->buffer->texture;
              CoglPipeline *pipeline =
                cogl_pipeline_new (compositor->cogl_context);
              cogl_pipeline_set_layer_texture (pipeline, 0,
                                               COGL_TEXTURE (texture));
              cogl_framebuffer_draw_rectangle (fb, pipeline, -1, 1, 1, -1);
              cogl_object_unref (pipeline);
            }
        }
      cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
    }

  while (!g_queue_is_empty (&compositor->frame_callbacks))
    {
      CoglandFrameCallback *callback =
        g_queue_peek_head (&compositor->frame_callbacks);

      wl_resource_post_event (&callback->resource,
                              WL_CALLBACK_DONE, get_time ());
      wl_resource_destroy (&callback->resource, 0);
    }

  return TRUE;
}
Exemplo n.º 11
0
Arquivo: cogland.c Projeto: 3v1n0/cogl
static CoglBool
paint_cb (void *user_data)
{
  CoglandCompositor *compositor = user_data;
  GList *l;

  for (l = compositor->outputs; l; l = l->next)
    {
      CoglandOutput *output = l->data;
      CoglFramebuffer *fb = output->onscreen;
      GList *l2;

      cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);

      cogl_primitive_draw (compositor->triangle,
                           fb, compositor->triangle_pipeline);

      for (l2 = compositor->surfaces; l2; l2 = l2->next)
        {
          CoglandSurface *surface = l2->data;

          if (surface->texture)
            {
              CoglTexture2D *texture = surface->texture;
              CoglPipeline *pipeline =
                cogl_pipeline_new (compositor->cogl_context);
              cogl_pipeline_set_layer_texture (pipeline, 0, texture);
              cogl_framebuffer_draw_rectangle (fb, pipeline, -1, 1, 1, -1);
              cogl_object_unref (pipeline);
            }
        }
      cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
    }

  while (!wl_list_empty (&compositor->frame_callbacks))
    {
      CoglandFrameCallback *callback =
        wl_container_of (compositor->frame_callbacks.next, callback, link);

      wl_callback_send_done (callback->resource, get_time ());
      wl_resource_destroy (callback->resource);
    }

  compositor->redraw_idle = 0;

  return G_SOURCE_REMOVE;
}
Exemplo n.º 12
0
int
main (int argc, char **argv)
{
    Data data;
    CoglOnscreen *onscreen;
    CoglError *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}
    };
    GSource *cogl_source;
    GMainLoop *loop;

    data.ctx = cogl_context_new (NULL, &error);
    if (!data.ctx) {
        fprintf (stderr, "Failed to create context: %s\n", error->message);
        return 1;
    }

    onscreen = cogl_onscreen_new (data.ctx, 640, 480);
    cogl_onscreen_show (onscreen);
    data.fb = COGL_FRAMEBUFFER (onscreen);

    cogl_onscreen_set_resizable (onscreen, TRUE);

    data.triangle = cogl_primitive_new_p2c4 (data.ctx,
                                             COGL_VERTICES_MODE_TRIANGLES,
                                             3, triangle_vertices);
    data.pipeline = cogl_pipeline_new (data.ctx);

    cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT);

    g_source_attach (cogl_source, NULL);

    if (cogl_has_feature (data.ctx, COGL_FEATURE_ID_SWAP_BUFFERS_EVENT))
      cogl_onscreen_add_swap_buffers_callback (COGL_ONSCREEN (data.fb),
                                               swap_complete_cb, &data);

    g_idle_add (paint_cb, &data);

    loop = g_main_loop_new (NULL, TRUE);
    g_main_loop_run (loop);

    return 0;
}
Exemplo n.º 13
0
static void
flush_pending_resize_notifications_cb (void *data,
                                       void *user_data)
{
  CoglFramebuffer *framebuffer = data;

  if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
    {
      CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
      CoglOnscreenEGL *egl_onscreen = onscreen->winsys;

      if (egl_onscreen->pending_resize_notify)
        {
          _cogl_onscreen_notify_resize (onscreen);
          egl_onscreen->pending_resize_notify = FALSE;
        }
    }
}
Exemplo n.º 14
0
static CoglBool
paint_cb (void *user_data)
{
    Data *data = user_data;

    cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
    cogl_framebuffer_draw_primitive (data->fb, data->pipeline, data->triangle);
    cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));

    /* If the driver can deliver swap complete events then we can remove
     * the idle paint callback until we next get a swap complete event
     * otherwise we keep the idle paint callback installed and simply
     * paint as fast as the driver will allow... */
    if (cogl_has_feature (data->ctx, COGL_FEATURE_ID_SWAP_BUFFERS_EVENT))
      return FALSE; /* remove the callback */
    else
      return TRUE;
}
Exemplo n.º 15
0
static gboolean
paint_cb (void *user_data)
{
    Data *data = user_data;
    double elapsed = g_timer_elapsed (data->timer, NULL);
    double dt = elapsed - data->last_elapsed;
    CoglError *error = NULL;

    /* Draw scene with GLES2 */
    if (!cogl_push_gles2_context (data->ctx,
                                  data->gles2_ctx,
                                  data->fb,
                                  data->fb,
                                  &error))
    {
        g_error ("Failed to push gles2 context: %s\n", error->message);
    }

    gears_draw ();

    cogl_pop_gles2_context (data->ctx);

    cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));

    /* advance rotation for next frame */
    angle += 70.0 * dt;  /* 70 degrees per second */
    if (angle > 3600.0)
        angle -= 3600.0;

    data->frames++;

    if (elapsed > 5.0) {
        GLfloat fps = data->frames / elapsed;
        printf ("%d frames in %3.1f seconds = %6.3f FPS\n",
                data->frames, elapsed, fps);
        g_timer_reset (data->timer);
        data->last_elapsed = 0;
        data->frames = 0;
    }else
      data->last_elapsed = elapsed;

    return FALSE; /* remove the callback */
}
Exemplo n.º 16
0
static CoglFilterReturn
sdl_event_filter_cb (SDL_Event *event, void *data)
{
  if (event->type == SDL_WINDOWEVENT &&
      event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
    {
      CoglContext *context = data;
      CoglDisplay *display = context->display;
      CoglDisplaySdl2 *sdl_display = display->winsys;
      float width = event->window.data1;
      float height = event->window.data2;
      CoglFramebuffer *framebuffer;
      CoglOnscreenSdl2 *sdl_onscreen;
      SDL_Window *window;

      window = SDL_GetWindowFromID (event->window.windowID);

      if (window == NULL)
        return COGL_FILTER_CONTINUE;

      framebuffer = SDL_GetWindowData (window, COGL_SDL_WINDOW_DATA_KEY);

      if (framebuffer == NULL || framebuffer->context != context)
        return COGL_FILTER_CONTINUE;

      _cogl_framebuffer_winsys_update_size (framebuffer, width, height);

      sdl_onscreen = COGL_ONSCREEN (framebuffer)->winsys;

      /* We only want to notify that a resize happened when the
         application calls cogl_context_dispatch so instead of immediately
         notifying we'll set a flag to remember to notify later */
      sdl_display->pending_resize_notify = TRUE;
      sdl_onscreen->pending_resize_notify = TRUE;

      return COGL_FILTER_CONTINUE;
    }

  return COGL_FILTER_CONTINUE;
}
Exemplo n.º 17
0
static void
flush_pending_swap_notify_cb (void *data,
                              void *user_data)
{
  CoglFramebuffer *framebuffer = data;

  if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
    {
      CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
      CoglOnscreenEGL *egl_onscreen = onscreen->winsys;
      CoglOnscreenKMS *kms_onscreen = egl_onscreen->platform;

      if (kms_onscreen->pending_swap_notify)
        {
          CoglFrameInfo *info = g_queue_pop_head (&onscreen->pending_frame_infos);

          _cogl_onscreen_notify_frame_sync (onscreen, info);
          _cogl_onscreen_notify_complete (onscreen, info);
          kms_onscreen->pending_swap_notify = FALSE;

          cogl_object_unref (info);
        }
    }
}
Exemplo n.º 18
0
int
main (int argc, char **argv)
{
    Data data;
    CoglOnscreen *onscreen;
    GError *error = NULL;
    GSource *cogl_source;
    GMainLoop *loop;
    CoglRenderer *renderer;
    CoglDisplay *display;

    renderer = cogl_renderer_new ();
    cogl_renderer_add_constraint (renderer,
                                  COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2);
    display = cogl_display_new (renderer, NULL);
    data.ctx = cogl_context_new (display, NULL);

    onscreen = cogl_onscreen_new (data.ctx, 300, 300);
    cogl_onscreen_show (onscreen);
    data.fb = COGL_FRAMEBUFFER (onscreen);

    data.gles2_ctx = cogl_gles2_context_new (data.ctx, &error);
    if (!data.gles2_ctx)
        g_error ("Failed to create GLES2 context: %s\n", error->message);

    /* Draw scene with GLES2 */
    if (!cogl_push_gles2_context (data.ctx,
                                  data.gles2_ctx,
                                  data.fb,
                                  data.fb,
                                  &error))
    {
        g_error ("Failed to push gles2 context: %s\n", error->message);
    }

    gears_reshape (cogl_framebuffer_get_width (data.fb),
                   cogl_framebuffer_get_height (data.fb));

    /* Initialize the gears */
    gears_init();

    cogl_pop_gles2_context (data.ctx);

    cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT);

    g_source_attach (cogl_source, NULL);

    if (cogl_has_feature (data.ctx, COGL_FEATURE_ID_SWAP_BUFFERS_EVENT))
        cogl_onscreen_add_swap_buffers_callback (COGL_ONSCREEN (data.fb),
                                                 swap_complete_cb, &data);

    g_idle_add (paint_cb, &data);

    data.timer = g_timer_new ();
    data.frames = 0;
    data.last_elapsed = 0;

    loop = g_main_loop_new (NULL, TRUE);
    g_main_loop_run (loop);

    return 0;
}
Exemplo n.º 19
0
static void handle_repaint(GdkFrameClock *clock, void *data)
{
    g_Callback(COGL_ONSCREEN(g_Framebuffer), g_CallbackData);
}
Exemplo n.º 20
0
CoglOnscreen* ImGui_ImplGtk3Cogl_Init(GtkWidget* widget,
                                      void (*callback)(CoglOnscreen *onscreen, void *data),
                                      void *data)
{
    g_clear_pointer(&g_GtkWidget, g_object_unref);
    g_clear_pointer(&g_GdkWindow, g_object_unref);
    g_clear_pointer(&g_Framebuffer, cogl_object_unref);
    g_clear_pointer(&g_Context, cogl_object_unref);

    g_GtkWidget = GTK_WIDGET(g_object_ref(widget));
    gtk_widget_realize(widget);
    GdkWindow *parent_window = gtk_widget_get_window(widget);

    GtkAllocation allocation;
    gtk_widget_get_allocation(widget, &allocation);

    g_Callbacks = get_backend_callbacks(parent_window);

    GdkWindowAttr attributes;
    memset(&attributes, 0, sizeof(attributes));
    attributes.x = 0;
    attributes.y = 0;
    attributes.width = allocation.width;
    attributes.height = allocation.height;
    attributes.wclass = GDK_INPUT_OUTPUT;
    attributes.window_type = g_Callbacks->winsys == COGL_WINSYS_ID_EGL_WAYLAND ?
        GDK_WINDOW_SUBSURFACE : GDK_WINDOW_CHILD;

    GdkDisplay *display = gdk_window_get_display(parent_window);
    attributes.visual = gtk_widget_get_visual(widget);

    g_GdkWindow = gdk_window_new(parent_window, &attributes,
                                 GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
    gdk_window_set_transient_for(g_GdkWindow, parent_window);
    gdk_window_set_pass_through(g_GdkWindow, TRUE);

    cairo_rectangle_int_t empty_rect;
    memset(&empty_rect, 0, sizeof(empty_rect));
    cairo_region_t *input_region = cairo_region_create_rectangle(&empty_rect);
    gdk_window_input_shape_combine_region(g_GdkWindow, input_region, 0, 0);
    cairo_region_destroy(input_region);

    cairo_region_t *region = get_window_region(g_GdkWindow);
    gdk_window_set_opaque_region(g_GdkWindow, region);
    cairo_region_destroy(region);

    CoglRenderer *renderer = cogl_renderer_new();
    cogl_renderer_set_winsys_id(renderer, g_Callbacks->winsys);
    g_Callbacks->init(renderer, display, g_GdkWindow);

    gdk_window_ensure_native(g_GdkWindow);

    g_Context = cogl_context_new(cogl_display_new(renderer, NULL), NULL);
    CoglOnscreen *onscreen = cogl_onscreen_new(g_Context, 1, 1);
    cogl_object_unref(renderer);

    g_Callbacks->resize(g_GdkWindow, onscreen,
                        allocation.width, allocation.height,
                        allocation.x, allocation.y);

    gtk_widget_add_events(widget, EVENT_MASK);
    g_signal_connect(widget, "event", G_CALLBACK(handle_gdk_event), NULL);
    g_signal_connect(widget, "size-allocate", G_CALLBACK(handle_allocate), NULL);

    g_Callbacks->set_window(onscreen, g_GdkWindow);

    if (!cogl_framebuffer_allocate(COGL_FRAMEBUFFER(onscreen), NULL))
        g_warning("Unable to allocate framebuffer");

    g_Framebuffer = COGL_FRAMEBUFFER(onscreen);

    ImGuiIO& io = ImGui::GetIO();
    for (int i = 0; i < ImGuiKey_COUNT; i++)
    {
        io.KeyMap[i] = i;
    }

    io.SetClipboardTextFn = ImGui_ImplGtk3Cogl_SetClipboardText;
    io.GetClipboardTextFn = ImGui_ImplGtk3Cogl_GetClipboardText;
    io.ClipboardUserData = gtk_widget_get_clipboard(g_GtkWidget,
                                                    GDK_SELECTION_CLIPBOARD);

    g_Callback = callback;
    g_CallbackData = data;
    GdkFrameClock *clock = gdk_window_get_frame_clock(g_GdkWindow);
    g_signal_connect(clock, "paint", G_CALLBACK(handle_repaint), NULL);

    gdk_frame_clock_request_phase(clock, GDK_FRAME_CLOCK_PHASE_PAINT);

    gdk_window_show(g_GdkWindow);

    return COGL_ONSCREEN(g_Framebuffer);
}
Exemplo n.º 21
0
int
main (int argc, char **argv)
{
  CoglContext *ctx;
  CoglOnscreen *onscreen;
  CoglFramebuffer *fb;
  GError *error = NULL;
  Data data;
  PangoRectangle hello_label_size;
  float fovy, aspect, z_near, z_2d, z_far;
  CoglDepthState depth_state;
  CoglBool has_swap_notify;

  ctx = cogl_context_new (NULL, &error);
  if (!ctx) {
      fprintf (stderr, "Failed to create context: %s\n", error->message);
      return 1;
  }

  onscreen = cogl_onscreen_new (ctx, 640, 480);
  fb = COGL_FRAMEBUFFER (onscreen);
  data.fb = fb;
  data.framebuffer_width = cogl_framebuffer_get_width (fb);
  data.framebuffer_height = cogl_framebuffer_get_height (fb);

  data.timer = g_timer_new ();

  cogl_onscreen_show (onscreen);

  cogl_framebuffer_set_viewport (fb,
                                 0, 0,
                                 data.framebuffer_width,
                                 data.framebuffer_height);

  fovy = 60; /* y-axis field of view */
  aspect = (float)data.framebuffer_width/(float)data.framebuffer_height;
  z_near = 0.1; /* distance to near clipping plane */
  z_2d = 1000; /* position to 2d plane */
  z_far = 2000; /* distance to far clipping plane */

  cogl_framebuffer_perspective (fb, fovy, aspect, z_near, z_far);

  /* Since the pango renderer emits geometry in pixel/device coordinates
   * and the anti aliasing is implemented with the assumption that the
   * geometry *really* does end up pixel aligned, we setup a modelview
   * matrix so that for geometry in the plane z = 0 we exactly map x
   * coordinates in the range [0,stage_width] and y coordinates in the
   * range [0,stage_height] to the framebuffer extents with (0,0) being
   * the top left.
   *
   * This is roughly what Clutter does for a ClutterStage, but this
   * demonstrates how it is done manually using Cogl.
   */
  cogl_matrix_init_identity (&data.view);
  cogl_matrix_view_2d_in_perspective (&data.view, fovy, aspect, z_near, z_2d,
                                      data.framebuffer_width,
                                      data.framebuffer_height);
  cogl_framebuffer_set_modelview_matrix (fb, &data.view);

  /* Initialize some convenient constants */
  cogl_matrix_init_identity (&identity);
  cogl_color_set_from_4ub (&white, 0xff, 0xff, 0xff, 0xff);

  /* rectangle indices allow the GPU to interpret a list of quads (the
   * faces of our cube) as a list of triangles.
   *
   * Since this is a very common thing to do
   * cogl_get_rectangle_indices() is a convenience function for
   * accessing internal index buffers that can be shared.
   */
  data.indices = cogl_get_rectangle_indices (ctx, 6 /* n_rectangles */);
  data.prim = cogl_primitive_new_p3t2 (ctx, COGL_VERTICES_MODE_TRIANGLES,
                                       G_N_ELEMENTS (vertices),
                                       vertices);
  /* Each face will have 6 indices so we have 6 * 6 indices in total... */
  cogl_primitive_set_indices (data.prim,
                              data.indices,
                              6 * 6);

  /* Load a jpeg crate texture from a file */
  printf ("crate.jpg (CC by-nc-nd http://bit.ly/9kP45T) ShadowRunner27 http://bit.ly/m1YXLh\n");
  data.texture = cogl_texture_new_from_file (COGL_EXAMPLES_DATA "crate.jpg",
                                             COGL_TEXTURE_NO_SLICING,
                                             COGL_PIXEL_FORMAT_ANY,
                                             &error);
  if (!data.texture)
    g_error ("Failed to load texture: %s", error->message);

  /* a CoglPipeline conceptually describes all the state for vertex
   * processing, fragment processing and blending geometry. When
   * drawing the geometry for the crate this pipeline says to sample a
   * single texture during fragment processing... */
  data.crate_pipeline = cogl_pipeline_new (ctx);
  cogl_pipeline_set_layer_texture (data.crate_pipeline, 0, data.texture);

  /* Since the box is made of multiple triangles that will overlap
   * when drawn and we don't control the order they are drawn in, we
   * enable depth testing to make sure that triangles that shouldn't
   * be visible get culled by the GPU. */
  cogl_depth_state_init (&depth_state);
  cogl_depth_state_set_test_enabled (&depth_state, TRUE);

  cogl_pipeline_set_depth_state (data.crate_pipeline, &depth_state, NULL);

  /* Setup a Pango font map and context */

  data.pango_font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new (ctx));

  cogl_pango_font_map_set_use_mipmapping (data.pango_font_map, TRUE);

  data.pango_context =
    pango_font_map_create_context (PANGO_FONT_MAP (data.pango_font_map));

  data.pango_font_desc = pango_font_description_new ();
  pango_font_description_set_family (data.pango_font_desc, "Sans");
  pango_font_description_set_size (data.pango_font_desc, 30 * PANGO_SCALE);

  /* Setup the "Hello Cogl" text */

  data.hello_label = pango_layout_new (data.pango_context);
  pango_layout_set_font_description (data.hello_label, data.pango_font_desc);
  pango_layout_set_text (data.hello_label, "Hello Cogl", -1);

  pango_layout_get_extents (data.hello_label, NULL, &hello_label_size);
  data.hello_label_width = PANGO_PIXELS (hello_label_size.width);
  data.hello_label_height = PANGO_PIXELS (hello_label_size.height);

  data.swap_ready = TRUE;

  has_swap_notify =
    cogl_has_feature (ctx, COGL_FEATURE_ID_SWAP_BUFFERS_EVENT);

  if (has_swap_notify)
    cogl_onscreen_add_swap_buffers_callback (COGL_ONSCREEN (fb),
                                             swap_notify_cb,
                                             &data);

  while (1)
    {
      CoglPollFD *poll_fds;
      int n_poll_fds;
      int64_t timeout;

      if (data.swap_ready)
        {
          paint (&data);
          cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
        }

      cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);

      if (!has_swap_notify)
        {
          /* If the winsys doesn't support swap event notification
             then we'll just redraw constantly */
          data.swap_ready = TRUE;
          timeout = 0;
        }

      g_poll ((GPollFD *) poll_fds, n_poll_fds,
              timeout == -1 ? -1 : timeout / 1000);

      cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
    }

  return 0;
}
Exemplo n.º 22
0
static gboolean
meta_pre_paint_func (gpointer data)
{
  GList *l;
  MetaWindowActor *top_window;
  MetaCompositor *compositor = data;

  if (compositor->onscreen == NULL)
    {
      compositor->onscreen = COGL_ONSCREEN (cogl_get_draw_framebuffer ());
      compositor->frame_closure = cogl_onscreen_add_frame_callback (compositor->onscreen,
                                                                    frame_callback,
                                                                    compositor,
                                                                    NULL);
    }

  if (compositor->windows == NULL)
    return TRUE;

  top_window = g_list_last (compositor->windows)->data;

  if (meta_window_actor_should_unredirect (top_window) &&
      compositor->disable_unredirect_count == 0)
    set_unredirected_window (compositor, meta_window_actor_get_meta_window (top_window));
  else
    set_unredirected_window (compositor, NULL);

  for (l = compositor->windows; l; l = l->next)
    meta_window_actor_pre_paint (l->data);

  if (compositor->frame_has_updated_xsurfaces)
    {
      /* We need to make sure that any X drawing that happens before
       * the XDamageSubtract() for each window above is visible to
       * subsequent GL rendering; the standardized way to do this is
       * GL_EXT_X11_sync_object. Since this isn't implemented yet in
       * mesa, we also have a path that relies on the implementation
       * of the open source drivers.
       *
       * Anything else, we just hope for the best.
       *
       * Xorg and open source driver specifics:
       *
       * The X server makes sure to flush drawing to the kernel before
       * sending out damage events, but since we use
       * DamageReportBoundingBox there may be drawing between the last
       * damage event and the XDamageSubtract() that needs to be
       * flushed as well.
       *
       * Xorg always makes sure that drawing is flushed to the kernel
       * before writing events or responses to the client, so any
       * round trip request at this point is sufficient to flush the
       * GLX buffers.
       */
      if (compositor->have_x11_sync_object)
        compositor->have_x11_sync_object = meta_sync_ring_insert_wait ();
      else
        XSync (compositor->display->xdisplay, False);
    }

  return TRUE;
}
Exemplo n.º 23
0
static void
_draw (Data *data)
{
  /*
    The cogl pipeline needs to be retrieved from the sink before every draw.
    This is due to the cogl-gst sink creating a new cogl pipeline for each frame
    by copying the previous one and attaching the new frame to it.
  */
  CoglPipeline* current = cogl_gst_video_sink_get_pipeline (data->sink);

  data->video_pipeline = current;

  if (data->video_output.x)
    {
      int x = data->video_output.x;

      /* Letterboxed with vertical borders */
      cogl_framebuffer_draw_rectangle (data->fb,
                                       data->border_pipeline,
                                       0, 0, x, data->onscreen_height);
      cogl_framebuffer_draw_rectangle (data->fb,
                                       data->border_pipeline,
                                       data->onscreen_width - x,
                                       0,
                                       data->onscreen_width,
                                       data->onscreen_height);
      cogl_framebuffer_draw_rectangle (data->fb, data->video_pipeline,
                                       x, 0,
                                       x + data->video_output.width,
                                       data->onscreen_height);
    }
  else if (data->video_output.y)
    {
      int y = data->video_output.y;

      /* Letterboxed with horizontal borders */
      cogl_framebuffer_draw_rectangle (data->fb,
                                       data->border_pipeline,
                                       0, 0, data->onscreen_width, y);
      cogl_framebuffer_draw_rectangle (data->fb,
                                       data->border_pipeline,
                                       0,
                                       data->onscreen_height - y,
                                       data->onscreen_width,
                                       data->onscreen_height);
      cogl_framebuffer_draw_rectangle (data->fb, data->video_pipeline,
                                       0, y,
                                       data->onscreen_width,
                                       y + data->video_output.height);

    }
  else
    {
      cogl_framebuffer_draw_rectangle (data->fb,
                                       data->video_pipeline,
                                       0, 0,
                                       data->onscreen_width,
                                       data->onscreen_height);
    }

  cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));
}
Exemplo n.º 24
0
int
main (int argc, char **argv)
{
    Data data;
    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}
    };
    GSource *cogl_source;
    GMainLoop *loop;
    CoglRenderer *renderer;
    CoglDisplay *display;

    renderer = cogl_renderer_new ();
    cogl_renderer_add_constraint (renderer,
                                  COGL_RENDERER_CONSTRAINT_SUPPORTS_COGL_GLES2);
    display = cogl_display_new (renderer, NULL);
    data.ctx = cogl_context_new (display, NULL);

    onscreen = cogl_onscreen_new (data.ctx, 640, 480);
    cogl_onscreen_show (onscreen);
    data.fb = COGL_FRAMEBUFFER (onscreen);

    /* Prepare onscreen primitive */
    data.triangle = cogl_primitive_new_p2c4 (data.ctx,
                                             COGL_VERTICES_MODE_TRIANGLES,
                                             3, triangle_vertices);
    data.pipeline = cogl_pipeline_new (data.ctx);

    data.offscreen_texture = COGL_TEXTURE (
      cogl_texture_2d_new_with_size (data.ctx,
                                     OFFSCREEN_WIDTH,
                                     OFFSCREEN_HEIGHT,
                                     COGL_PIXEL_FORMAT_ANY));
    data.offscreen = cogl_offscreen_new_to_texture (data.offscreen_texture);

    data.gles2_ctx = cogl_gles2_context_new (data.ctx, &error);
    if (!data.gles2_ctx) {
        g_error ("Failed to create GLES2 context: %s\n", error->message);
    }

    data.gles2_vtable = cogl_gles2_context_get_vtable (data.gles2_ctx);

    /* Draw scene with GLES2 */
    if (!cogl_push_gles2_context (data.ctx,
                                  data.gles2_ctx,
                                  data.fb,
                                  data.fb,
                                  &error))
    {
        g_error ("Failed to push gles2 context: %s\n", error->message);
    }

    cogl_pop_gles2_context (data.ctx);

    cogl_source = cogl_glib_source_new (data.ctx, G_PRIORITY_DEFAULT);

    g_source_attach (cogl_source, NULL);

    cogl_onscreen_add_frame_callback (COGL_ONSCREEN (data.fb),
                                      frame_event_cb,
                                      &data,
                                      NULL); /* destroy notify */

    g_idle_add (paint_cb, &data);

    loop = g_main_loop_new (NULL, TRUE);
    g_main_loop_run (loop);

    return 0;
}