static void
emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node)
{
  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  /* It's expensive to go through the Cogl journal for large runs
   * of text in part because the journal transforms the quads in software
   * to avoid changing the modelview matrix. So for larger runs of text
   * we load the vertices into a VBO, and this has the added advantage
   * that if the text doesn't change from frame to frame the VBO can
   * be re-used avoiding the repeated cost of validating the data and
   * mapping it into the GPU... */

  if (node->d.texture.vertex_buffer == COGL_INVALID_HANDLE)
    {
      CoglHandle vb = cogl_vertex_buffer_new (node->d.texture.verts->len);

      cogl_vertex_buffer_add (vb, "gl_Vertex", 2,
                              COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
                              sizeof (CoglPangoDisplayListVertex),
                              &g_array_index (node->d.texture.verts,
                                              CoglPangoDisplayListVertex, 0).x);
      cogl_vertex_buffer_add (vb, "gl_MultiTexCoord0", 2,
                              COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
                              sizeof (CoglPangoDisplayListVertex),
                              &g_array_index (node->d.texture.verts,
                                              CoglPangoDisplayListVertex,
                                              0).t_x);
      cogl_vertex_buffer_submit (vb);

      node->d.texture.vertex_buffer = vb;
    }

#ifdef CLUTTER_COGL_HAS_GL
  if (ctx->driver == COGL_DRIVER_GL)
    cogl_vertex_buffer_draw (node->d.texture.vertex_buffer,
                             GL_QUADS,
                             0, node->d.texture.verts->len);
  else
#endif
    {
      /* GLES doesn't support GL_QUADS so instead we use a VBO with
         indexed vertices to generate GL_TRIANGLES from the quads */

      int n_indices = node->d.texture.verts->len / 4 * 6;
      CoglHandle indices_vbo
        = cogl_vertex_buffer_indices_get_for_quads (n_indices);

      cogl_vertex_buffer_draw_elements (node->d.texture.vertex_buffer,
                                        COGL_VERTICES_MODE_TRIANGLES,
                                        indices_vbo,
                                        0, node->d.texture.verts->len - 1,
                                        0, n_indices);
    }
}
Exemple #2
0
static void
mx_fade_effect_paint_target (ClutterOffscreenEffect *effect)
{
  guint8 opacity;
  CoglColor color;
  ClutterActor *actor;

  CoglMaterial *material = clutter_offscreen_effect_get_target (effect);
  MxFadeEffect *self = MX_FADE_EFFECT (effect);
  MxFadeEffectPrivate *priv = self->priv;

  if (priv->update_vbo)
    mx_fade_effect_update_vbo (self);

  if (!priv->vbo || !priv->indices || !material)
    return;

  /* Set the blend string if the material has changed so we can blend with
   * the paint opacity.
   */
  if (material != priv->old_material)
    {
      GError *error = NULL;
      priv->old_material = material;

      if (!cogl_material_set_layer_combine (material, 1,
                                            "RGBA = MODULATE(PREVIOUS,CONSTANT)", &error))
        {
          g_warning (G_STRLOC ": Error setting layer combine blend string: %s",
                     error->message);
          g_error_free (error);
        }
    }

  /* Set the layer-combine constant so the texture is blended with the paint
   * opacity when painted.
   */
  actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
  opacity = clutter_actor_get_paint_opacity (actor);
  cogl_color_init_from_4ub (&color, opacity, opacity, opacity, opacity);
  cogl_material_set_layer_combine_constant (material, 1, &color);

  /* Draw the texture */
  cogl_set_source (material);
  cogl_vertex_buffer_draw_elements (priv->vbo,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    priv->indices,
                                    0,
                                    (priv->n_quads * 4) - 1,
                                    0,
                                    priv->n_quads * 6);
}
static void
on_paint (ClutterActor *actor, TestState *state)
{
  cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
  cogl_vertex_buffer_draw_elements (state->buffer,
                                    COGL_VERTICES_MODE_TRIANGLE_STRIP,
                                    state->indices,
                                    0, /* min index */
                                    (MESH_WIDTH + 1) *
                                    (MESH_HEIGHT + 1) - 1, /* max index */
                                    0, /* indices offset */
                                    state->n_static_indices);
}
Exemple #4
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);
    }
}
Exemple #5
0
static void
clutter_deform_effect_paint_target (ClutterOffscreenEffect *effect)
{
  ClutterDeformEffect *self= CLUTTER_DEFORM_EFFECT (effect);
  ClutterDeformEffectPrivate *priv = self->priv;
  gboolean is_depth_enabled, is_cull_enabled;
  CoglHandle material;
  gint n_tiles;

  if (priv->is_dirty)
    {
      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_size (effect, &width, &height))
        clutter_actor_get_size (actor, &width, &height);

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

              vertex = &priv->vertices[(i * (priv->x_tiles + 1)) + j];

              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);
            }
        }

      /* XXX in theory, 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
       */
      cogl_vertex_buffer_add (priv->vbo, "gl_Vertex",
                              3,
                              COGL_ATTRIBUTE_TYPE_FLOAT,
                              FALSE,
                              sizeof (CoglTextureVertex),
                              &priv->vertices->x);
      cogl_vertex_buffer_add (priv->vbo, "gl_MultiTexCoord0",
                              2,
                              COGL_ATTRIBUTE_TYPE_FLOAT,
                              FALSE,
                              sizeof (CoglTextureVertex),
                              &priv->vertices->tx);
      cogl_vertex_buffer_add (priv->vbo, "gl_Color",
                              4,
                              COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE,
                              FALSE,
                              sizeof (CoglTextureVertex),
                              &priv->vertices->color);

      priv->is_dirty = FALSE;
    }

  /* enable depth test, if it's not already enabled */
  is_depth_enabled = cogl_get_depth_test_enabled ();
  if (!is_depth_enabled)
    cogl_set_depth_test_enabled (TRUE);

  /* enable backface culling if it's not already enabled and if
   * we have a back material
   */
  is_cull_enabled = cogl_get_backface_culling_enabled ();
  if (priv->back_material != COGL_INVALID_HANDLE && !is_cull_enabled)
    cogl_set_backface_culling_enabled (TRUE);
  else if (priv->back_material == COGL_INVALID_HANDLE && is_cull_enabled)
    cogl_set_backface_culling_enabled (FALSE);

  n_tiles = (priv->x_tiles + 1) * (priv->y_tiles + 1);

  /* draw the front */
  material = clutter_offscreen_effect_get_target (effect);
  if (material != COGL_INVALID_HANDLE)
    {
      cogl_set_source (material);
      cogl_vertex_buffer_draw_elements (priv->vbo,
                                        COGL_VERTICES_MODE_TRIANGLE_STRIP,
                                        priv->indices,
                                        0,
                                        n_tiles,
                                        0,
                                        priv->n_indices);
    }

  /* draw the back */
  material = priv->back_material;
  if (material != COGL_INVALID_HANDLE)
    {
      cogl_set_source (priv->back_material);
      cogl_vertex_buffer_draw_elements (priv->vbo,
                                        COGL_VERTICES_MODE_TRIANGLE_STRIP,
                                        priv->back_indices,
                                        0,
                                        n_tiles,
                                        0,
                                        priv->n_indices);
    }

  /* restore the previous state */
  if (!is_depth_enabled)
    cogl_set_depth_test_enabled (FALSE);

  if (priv->back_material != COGL_INVALID_HANDLE && !is_cull_enabled)
    cogl_set_backface_culling_enabled (FALSE);
  else if (priv->back_material == COGL_INVALID_HANDLE && is_cull_enabled)
    cogl_set_backface_culling_enabled (TRUE);
}