示例#1
0
文件: cogl.c 项目: collinss/muffin
void
cogl_begin_gl (void)
{
  CoglPipeline *pipeline;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  if (ctx->in_begin_gl_block)
    {
      static CoglBool shown = FALSE;
      if (!shown)
        g_warning ("You should not nest cogl_begin_gl/cogl_end_gl blocks");
      shown = TRUE;
      return;
    }
  ctx->in_begin_gl_block = TRUE;

  /* Flush all batched primitives */
  cogl_flush ();

  /* Flush framebuffer state, including clip state, modelview and
   * projection matrix state
   *
   * NB: _cogl_framebuffer_flush_state may disrupt various state (such
   * as the pipeline state) when flushing the clip stack, so should
   * always be done first when preparing to draw. */
  _cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (),
                                 _cogl_get_read_framebuffer (),
                                 COGL_FRAMEBUFFER_STATE_ALL);

  /* Setup the state for the current pipeline */

  /* We considered flushing a specific, minimal pipeline here to try and
   * simplify the GL state, but decided to avoid special cases and second
   * guessing what would be actually helpful.
   *
   * A user should instead call cogl_set_source_color4ub() before
   * cogl_begin_gl() to simplify the state flushed.
   *
   * XXX: note defining n_tex_coord_attribs using
   * cogl_pipeline_get_n_layers is a hack, but the problem is that
   * n_tex_coord_attribs is usually defined when drawing a primitive
   * which isn't happening here.
   *
   * Maybe it would be more useful if this code did flush the
   * opaque_color_pipeline and then call into cogl-pipeline-opengl.c to then
   * restore all state for the material's backend back to default OpenGL
   * values.
   */
  pipeline = cogl_get_source ();
  _cogl_pipeline_flush_gl_state (ctx,
                                 pipeline,
                                 cogl_get_draw_framebuffer (),
                                 FALSE,
                                 FALSE);

  /* Disable any cached vertex arrays */
  _cogl_gl_disable_all_attributes (ctx);
}
示例#2
0
static void _capture_desktop(MetaSwitcher* self)
{
    MetaSwitcherPrivate* priv = self->priv;
    MetaScreen* screen = meta_plugin_get_screen(priv->plugin);
    ClutterActor* stage = meta_get_stage_for_screen(screen);

    gfloat tx, ty, w, h;
    clutter_actor_get_position(priv->top, &tx, &ty);
    clutter_actor_get_size(priv->top, &w, &h);

    g_debug("%s: %f, %f, %f, %f", __func__, tx, ty, w, h);
    if (priv->snapshot) {
        cairo_surface_destroy(priv->snapshot);
        priv->snapshot = NULL;
    }
    priv->snapshot_offset = 20.0;
    w += priv->snapshot_offset*3;
    clutter_stage_ensure_redraw(CLUTTER_STAGE(stage));

    guchar* data = g_malloc(w*h*4);
    cogl_framebuffer_read_pixels(cogl_get_draw_framebuffer(),
            tx-priv->snapshot_offset, ty, w, h,
            CLUTTER_CAIRO_FORMAT_ARGB32, data);

    /*guchar* data = clutter_stage_read_pixels(CLUTTER_STAGE(stage), */
            /*tx-priv->snapshot_offset, ty, w, h);*/
    priv->snapshot = cairo_image_surface_create_for_data(data,
            CAIRO_FORMAT_ARGB32, w, h, w*4);
    g_free(data);
}
示例#3
0
static void
_cogl_path_fill_nodes_with_clipped_rectangle (CoglPath *path)
{
  CoglFramebuffer *fb;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  if (!(ctx->private_feature_flags & COGL_PRIVATE_FEATURE_STENCIL_BUFFER))
    {
      static gboolean seen_warning = FALSE;

      if (!seen_warning)
        {
          g_warning ("Paths can not be filled using materials with "
                     "sliced textures unless there is a stencil "
                     "buffer");
          seen_warning = TRUE;
        }
    }

  fb = cogl_get_draw_framebuffer ();
  cogl_framebuffer_push_path_clip (fb, path);
  cogl_rectangle (path->data->path_nodes_min.x,
                  path->data->path_nodes_min.y,
                  path->data->path_nodes_max.x,
                  path->data->path_nodes_max.y);
  cogl_framebuffer_pop_clip (fb);
}
示例#4
0
void
_cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags)
{
  gboolean needs_fallback = FALSE;
  CoglPipeline *pipeline = cogl_get_source ();

  _cogl_pipeline_foreach_layer_internal (pipeline,
                                         validate_layer_cb, &needs_fallback);
  if (needs_fallback)
    {
      _cogl_path_fill_nodes_with_clipped_rectangle (path);
      return;
    }

  _cogl_path_build_fill_attribute_buffer (path);

  _cogl_framebuffer_draw_indexed_attributes (cogl_get_draw_framebuffer (),
                                             pipeline,
                                             COGL_VERTICES_MODE_TRIANGLES,
                                             0, /* first_vertex */
                                             path->data->fill_vbo_n_indices,
                                             path->data->fill_vbo_indices,
                                             path->data->fill_attributes,
                                             COGL_PATH_N_ATTRIBUTES,
                                             flags);
}
示例#5
0
void
_st_paint_shadow_with_opacity (StShadow        *shadow_spec,
                               CoglPipeline    *shadow_pipeline,
                               ClutterActorBox *box,
                               guint8           paint_opacity)
{
    CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
    ClutterActorBox shadow_box;
    CoglColor color;

    g_return_if_fail (shadow_spec != NULL);
    g_return_if_fail (shadow_pipeline != NULL);

    st_shadow_get_box (shadow_spec, box, &shadow_box);

    cogl_color_init_from_4ub (&color,
                              shadow_spec->color.red   * paint_opacity / 255,
                              shadow_spec->color.green * paint_opacity / 255,
                              shadow_spec->color.blue  * paint_opacity / 255,
                              shadow_spec->color.alpha * paint_opacity / 255);
    cogl_color_premultiply (&color);
    cogl_pipeline_set_layer_combine_constant (shadow_pipeline, 0, &color);
    cogl_framebuffer_draw_rectangle (fb, shadow_pipeline,
                                     shadow_box.x1, shadow_box.y1,
                                     shadow_box.x2, shadow_box.y2);
}
示例#6
0
文件: cogl.c 项目: collects/cogl
CoglClipState *
_cogl_get_clip_state (void)
{
    CoglFramebuffer *framebuffer;

    framebuffer = cogl_get_draw_framebuffer ();
    return _cogl_framebuffer_get_clip_state (framebuffer);
}
示例#7
0
static void
meta_surface_actor_pick (ClutterActor       *actor,
                         const ClutterColor *color)
{
  MetaSurfaceActor *self = META_SURFACE_ACTOR (actor);
  MetaSurfaceActorPrivate *priv =
    meta_surface_actor_get_instance_private (self);
  ClutterActorIter iter;
  ClutterActor *child;

  if (!clutter_actor_should_pick_paint (actor))
    return;

  /* If there is no region then use the regular pick */
  if (priv->input_region == NULL)
    CLUTTER_ACTOR_CLASS (meta_surface_actor_parent_class)->pick (actor, color);
  else
    {
      int n_rects;
      float *rectangles;
      int i;
      CoglPipeline *pipeline;
      CoglContext *ctx;
      CoglFramebuffer *fb;
      CoglColor cogl_color;

      n_rects = cairo_region_num_rectangles (priv->input_region);
      rectangles = g_alloca (sizeof (float) * 4 * n_rects);

      for (i = 0; i < n_rects; i++)
        {
          cairo_rectangle_int_t rect;
          int pos = i * 4;

          cairo_region_get_rectangle (priv->input_region, i, &rect);

          rectangles[pos + 0] = rect.x;
          rectangles[pos + 1] = rect.y;
          rectangles[pos + 2] = rect.x + rect.width;
          rectangles[pos + 3] = rect.y + rect.height;
        }

      ctx = clutter_backend_get_cogl_context (clutter_get_default_backend ());
      fb = cogl_get_draw_framebuffer ();

      cogl_color_init_from_4ub (&cogl_color, color->red, color->green, color->blue, color->alpha);

      pipeline = cogl_pipeline_new (ctx);
      cogl_pipeline_set_color (pipeline, &cogl_color);
      cogl_framebuffer_draw_rectangles (fb, pipeline, rectangles, n_rects);
      cogl_object_unref (pipeline);
    }

  clutter_actor_iter_init (&iter, actor);

  while (clutter_actor_iter_next (&iter, &child))
    clutter_actor_paint (child);
}
示例#8
0
文件: cogl.c 项目: collinss/muffin
void
cogl_perspective (float fov_y,
		  float aspect,
		  float z_near,
		  float z_far)
{
  cogl_framebuffer_perspective (cogl_get_draw_framebuffer (),
                                fov_y, aspect, z_near, z_far);
}
示例#9
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;
    }
}
示例#10
0
/* TODO: Update to the protoype used in the Cogl master branch.
 * This is experimental API but not in sync with the cogl_path_fill()
 * api in Cogl master which takes explicit framebuffer and pipeline
 * arguments */
void
cogl2_path_fill (CoglPath *path)
{
  _COGL_RETURN_IF_FAIL (cogl_is_path (path));

  _cogl_path_fill_nodes (path,
                         cogl_get_draw_framebuffer (),
                         cogl_get_source (),
                         0 /* flags */);
}
示例#11
0
文件: cogl.c 项目: collinss/muffin
/* XXX: This function should either be replaced with one returning
 * integers, or removed/deprecated and make the
 * _cogl_framebuffer_get_viewport* functions public.
 */
void
cogl_get_viewport (float viewport[4])
{
  CoglFramebuffer *framebuffer;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  framebuffer = cogl_get_draw_framebuffer ();
  cogl_framebuffer_get_viewport4fv (framebuffer, viewport);
}
示例#12
0
文件: cogl.c 项目: collinss/muffin
void
cogl_frustum (float        left,
	      float        right,
	      float        bottom,
	      float        top,
	      float        z_near,
	      float        z_far)
{
  cogl_framebuffer_frustum (cogl_get_draw_framebuffer (),
                            left, right, bottom, top, z_near, z_far);
}
示例#13
0
文件: cogl.c 项目: collinss/muffin
void
cogl_ortho (float left,
	    float right,
	    float bottom,
	    float top,
	    float near,
	    float far)
{
  cogl_framebuffer_orthographic (cogl_get_draw_framebuffer (),
                                 left, top, right, bottom, near, far);
}
示例#14
0
static void
_cogl_rectangles_with_multitexture_coords (
                                        CoglMultiTexturedRect *rects,
                                        int n_rects)
{
  _cogl_framebuffer_draw_multitextured_rectangles (cogl_get_draw_framebuffer (),
                                                   cogl_get_source (),
                                                   rects,
                                                   n_rects,
                                                   FALSE);
}
示例#15
0
/* TODO: Update to the protoype used in the Cogl master branch.
 * This is experimental API but not in sync with the cogl_path_fill()
 * api in Cogl master which takes explicit framebuffer and pipeline
 * arguments */
void
cogl2_path_stroke (CoglPath *path)
{
  _COGL_RETURN_IF_FAIL (cogl_is_path (path));

  if (path->data->path_nodes->len == 0)
    return;

  _cogl_path_stroke_nodes (path,
                           cogl_get_draw_framebuffer (),
                           cogl_get_source ());
}
示例#16
0
void
cogl_clip_stack_restore (void)
{
  CoglFramebuffer *framebuffer;
  CoglClipState *clip_state;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  framebuffer = cogl_get_draw_framebuffer ();
  clip_state = _cogl_framebuffer_get_clip_state (framebuffer);

  _cogl_clip_stack_restore_real (clip_state);
}
示例#17
0
/* XXX: This should never have been made public API! */
void
cogl_clip_ensure (void)
{
  CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
  CoglClipState *clip_state;

  clip_state = _cogl_framebuffer_get_clip_state (framebuffer);
  /* Flushing the clip state doesn't cause the journal to be
     flushed. This function may be being called by an external
     application however so it makes sense to flush the journal
     here */
  _cogl_framebuffer_flush_journal (framebuffer);
  _cogl_clip_state_flush (clip_state);
}
示例#18
0
static void
_cogl_path_stroke_nodes (CoglPath *path)
{
  CoglPathData *data = path->data;
  CoglPipeline *copy = NULL;
  CoglPipeline *source;
  unsigned int path_start;
  int path_num = 0;
  CoglPathNode *node;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  source = cogl_get_source ();

  if (cogl_pipeline_get_n_layers (source) != 0)
    {
      copy = cogl_pipeline_copy (source);
      _cogl_pipeline_prune_to_n_layers (copy, 0);
      source = copy;
    }

  _cogl_path_build_stroke_attribute_buffer (path);

  cogl_push_source (source);

  for (path_start = 0;
       path_start < data->path_nodes->len;
       path_start += node->path_size)
    {
      node = &g_array_index (data->path_nodes, CoglPathNode, path_start);

      cogl_framebuffer_vdraw_attributes (cogl_get_draw_framebuffer (),
                                         source,
                                         COGL_VERTICES_MODE_LINE_STRIP,
                                         0, node->path_size,
                                         data->stroke_attributes[path_num],
                                         NULL);

      path_num++;
    }

  cogl_pop_source ();

  if (copy)
    cogl_object_unref (copy);
}
示例#19
0
文件: cogl.c 项目: collinss/muffin
void
cogl_set_viewport (int x,
                   int y,
                   int width,
                   int height)
{
  CoglFramebuffer *framebuffer;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  framebuffer = cogl_get_draw_framebuffer ();

  cogl_framebuffer_set_viewport (framebuffer,
                                 x,
                                 y,
                                 width,
                                 height);
}
示例#20
0
void
cogl_clip_push_window_rectangle (int x_offset,
                                 int y_offset,
                                 int width,
                                 int height)
{
  CoglFramebuffer *framebuffer;
  CoglClipState *clip_state;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  framebuffer = cogl_get_draw_framebuffer ();
  clip_state = _cogl_framebuffer_get_clip_state (framebuffer);

  clip_state->stacks->data =
    _cogl_clip_stack_push_window_rectangle (clip_state->stacks->data,
                                            x_offset, y_offset,
                                            width, height);
}
示例#21
0
/**
 * mash_data_render:
 * @self: A #MashData instance
 *
 * Renders the data contained in the model to the Clutter
 * scene. The current Cogl source material will be used to affect the
 * appearance of the model. This function is not usually called
 * directly but instead the #MashData instance is added to a
 * #MashModel and this function will be automatically called by
 * the paint method of the model.
 */
void
mash_data_render (MashData *self, CoglPipeline* pl){
    MashDataPrivate *priv;
    g_return_if_fail (MASH_IS_DATA (self));
    priv = self->priv;

    if (priv->loaded_data.prim != NULL){
        CoglFramebuffer     *fb  = /*(CoglFramebuffer*)*/ cogl_get_draw_framebuffer();
        cogl_primitive_draw(priv->loaded_data.prim, fb, pl);
    }
    else if(priv->loaded_data.vertices_vbo != NULL && priv->loaded_data.indices != NULL){
        cogl_vertex_buffer_draw_elements (priv->loaded_data.vertices_vbo,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    priv->loaded_data.indices,
                                    priv->loaded_data.min_index,
                                    priv->loaded_data.max_index,
                                    0, priv->loaded_data.n_triangles * 3);
    }
}
示例#22
0
static void
meta_overlay_paint (MetaOverlay *overlay)
{
  if (!overlay->enabled)
    return;

  g_assert (meta_is_wayland_compositor ());

  cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
                                   overlay->pipeline,
                                   overlay->current_rect.x,
                                   overlay->current_rect.y,
                                   overlay->current_rect.x +
                                   overlay->current_rect.width,
                                   overlay->current_rect.y +
                                   overlay->current_rect.height);

  overlay->previous_rect = overlay->current_rect;
  overlay->previous_is_valid = TRUE;
}
示例#23
0
void
cogl_clip_push_rectangle (float x_1,
                          float y_1,
                          float x_2,
                          float y_2)
{
  CoglFramebuffer *framebuffer;
  CoglClipState *clip_state;
  CoglMatrix modelview_matrix;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  framebuffer = cogl_get_draw_framebuffer ();
  clip_state = _cogl_framebuffer_get_clip_state (framebuffer);

  cogl_get_modelview_matrix (&modelview_matrix);

  clip_state->stacks->data =
    _cogl_clip_stack_push_rectangle (clip_state->stacks->data,
                                     x_1, y_1, x_2, y_2,
                                     &modelview_matrix);
}
static void
shell_anamorphosis_effect_paint_target (ClutterOffscreenEffect *effect)
{
  ShellAnamorphosisEffect *self = SHELL_ANAMORPHOSIS_EFFECT (effect);
  ShellAnamorphosisEffectPrivate *priv = shell_anamorphosis_effect_get_instance_private (self);
  CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
  ClutterActor *actor;
  guint8 paint_opacity;

  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
  paint_opacity = clutter_actor_get_paint_opacity (actor);


  cogl_pipeline_set_color4ub (priv->pipeline,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity);

  cogl_framebuffer_draw_rectangle (fb, priv->pipeline,
                                   0, 0, priv->tex_width, priv->tex_height);
}
示例#25
0
static void
clutter_colorize_effect_paint_target (ClutterOffscreenEffect *effect)
{
  ClutterColorizeEffect *self = CLUTTER_COLORIZE_EFFECT (effect);
  CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
  ClutterActor *actor;
  guint8 paint_opacity;

  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
  paint_opacity = clutter_actor_get_paint_opacity (actor);

  cogl_pipeline_set_color4ub (self->pipeline,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity);

  cogl_framebuffer_draw_rectangle (framebuffer,
                                   self->pipeline,
                                   0, 0,
                                   self->tex_width, self->tex_height);
}
示例#26
0
文件: cogl.c 项目: collinss/muffin
void
cogl_get_bitmasks (int *red,
                   int *green,
                   int *blue,
                   int *alpha)
{
  CoglFramebuffer *framebuffer;

  framebuffer = cogl_get_draw_framebuffer ();

  if (red)
    *red = cogl_framebuffer_get_red_bits (framebuffer);

  if (green)
    *green = cogl_framebuffer_get_green_bits (framebuffer);

  if (blue)
    *blue = cogl_framebuffer_get_blue_bits (framebuffer);

  if (alpha)
    *alpha = cogl_framebuffer_get_alpha_bits (framebuffer);
}
示例#27
0
static void
shell_glsl_quad_paint (ClutterActor *actor)
{
  ShellGLSLQuad *self = SHELL_GLSL_QUAD (actor);
  ShellGLSLQuadPrivate *priv;
  guint8 paint_opacity;
  ClutterActorBox box;

  priv = shell_glsl_quad_get_instance_private (self);

  paint_opacity = clutter_actor_get_paint_opacity (actor);
  clutter_actor_get_allocation_box (actor, &box);

  cogl_pipeline_set_color4ub (priv->pipeline,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity,
                              paint_opacity);
  cogl_framebuffer_draw_rectangle (cogl_get_draw_framebuffer (),
                                   priv->pipeline,
                                   box.x1, box.y1,
                                   box.x2, box.y2);
}
示例#28
0
static void
do_grab_screenshot (_screenshot_data *screenshot_data,
                    int               x,
                    int               y,
                    int               width,
                    int               height)
{
  CoglBitmap *bitmap;
  ClutterBackend *backend;
  CoglContext *context;
  int stride;
  guchar *data;

  backend = clutter_get_default_backend ();
  context = clutter_backend_get_cogl_context (backend);

  screenshot_data->image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                                       width, height);


  data = cairo_image_surface_get_data (screenshot_data->image);
  stride = cairo_image_surface_get_stride (screenshot_data->image);

  bitmap = cogl_bitmap_new_for_data (context,
                                     width,
                                     height,
                                     CLUTTER_CAIRO_FORMAT_ARGB32,
                                     stride,
                                     data);
  cogl_framebuffer_read_pixels_into_bitmap (cogl_get_draw_framebuffer (),
                                            x, y,
                                            COGL_READ_PIXELS_COLOR_BUFFER,
                                            bitmap);

  cairo_surface_mark_dirty (screenshot_data->image);
  cogl_object_unref (bitmap);
}
示例#29
0
static void
clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect)
{
  ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
  ClutterDeformEffectPrivate *priv = self->priv;
  CoglHandle material;
  CoglPipeline *pipeline;
  CoglDepthState depth_state;
  CoglFramebuffer *fb = cogl_get_draw_framebuffer ();

  if (priv->is_dirty)
    {
      ClutterRect rect;
      gboolean mapped_buffer;
      CoglVertexP3T2C4 *verts;
      ClutterActor *actor;
      gfloat width, height;
      guint opacity;
      gint i, j;

      actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
      opacity = clutter_actor_get_paint_opacity (actor);

      /* if we don't have a target size, fall back to the actor's
       * allocation, though wrong it might be
       */
      if (clutter_offscreen_effect_get_target_rect (effect, &rect))
        {
          width = clutter_rect_get_width (&rect);
          height = clutter_rect_get_height (&rect);
        }
      else
        clutter_actor_get_size (actor, &width, &height);

      /* XXX ideally, the sub-classes should tell us what they
       * changed in the texture vertices; we then would be able to
       * avoid resubmitting the same data, if it did not change. for
       * the time being, we resubmit everything
       */
      verts = cogl_buffer_map (COGL_BUFFER (priv->buffer),
                               COGL_BUFFER_ACCESS_WRITE,
                               COGL_BUFFER_MAP_HINT_DISCARD);

      /* If the map failed then we'll resort to allocating a temporary
         buffer */
      if (verts == NULL)
        {
          mapped_buffer = FALSE;
          verts = g_malloc (sizeof (*verts) * priv->n_vertices);
        }
      else
        mapped_buffer = TRUE;

      for (i = 0; i < priv->y_tiles + 1; i++)
        {
          for (j = 0; j < priv->x_tiles + 1; j++)
            {
              CoglVertexP3T2C4 *vertex_out;
              CoglTextureVertex vertex;

              /* CoglTextureVertex isn't an ideal structure to use for
                 this because it contains a CoglColor. The internal
                 layout of CoglColor is mean to be private so Clutter
                 can not pass a pointer to it as a vertex
                 attribute. Also it contains padding so we end up
                 storing more data in the vertex buffer than we need
                 to. Instead we let the application modify a dummy
                 vertex and then copy the details back out to a more
                 well-defined struct */

              vertex.tx = (float) j / priv->x_tiles;
              vertex.ty = (float) i / priv->y_tiles;

              vertex.x = width * vertex.tx;
              vertex.y = height * vertex.ty;
              vertex.z = 0.0f;

              cogl_color_init_from_4ub (&vertex.color, 255, 255, 255, opacity);

              clutter_deform_effect_deform_vertex (self,
                                                   width, height,
                                                   &vertex);

              vertex_out = verts + i * (priv->x_tiles + 1) + j;

              vertex_out->x = vertex.x;
              vertex_out->y = vertex.y;
              vertex_out->z = vertex.z;
              vertex_out->s = vertex.tx;
              vertex_out->t = vertex.ty;
              vertex_out->r = cogl_color_get_red_byte (&vertex.color);
              vertex_out->g = cogl_color_get_green_byte (&vertex.color);
              vertex_out->b = cogl_color_get_blue_byte (&vertex.color);
              vertex_out->a = cogl_color_get_alpha_byte (&vertex.color);
            }
        }

      if (mapped_buffer)
        cogl_buffer_unmap (COGL_BUFFER (priv->buffer));
      else
        {
          cogl_buffer_set_data (COGL_BUFFER (priv->buffer),
                                0, /* offset */
                                verts,
                                sizeof (*verts) * priv->n_vertices);
          g_free (verts);
        }

      priv->is_dirty = FALSE;
    }

  material = clutter_offscreen_effect_get_target (effect);
  pipeline = COGL_PIPELINE (material);

  /* enable depth testing */
  cogl_depth_state_init (&depth_state);
  cogl_depth_state_set_test_enabled (&depth_state, TRUE);
  cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL);

  /* enable backface culling if we have a back material */
  if (priv->back_pipeline != NULL)
    cogl_pipeline_set_cull_face_mode (pipeline,
                                      COGL_PIPELINE_CULL_FACE_MODE_BACK);

  /* draw the front */
  if (material != NULL)
    cogl_framebuffer_draw_primitive (fb, pipeline, priv->primitive);

  /* draw the back */
  if (priv->back_pipeline != NULL)
    {
      CoglPipeline *back_pipeline;

      /* We probably shouldn't be modifying the user's material so
         instead we make a temporary copy */
      back_pipeline = cogl_pipeline_copy (priv->back_pipeline);
      cogl_pipeline_set_depth_state (back_pipeline, &depth_state, NULL);
      cogl_pipeline_set_cull_face_mode (back_pipeline,
                                        COGL_PIPELINE_CULL_FACE_MODE_FRONT);

      cogl_framebuffer_draw_primitive (fb, back_pipeline, priv->primitive);

      cogl_object_unref (back_pipeline);
    }

  if (G_UNLIKELY (priv->lines_primitive != NULL))
    {
      CoglContext *ctx =
        clutter_backend_get_cogl_context (clutter_get_default_backend ());
      CoglPipeline *lines_pipeline = cogl_pipeline_new (ctx);
      cogl_pipeline_set_color4f (lines_pipeline, 1.0, 0, 0, 1.0);
      cogl_framebuffer_draw_primitive (fb, lines_pipeline,
                                       priv->lines_primitive);
      cogl_object_unref (lines_pipeline);
    }
}
示例#30
0
文件: cogl.c 项目: collinss/muffin
/* XXX: it's expected that we'll deprecated this with
 * cogl_framebuffer_clear at some point. */
void
cogl_clear (const CoglColor *color, unsigned long buffers)
{
  cogl_framebuffer_clear (cogl_get_draw_framebuffer (), buffers, color);
}