Ejemplo n.º 1
0
static ClutterStageWaylandWaylandBuffer *
wayland_create_buffer (ClutterGeometry *geom)
{
  ClutterBackend *backend = clutter_get_default_backend ();
  ClutterBackendWayland *backend_wayland = CLUTTER_BACKEND_WAYLAND (backend);
  ClutterStageWaylandWaylandBuffer *buffer;
  cairo_rectangle_int_t rect;

  if (backend_wayland->drm_enabled &&
      backend_wayland->wayland_drm != NULL)
    buffer = wayland_create_drm_buffer (backend_wayland, geom);
  else if (backend_wayland->wayland_shm != NULL)
    buffer = wayland_create_shm_buffer (backend_wayland, geom);
  else
    return NULL;

  buffer->offscreen = cogl_offscreen_new_to_texture (buffer->tex);

  rect.x = geom->x;
  rect.y = geom->y;
  rect.width = geom->width;
  rect.height = geom->height;
  buffer->dirty_region = cairo_region_create_rectangle (&rect);

  return buffer;
}
Ejemplo n.º 2
0
void
test_backface_culling (void)
{
  TestState state;
  CoglTexture *tex;

  state.width = cogl_framebuffer_get_width (test_fb);
  state.height = cogl_framebuffer_get_height (test_fb);

  state.offscreen = NULL;

  state.texture = make_texture ();

  tex = cogl_texture_new_with_size (state.width, state.height,
                                    COGL_TEXTURE_NO_SLICING,
                                    COGL_PIXEL_FORMAT_ANY); /* internal fmt */
  state.offscreen = COGL_FRAMEBUFFER (cogl_offscreen_new_to_texture (tex));
  state.offscreen_tex = tex;

  paint (&state);

  cogl_object_unref (state.offscreen);
  cogl_object_unref (state.offscreen_tex);
  cogl_object_unref (state.texture);

  if (cogl_test_verbose ())
    g_print ("OK\n");
}
Ejemplo n.º 3
0
void
test_cogl_backface_culling (TestUtilsGTestFixture *fixture,
                            void *data)
{
  TestUtilsSharedState *shared_state = data;
  TestState state;
  CoglHandle tex;

  state.fb = shared_state->fb;
  state.width = cogl_framebuffer_get_width (shared_state->fb);
  state.height = cogl_framebuffer_get_height (shared_state->fb);

  state.offscreen = COGL_INVALID_HANDLE;

  state.texture = make_texture ();

  tex = cogl_texture_new_with_size (state.width, state.height,
                                    COGL_TEXTURE_NO_SLICING,
                                    COGL_PIXEL_FORMAT_ANY); /* internal fmt */
  state.offscreen = cogl_offscreen_new_to_texture (tex);
  state.offscreen_tex = tex;

  paint (&state);

  cogl_object_unref (state.offscreen);
  cogl_handle_unref (state.offscreen_tex);
  cogl_handle_unref (state.texture);

  if (g_test_verbose ())
    g_print ("OK\n");
}
Ejemplo n.º 4
0
void
test_color_mask (void)
{
  TestState state;
  int i;

  state.width = cogl_framebuffer_get_width (test_fb);
  state.height = cogl_framebuffer_get_height (test_fb);

  for (i = 0; i < NUM_FBOS; i++)
    {
      state.tex[i] = test_utils_texture_new_with_size (test_ctx, 128, 128,
                                                 TEST_UTILS_TEXTURE_NO_ATLAS,
                                                 COGL_PIXEL_FORMAT_RGB_888);


      state.fbo[i] = COGL_FRAMEBUFFER (
        cogl_offscreen_new_to_texture (state.tex[i]));

      /* Clear the texture color bits */
      cogl_framebuffer_clear4f (state.fbo[i],
                                COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);

      cogl_framebuffer_set_color_mask (state.fbo[i],
                                       i == 0 ? COGL_COLOR_MASK_RED :
                                       i == 1 ? COGL_COLOR_MASK_GREEN :
                                       COGL_COLOR_MASK_BLUE);
    }

  paint (&state);

  if (cogl_test_verbose ())
    g_print ("OK\n");
}
Ejemplo n.º 5
0
static void
create_gles2_context (CoglTexture **offscreen_texture,
                      CoglOffscreen **offscreen,
                      CoglPipeline **pipeline,
                      CoglGLES2Context **gles2_ctx,
                      const CoglGLES2Vtable **gles2)
{
  GError *error = NULL;

  *offscreen_texture = COGL_TEXTURE (
    cogl_texture_2d_new_with_size (test_ctx,
                                   cogl_framebuffer_get_width (test_fb),
                                   cogl_framebuffer_get_height (test_fb),
                                   COGL_PIXEL_FORMAT_ANY,
                                   NULL));
  *offscreen = cogl_offscreen_new_to_texture (*offscreen_texture);

  *pipeline = cogl_pipeline_new (test_ctx);
  cogl_pipeline_set_layer_texture (*pipeline, 0, *offscreen_texture);

  *gles2_ctx = cogl_gles2_context_new (test_ctx, NULL);
  if (!*gles2_ctx)
    g_error ("Failed to create GLES2 context: %s\n", error->message);

  *gles2 = cogl_gles2_context_get_vtable (*gles2_ctx);
}
Ejemplo n.º 6
0
CoglHandle
_st_create_shadow_material_from_actor (StShadow     *shadow_spec,
                                       ClutterActor *actor)
{
  CoglHandle shadow_material = COGL_INVALID_HANDLE;

  if (CLUTTER_IS_TEXTURE (actor))
    {
      CoglHandle texture;

      texture = clutter_texture_get_cogl_texture (CLUTTER_TEXTURE (actor));
      shadow_material = _st_create_shadow_material (shadow_spec, texture);
    }
  else
    {
      CoglHandle buffer, offscreen;
      ClutterActorBox box;
      CoglColor clear_color;
      float width, height;

      clutter_actor_get_allocation_box (actor, &box);
      clutter_actor_box_get_size (&box, &width, &height);

      if (width == 0 || height == 0)
        return COGL_INVALID_HANDLE;

      buffer = st_cogl_texture_new_with_size_wrapper (width, height,
                                                      COGL_TEXTURE_NO_SLICING,
                                                      COGL_PIXEL_FORMAT_ANY);

      if (buffer == COGL_INVALID_HANDLE)
        return COGL_INVALID_HANDLE;

      offscreen = cogl_offscreen_new_to_texture (buffer);

      if (offscreen == COGL_INVALID_HANDLE)
        {
          cogl_handle_unref (buffer);
          return COGL_INVALID_HANDLE;
        }

      cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
      cogl_push_framebuffer (offscreen);
      cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
      cogl_translate (-box.x1, -box.y1, 0);
      cogl_ortho (0, width, height, 0, 0, 1.0);
      clutter_actor_paint (actor);
      cogl_pop_framebuffer ();
      cogl_handle_unref (offscreen);

      shadow_material = _st_create_shadow_material (shadow_spec, buffer);

      cogl_handle_unref (buffer);
    }

  return shadow_material;
}
Ejemplo n.º 7
0
static void
st_background_effect_paint_target (ClutterOffscreenEffect *effect)
{
  StBackgroundEffect *self = ST_BACKGROUND_EFFECT (effect);

  if ((self->bg_texture != NULL) && (self->opacity == 0xff))
    {
      cogl_push_source (self->pipeline2);
      cogl_rectangle (0.0f, 0.0f, (self->fg_width_i), (self->fg_height_i));
      cogl_pop_source ();

      CoglOffscreen *vertical_FBO;
      vertical_FBO = cogl_offscreen_new_to_texture (self->bg_sub_texture);
      cogl_push_framebuffer ((CoglFramebuffer*)vertical_FBO);
      cogl_push_source (self->pipeline0);
      cogl_rectangle (-1.0f, 1.0f, 1.0f, -1.0f);
      cogl_pop_source ();
      cogl_pop_framebuffer ();
      cogl_handle_unref (vertical_FBO);

      cogl_pipeline_set_layer_texture (self->pipeline1, 0, self->bg_sub_texture);
      cogl_push_source (self->pipeline1);
      cogl_rectangle (4.0f, 4.0f, (self->bg_width_i) + 4.0f,
                      (self->bg_height_i) + 4.0f);
      cogl_pop_source ();

    }

  cogl_pipeline_set_color4ub (self->pipeline3,
                              0x00,
                              0x00,
                              0x00,
                              0x80);

  cogl_push_source (self->pipeline3);
  cogl_rectangle (0.0f, 0.0f, (self->fg_width_i), (self->fg_height_i));
  cogl_pop_source ();

  clutter_actor_queue_redraw (self->actor);

  cogl_pipeline_set_color4ub (self->pipeline4,
                              self->opacity,
                              self->opacity,
                              self->opacity,
                              self->opacity);

  cogl_push_source (self->pipeline4);
  cogl_rectangle (0.0f, 0.0f, (self->fg_width_i), (self->fg_height_i));
  cogl_pop_source ();

  clutter_actor_queue_redraw (self->actor);

}
Ejemplo n.º 8
0
static CoglHandle
data_to_cogl_handle (const guchar *data,
                     gboolean      has_alpha,
                     int           width,
                     int           height,
                     int           rowstride,
                     gboolean      add_padding)
{
    CoglHandle texture, offscreen;
    CoglColor clear_color;
    guint size;

    size = MAX (width, height);

    if (!add_padding || width == height)
        return cogl_texture_new_from_data (width,
                                           height,
                                           COGL_TEXTURE_NONE,
                                           has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
                                           COGL_PIXEL_FORMAT_ANY,
                                           rowstride,
                                           data);

    texture = cogl_texture_new_with_size (size, size,
                                          COGL_TEXTURE_NO_SLICING,
                                          COGL_PIXEL_FORMAT_ANY);

    offscreen = cogl_offscreen_new_to_texture (texture);
    cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
    cogl_push_framebuffer (offscreen);
    cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
    cogl_pop_framebuffer ();
    cogl_handle_unref (offscreen);

    cogl_texture_set_region (texture,
                             0, 0,
                             (size - width) / 2, (size - height) / 2,
                             width, height,
                             width, height,
                             has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
                             rowstride,
                             data);
    return texture;
}
static CoglHandle
pixbuf_to_cogl_handle (GdkPixbuf *pixbuf,
                       gboolean   add_padding)
{
  CoglHandle texture, offscreen;
  CoglColor clear_color;
  int width, height;
  guint size;

  width = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);
  size = MAX (width, height);

  if (!add_padding || width == height)
    return cogl_texture_new_from_data (width,
                                       height,
                                       COGL_TEXTURE_NONE,
                                       gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
                                       COGL_PIXEL_FORMAT_ANY,
                                       gdk_pixbuf_get_rowstride (pixbuf),
                                       gdk_pixbuf_get_pixels (pixbuf));

  texture = cogl_texture_new_with_size (size, size,
                                        COGL_TEXTURE_NO_SLICING,
                                        COGL_PIXEL_FORMAT_ANY);

  offscreen = cogl_offscreen_new_to_texture (texture);
  cogl_color_set_from_4ub (&clear_color, 0, 0, 0, 0);
  cogl_push_framebuffer (offscreen);
  cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
  cogl_pop_framebuffer ();
  cogl_handle_unref (offscreen);

  cogl_texture_set_region (texture,
                           0, 0,
                           (size - width) / 2, (size - height) / 2,
                           width, height,
                           width, height,
                           gdk_pixbuf_get_has_alpha (pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
                           gdk_pixbuf_get_rowstride (pixbuf),
                           gdk_pixbuf_get_pixels (pixbuf));
  return texture;
}
Ejemplo n.º 10
0
void
test_cogl_color_mask (TestUtilsGTestFixture *fixture,
                      void *data)
{
  TestUtilsSharedState *shared_state = data;
  TestState state;
  CoglColor bg;
  int i;

  state.width = cogl_framebuffer_get_width (shared_state->fb);
  state.height = cogl_framebuffer_get_height (shared_state->fb);

  cogl_color_init_from_4ub (&bg, 0, 0, 0, 255);

  for (i = 0; i < NUM_FBOS; i++)
    {
      state.tex[i] = cogl_texture_new_with_size (128, 128,
                                                 COGL_TEXTURE_NO_ATLAS,
                                                 COGL_PIXEL_FORMAT_RGB_888);


      state.fbo[i] = cogl_offscreen_new_to_texture (state.tex[i]);

      /* Clear the texture color bits */
      cogl_push_framebuffer (state.fbo[i]);
      cogl_clear (&bg, COGL_BUFFER_BIT_COLOR);
      cogl_pop_framebuffer ();

      cogl_framebuffer_set_color_mask (state.fbo[i],
                                       i == 0 ? COGL_COLOR_MASK_RED :
                                       i == 1 ? COGL_COLOR_MASK_GREEN :
                                       COGL_COLOR_MASK_BLUE);
    }

  paint (&state);

  if (g_test_verbose ())
    g_print ("OK\n");
}
Ejemplo n.º 11
0
Archivo: msaa.c Proyecto: jsdir/_
int
main (int argc, char **argv)
{
    CoglOnscreenTemplate *onscreen_template;
    CoglDisplay *display;
    CoglContext *ctx;
    CoglOnscreen *onscreen;
    CoglFramebuffer *fb;
    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}
    };
    CoglPrimitive *triangle;
    CoglTexture *tex;
    CoglOffscreen *offscreen;
    CoglFramebuffer *offscreen_fb;
    CoglPipeline *pipeline;

    onscreen_template = cogl_onscreen_template_new (NULL);
    cogl_onscreen_template_set_samples_per_pixel (onscreen_template, 4);
    display = cogl_display_new (NULL, onscreen_template);

    if (!cogl_display_setup (display, &error))
      {
        fprintf (stderr, "Platform doesn't support onscreen 4x msaa rendering: %s\n",
                 error->message);
        return 1;
      }

    ctx = cogl_context_new (display, &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);

    cogl_framebuffer_set_samples_per_pixel (fb, 4);

    if (!cogl_framebuffer_allocate (fb, &error))
      {
        fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, "
                 "disabling msaa for onscreen rendering: %s\n", error->message);
        cogl_error_free (error);
        cogl_framebuffer_set_samples_per_pixel (fb, 0);

        error = NULL;
        if (!cogl_framebuffer_allocate (fb, &error))
          {
            fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message);
            return 1;
          }
      }

    cogl_onscreen_show (onscreen);

    tex = cogl_texture_new_with_size (ctx,
                                      320, 480,
                                      COGL_TEXTURE_NO_SLICING,
                                      COGL_PIXEL_FORMAT_ANY);
    offscreen = cogl_offscreen_new_to_texture (tex);
    offscreen_fb = COGL_FRAMEBUFFER (offscreen);
    cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 4);
    if (!cogl_framebuffer_allocate (offscreen_fb, &error))
      {
        cogl_error_free (error);
        error = NULL;
        fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, "
                 "disabling msaa for offscreen rendering");
        cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 0);
      }

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

    for (;;) {
        CoglPollFD *poll_fds;
        int n_poll_fds;
        int64_t timeout;
        CoglPipeline *texture_pipeline;

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

        cogl_framebuffer_push_matrix (fb);
        cogl_framebuffer_scale (fb, 0.5, 1, 1);
        cogl_framebuffer_translate (fb, -1, 0, 0);
        cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
        cogl_framebuffer_pop_matrix (fb);

        cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
        cogl_framebuffer_resolve_samples (offscreen_fb);

        texture_pipeline = cogl_pipeline_new (ctx);
        cogl_pipeline_set_layer_texture (texture_pipeline, 0, tex);
        cogl_framebuffer_draw_rectangle (fb, texture_pipeline, 0, 1, 1, -1);
        cogl_object_unref (texture_pipeline);

        cogl_onscreen_swap_buffers (onscreen);

        cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
        g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
        cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
    }

    return 0;
}
Ejemplo n.º 12
0
static gboolean
setup_framebuffers (StThemeNodeTransition *transition,
                    const ClutterActorBox *allocation)
{
  StThemeNodeTransitionPrivate *priv = transition->priv;
  CoglColor clear_color = { 0, 0, 0, 0 };
  guint width, height;

  /* template material to avoid unnecessary shader compilation */
  static CoglHandle material_template = COGL_INVALID_HANDLE;

  width  = priv->offscreen_box.x2 - priv->offscreen_box.x1;
  height = priv->offscreen_box.y2 - priv->offscreen_box.y1;

  g_return_val_if_fail (width  > 0, FALSE);
  g_return_val_if_fail (height > 0, FALSE);

  if (priv->old_texture)
    cogl_handle_unref (priv->old_texture);
  priv->old_texture = cogl_texture_new_with_size (width, height,
                                                  COGL_TEXTURE_NO_SLICING,
                                                  COGL_PIXEL_FORMAT_ANY);

  if (priv->new_texture)
    cogl_handle_unref (priv->new_texture);
  priv->new_texture = cogl_texture_new_with_size (width, height,
                                                  COGL_TEXTURE_NO_SLICING,
                                                  COGL_PIXEL_FORMAT_ANY);

  g_return_val_if_fail (priv->old_texture != COGL_INVALID_HANDLE, FALSE);
  g_return_val_if_fail (priv->new_texture != COGL_INVALID_HANDLE, FALSE);

  if (priv->old_offscreen)
    cogl_handle_unref (priv->old_offscreen);
  priv->old_offscreen = cogl_offscreen_new_to_texture (priv->old_texture);

  if (priv->new_offscreen)
    cogl_handle_unref (priv->new_offscreen);
  priv->new_offscreen = cogl_offscreen_new_to_texture (priv->new_texture);

  g_return_val_if_fail (priv->old_offscreen != COGL_INVALID_HANDLE, FALSE);
  g_return_val_if_fail (priv->new_offscreen != COGL_INVALID_HANDLE, FALSE);

  if (priv->material == NULL)
    {
      if (G_UNLIKELY (material_template == COGL_INVALID_HANDLE))
        {
          material_template = cogl_material_new ();

          cogl_material_set_layer_combine (material_template, 0,
                                           "RGBA = REPLACE (TEXTURE)",
                                           NULL);
          cogl_material_set_layer_combine (material_template, 1,
                                           "RGBA = INTERPOLATE (PREVIOUS, "
                                                               "TEXTURE, "
                                                               "CONSTANT[A])",
                                           NULL);
          cogl_material_set_layer_combine (material_template, 2,
                                           "RGBA = MODULATE (PREVIOUS, "
                                                            "PRIMARY)",
                                           NULL);
        }
      priv->material = cogl_material_copy (material_template);
    }

  cogl_material_set_layer (priv->material, 0, priv->new_texture);
  cogl_material_set_layer (priv->material, 1, priv->old_texture);

  cogl_push_framebuffer (priv->old_offscreen);
  cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
  cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2,
              priv->offscreen_box.y2, priv->offscreen_box.y1,
              0.0, 1.0);
  st_theme_node_paint (priv->old_theme_node, allocation, 255);
  cogl_pop_framebuffer ();

  cogl_push_framebuffer (priv->new_offscreen);
  cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR);
  cogl_ortho (priv->offscreen_box.x1, priv->offscreen_box.x2,
              priv->offscreen_box.y2, priv->offscreen_box.y1,
              0.0, 1.0);
  st_theme_node_paint (priv->new_theme_node, allocation, 255);
  cogl_pop_framebuffer ();

  return TRUE;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
CoglTexture *
rut_gaussian_blurrer_blur (RutGaussianBlurrer *blurrer,
                           CoglTexture *source)
{
  unsigned int src_w, src_h;
  CoglPixelFormat format;
  CoglOffscreen *offscreen;

  /* create the first FBO to render the x pass */
  src_w = cogl_texture_get_width (source);
  src_h = cogl_texture_get_height (source);
  format = cogl_texture_get_format (source);

  if (blurrer->width != src_w ||
      blurrer->height != src_h ||
      blurrer->format != format)
    {
      _rut_gaussian_blurrer_free_buffers (blurrer);
    }

  if (!blurrer->x_pass)
    {
      CoglError *error = NULL;
      CoglTexture2D *texture_2d =
        cogl_texture_2d_new_with_size (blurrer->ctx->cogl_context,
                                       src_w,
                                       src_h,
                                       format);
      if (error)
        {
          g_warning ("blurrer: could not create x pass texture: %s",
                     error->message);
        }
      blurrer->x_pass = COGL_TEXTURE (texture_2d);
      blurrer->width = src_w;
      blurrer->height = src_h;
      blurrer->format = format;

      offscreen = cogl_offscreen_new_to_texture (blurrer->x_pass);
      blurrer->x_pass_fb = COGL_FRAMEBUFFER (offscreen);
      cogl_framebuffer_orthographic (blurrer->x_pass_fb,
                                     0, 0, src_w, src_h, -1, 100);
    }

  if (!blurrer->y_pass)
    {
      /* create the second FBO (final destination) to render the y pass */
      CoglTexture2D *texture_2d =
        cogl_texture_2d_new_with_size (blurrer->ctx->cogl_context,
                                       src_w,
                                       src_h,
                                       format);
      blurrer->destination = COGL_TEXTURE (texture_2d);
      blurrer->y_pass = blurrer->destination;

      offscreen = cogl_offscreen_new_to_texture (blurrer->destination);
      blurrer->y_pass_fb = COGL_FRAMEBUFFER (offscreen);
      cogl_framebuffer_orthographic (blurrer->y_pass_fb,
                                     0, 0, src_w, src_h, -1, 100);
    }

  set_blurrer_pipeline_texture (blurrer->x_pass_pipeline,
                                source, 1.0f / src_w, 0);
  set_blurrer_pipeline_texture (blurrer->y_pass_pipeline,
                                blurrer->x_pass, 0, 1.0f / src_h);

  /* x pass */
  cogl_framebuffer_draw_rectangle (blurrer->x_pass_fb,
                                   blurrer->x_pass_pipeline,
                                   0,
                                   0,
                                   blurrer->width,
                                   blurrer->height);

  /* y pass */
  cogl_framebuffer_draw_rectangle (blurrer->y_pass_fb,
                                   blurrer->y_pass_pipeline,
                                   0,
                                   0,
                                   blurrer->width,
                                   blurrer->height);

  return cogl_object_ref (blurrer->destination);
}
Ejemplo n.º 15
0
static void
on_paint (ClutterActor *actor, void *state)
{
  float saved_viewport[4];
  CoglMatrix saved_projection;
  CoglMatrix projection;
  CoglMatrix modelview;
  guchar *data;
  CoglHandle tex;
  CoglHandle offscreen;
  CoglColor black;
  float x0;
  float y0;
  float width;
  float height;

  /* for clearing the offscreen framebuffer to black... */
  cogl_color_init_from_4ub (&black, 0x00, 0x00, 0x00, 0xff);

  cogl_get_viewport (saved_viewport);
  cogl_get_projection_matrix (&saved_projection);
  cogl_push_matrix ();

  cogl_matrix_init_identity (&projection);
  cogl_matrix_init_identity (&modelview);

  cogl_set_projection_matrix (&projection);
  cogl_set_modelview_matrix (&modelview);

  /* - Create a 100x200 viewport (i.e. smaller than the onscreen framebuffer)
   *   and position it a (20, 10) inside the framebuffer.
   * - Fill the whole viewport with a purple rectangle
   * - Verify that the framebuffer is black with a 100x200 purple rectangle at
   *   (20, 10)
   */
  cogl_set_viewport (20, /* x */
                     10, /* y */
                     100, /* width */
                     200); /* height */
  /* clear everything... */
  cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
  /* fill the viewport with purple.. */
  cogl_set_source_color4ub (0xff, 0x00, 0xff, 0xff);
  cogl_rectangle (-1, 1, 1, -1);
  assert_rectangle_color_and_black_border (20, 10, 100, 200,
                                           0xff, 0x00, 0xff);


  /* - Create a viewport twice the size of the onscreen framebuffer with
   *   a negative offset positioning it at (-20, -10) relative to the
   *   buffer itself.
   * - Draw a 100x200 green rectangle at (40, 20) within the viewport (which
   *   is (20, 10) within the framebuffer)
   * - Verify that the framebuffer is black with a 100x200 green rectangle at
   *   (20, 10)
   */
  cogl_set_viewport (-20, /* x */
                     -10, /* y */
                     FRAMEBUFFER_WIDTH * 2, /* width */
                     FRAMEBUFFER_HEIGHT * 2); /* height */
  /* clear everything... */
  cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
  /* draw a 100x200 green rectangle offset into the viewport such that its
   * top left corner should be found at (20, 10) in the offscreen buffer */
  /* (offset 40 pixels right from the left of the viewport) */
  x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f;
  /* (offset 20 pixels down from the top of the viewport) */
  y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f;
  width = (1.0f / FRAMEBUFFER_WIDTH) * 100;
  height = (1.0f / FRAMEBUFFER_HEIGHT) * 200;
  cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
  cogl_rectangle (x0, y0, x0 + width, y0 - height);
  assert_rectangle_color_and_black_border (20, 10, 100, 200,
                                           0x00, 0xff, 0x00);


  /* - Create a 200x400 viewport and position it a (20, 10) inside the draw
   *   buffer.
   * - Push a 100x200 window space clip rectangle at (20, 10)
   * - Fill the whole viewport with a blue rectangle
   * - Verify that the framebuffer is black with a 100x200 blue rectangle at
   *   (20, 10)
   */
  cogl_set_viewport (20, /* x */
                     10, /* y */
                     200, /* width */
                     400); /* height */
  /* clear everything... */
  cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
  cogl_clip_push_window_rectangle (20, 10, 100, 200);
  /* fill the viewport with blue.. */
  cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
  cogl_rectangle (-1, 1, 1, -1);
  cogl_clip_pop ();
  assert_rectangle_color_and_black_border (20, 10, 100, 200,
                                           0x00, 0x00, 0xff);


  /* - Create a 200x400 viewport and position it a (20, 10) inside the draw
   *   buffer.
   * - Push a 100x200 model space clip rectangle at (20, 10) in the viewport
   *   (i.e. (40, 20) inside the framebuffer)
   * - Fill the whole viewport with a green rectangle
   * - Verify that the framebuffer is black with a 100x200 green rectangle at
   *   (40, 20)
   */
  cogl_set_viewport (20, /* x */
                     10, /* y */
                     200, /* width */
                     400); /* height */
  /* clear everything... */
  cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
  /* figure out where to position our clip rectangle in model space
   * coordinates... */
  /* (offset 40 pixels right from the left of the viewport) */
  x0 = -1.0f + (2.0f / 200) * 20.f;
  /* (offset 20 pixels down from the top of the viewport) */
  y0 = 1.0f - (2.0f / 400) * 10.0f;
  width = (2.0f / 200) * 100;
  height = (2.0f / 400) * 200;
  /* add the clip rectangle... */
  cogl_push_matrix ();
  cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0);
  /* XXX: Rotate just enough to stop Cogl from converting our model space
   * rectangle into a window space rectangle.. */
  cogl_rotate (0.1, 0, 0, 1);
  cogl_clip_push_rectangle (-(width/2.0), -(height/2.0),
                            width/2.0, height/2.0);
  cogl_pop_matrix ();
  /* fill the viewport with green.. */
  cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
  cogl_rectangle (-1, 1, 1, -1);
  cogl_clip_pop ();
  assert_rectangle_color_and_black_border (40, 20, 100, 200,
                                           0x00, 0xff, 0x00);


  /* Set the viewport to something specific so we can verify that it gets
   * restored after we are done testing with an offscreen framebuffer... */
  cogl_set_viewport (20, 10, 100, 200);

  /*
   * Next test offscreen drawing...
   */
  data = g_malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
  tex = cogl_texture_new_from_data (FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
                                    COGL_TEXTURE_NO_SLICING,
                                    COGL_PIXEL_FORMAT_RGBA_8888, /* data fmt */
                                    COGL_PIXEL_FORMAT_ANY, /* internal fmt */
                                    FRAMEBUFFER_WIDTH * 4, /* rowstride */
                                    data);
  g_free (data);
  offscreen = cogl_offscreen_new_to_texture (tex);

  cogl_push_framebuffer (offscreen);


  /* - Create a 100x200 viewport (i.e. smaller than the offscreen framebuffer)
   *   and position it a (20, 10) inside the framebuffer.
   * - Fill the whole viewport with a blue rectangle
   * - Verify that the framebuffer is black with a 100x200 blue rectangle at
   *   (20, 10)
   */
  cogl_set_viewport (20, /* x */
                     10, /* y */
                     100, /* width */
                     200); /* height */
  /* clear everything... */
  cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
  /* fill the viewport with blue.. */
  cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
  cogl_rectangle (-1, 1, 1, -1);
  assert_rectangle_color_and_black_border (20, 10, 100, 200,
                                           0x00, 0x00, 0xff);


  /* - Create a viewport twice the size of the offscreen framebuffer with
   *   a negative offset positioning it at (-20, -10) relative to the
   *   buffer itself.
   * - Draw a 100x200 red rectangle at (40, 20) within the viewport (which
   *   is (20, 10) within the framebuffer)
   * - Verify that the framebuffer is black with a 100x200 red rectangle at
   *   (20, 10)
   */
  cogl_set_viewport (-20, /* x */
                     -10, /* y */
                     FRAMEBUFFER_WIDTH * 2, /* width */
                     FRAMEBUFFER_HEIGHT * 2); /* height */
  /* clear everything... */
  cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
  /* draw a 100x200 red rectangle offset into the viewport such that its
   * top left corner should be found at (20, 10) in the offscreen buffer */
  /* (offset 40 pixels right from the left of the viewport) */
  x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f;
  /* (offset 20 pixels down from the top of the viewport) */
  y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f;
  width = (1.0f / FRAMEBUFFER_WIDTH) * 100;
  height = (1.0f / FRAMEBUFFER_HEIGHT) * 200;
  cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
  cogl_rectangle (x0, y0, x0 + width, y0 - height);
  assert_rectangle_color_and_black_border (20, 10, 100, 200,
                                           0xff, 0x00, 0x00);


  /* - Create a 200x400 viewport and position it a (20, 10) inside the draw
   *   buffer.
   * - Push a 100x200 window space clip rectangle at (20, 10)
   * - Fill the whole viewport with a blue rectangle
   * - Verify that the framebuffer is black with a 100x200 blue rectangle at
   *   (20, 10)
   */
  cogl_set_viewport (20, /* x */
                     10, /* y */
                     200, /* width */
                     400); /* height */
  /* clear everything... */
  cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
  cogl_clip_push_window_rectangle (20, 10, 100, 200);
  /* fill the viewport with blue.. */
  cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
  cogl_rectangle (-1, 1, 1, -1);
  cogl_clip_pop ();
  assert_rectangle_color_and_black_border (20, 10, 100, 200,
                                           0x00, 0x00, 0xff);


  /* - Create a 200x400 viewport and position it a (20, 10) inside the draw
   *   buffer.
   * - Push a 100x200 model space clip rectangle at (20, 10) in the viewport
   *   (i.e. (40, 20) inside the framebuffer)
   * - Fill the whole viewport with a green rectangle
   * - Verify that the framebuffer is black with a 100x200 green rectangle at
   *   (40, 20)
   */
  cogl_set_viewport (20, /* x */
                     10, /* y */
                     200, /* width */
                     400); /* height */
  /* clear everything... */
  cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
  /* figure out where to position our clip rectangle in model space
   * coordinates... */
  /* (offset 40 pixels right from the left of the viewport) */
  x0 = -1.0f + (2.0f / 200) * 20.f;
  /* (offset 20 pixels down from the top of the viewport) */
  y0 = 1.0f - (2.0f / 400) * 10.0f;
  width = (2.0f / 200) * 100;
  height = (2.0f / 400) * 200;
  /* add the clip rectangle... */
  cogl_push_matrix ();
  cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0);
  /* XXX: Rotate just enough to stop Cogl from converting our model space
   * rectangle into a window space rectangle.. */
  cogl_rotate (0.1, 0, 0, 1);
  cogl_clip_push_rectangle (-(width/2.0), -(height/2.0),
                            width/2, height/2);
  cogl_pop_matrix ();
  /* fill the viewport with green.. */
  cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
  cogl_rectangle (-1, 1, 1, -1);
  cogl_clip_pop ();
  assert_rectangle_color_and_black_border (40, 20, 100, 200,
                                           0x00, 0xff, 0x00);


  /* Set the viewport to something obscure to verify that it gets
   * replace when we switch back to the onscreen framebuffer... */
  cogl_set_viewport (0, 0, 10, 10);

  cogl_pop_framebuffer ();
  cogl_handle_unref (offscreen);

  /*
   * Verify that the previous onscreen framebuffer's viewport was restored
   * by drawing a white rectangle across the whole viewport. This should
   * draw a 100x200 rectangle at (20,10) relative to the onscreen draw
   * buffer...
   */
  cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
  cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
  cogl_rectangle (-1, 1, 1, -1);
  assert_rectangle_color_and_black_border (20, 10, 100, 200,
                                           0xff, 0xff, 0xff);


  /* Uncomment to display the last contents of the offscreen framebuffer */
#if 1
  cogl_matrix_init_identity (&projection);
  cogl_matrix_init_identity (&modelview);
  cogl_set_viewport (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
  cogl_set_projection_matrix (&projection);
  cogl_set_modelview_matrix (&modelview);
  cogl_set_source_texture (tex);
  cogl_rectangle (-1, 1, 1, -1);
#endif

  cogl_handle_unref (tex);

  /* Finally restore the stage's original state... */
  cogl_pop_matrix ();
  cogl_set_projection_matrix (&saved_projection);
  cogl_set_viewport (saved_viewport[0], saved_viewport[1],
                     saved_viewport[2], saved_viewport[3]);


  /* Comment this out if you want visual feedback of what this test
   * paints.
   */
  clutter_main_quit ();
}
Ejemplo n.º 16
0
static void
test_push_pop_single_context (void)
{
  CoglTexture *offscreen_texture;
  CoglOffscreen *offscreen;
  CoglPipeline *pipeline;
  CoglGLES2Context *gles2_ctx;
  const CoglGLES2Vtable *gles2;
  GError *error = NULL;

  offscreen_texture = COGL_TEXTURE (
    cogl_texture_2d_new_with_size (test_ctx,
                                   cogl_framebuffer_get_width (test_fb),
                                   cogl_framebuffer_get_height (test_fb),
                                   COGL_PIXEL_FORMAT_ANY,
                                   NULL));
  offscreen = cogl_offscreen_new_to_texture (offscreen_texture);

  pipeline = cogl_pipeline_new (test_ctx);
  cogl_pipeline_set_layer_texture (pipeline, 0, offscreen_texture);

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

  gles2 = cogl_gles2_context_get_vtable (gles2_ctx);

  /* Clear onscreen to 0xffff00 using GLES2 */

  if (!cogl_push_gles2_context (test_ctx,
                                gles2_ctx,
                                test_fb,
                                test_fb,
                                &error))
    {
      g_error ("Failed to push gles2 context: %s\n", error->message);
    }

  gles2->glClearColor (1, 1, 0, 1);
  gles2->glClear (GL_COLOR_BUFFER_BIT);

  cogl_pop_gles2_context (test_ctx);

  test_utils_check_pixel (test_fb, 0, 0, 0xffff00ff);

  /* Clear offscreen to 0xff0000 using GLES2 and then copy the result
   * onscreen.
   *
   * If we fail to bind the new context here then we'd probably end up
   * clearing onscreen to 0xff0000 and copying 0xffff00 to onscreen
   * instead.
   */

  if (!cogl_push_gles2_context (test_ctx,
                                gles2_ctx,
                                COGL_FRAMEBUFFER (offscreen),
                                COGL_FRAMEBUFFER (offscreen),
                                &error))
    {
      g_error ("Failed to push gles2 context: %s\n", error->message);
    }

  gles2->glClearColor (1, 0, 0, 1);
  gles2->glClear (GL_COLOR_BUFFER_BIT);

  cogl_pop_gles2_context (test_ctx);

  cogl_framebuffer_draw_rectangle (test_fb,
                                   pipeline,
                                   -1, 1, 1, -1);
  /* NB: Cogl doesn't automatically support mid-scene modifications
   * of textures and so we explicitly flush the drawn rectangle to the
   * framebuffer now otherwise it may be batched until after the
   * offscreen texture has been modified again. */
  cogl_flush ();

  /* Clear the offscreen framebuffer to blue using GLES2 before
   * reading back from the onscreen framebuffer in case we mistakenly
   * read from the offscreen framebuffer and get a false positive
   */
  if (!cogl_push_gles2_context (test_ctx,
                                gles2_ctx,
                                COGL_FRAMEBUFFER (offscreen),
                                COGL_FRAMEBUFFER (offscreen),
                                &error))
    {
      g_error ("Failed to push gles2 context: %s\n", error->message);
    }

  gles2->glClearColor (0, 0, 1, 1);
  gles2->glClear (GL_COLOR_BUFFER_BIT);

  cogl_pop_gles2_context (test_ctx);

  test_utils_check_pixel (test_fb, 0, 0, 0xff0000ff);

  /* Now copy the offscreen blue clear to the onscreen framebufer and
   * check that too */
  cogl_framebuffer_draw_rectangle (test_fb,
                                   pipeline,
                                   -1, 1, 1, -1);

  test_utils_check_pixel (test_fb, 0, 0, 0x0000ffff);

  if (!cogl_push_gles2_context (test_ctx,
                                gles2_ctx,
                                test_fb,
                                test_fb,
                                &error))
    {
      g_error ("Failed to push gles2 context: %s\n", error->message);
    }

  gles2->glClearColor (1, 0, 1, 1);
  gles2->glClear (GL_COLOR_BUFFER_BIT);

  cogl_pop_gles2_context (test_ctx);

  test_utils_check_pixel (test_fb, 0, 0, 0xff00ffff);


  cogl_object_unref (gles2_ctx);

  cogl_object_unref (pipeline);
}