예제 #1
0
CoglPrimitive *
cogl_primitive_new_p3t2 (CoglContext *ctx,
                         CoglVerticesMode mode,
                         int n_vertices,
                         const CoglVertexP3T2 *data)
{
  CoglAttributeBuffer *attribute_buffer =
    cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP3T2), data);
  CoglAttribute *attributes[2];

  attributes[0] = cogl_attribute_new (attribute_buffer,
                                      "cogl_position_in",
                                      sizeof (CoglVertexP3T2),
                                      offsetof (CoglVertexP3T2, x),
                                      3,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[1] = cogl_attribute_new (attribute_buffer,
                                      "cogl_tex_coord0_in",
                                      sizeof (CoglVertexP3T2),
                                      offsetof (CoglVertexP3T2, s),
                                      2,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);

  cogl_object_unref (attribute_buffer);

  return _cogl_primitive_new_with_attributes_unref (mode, n_vertices,
                                                    attributes,
                                                    2);
}
예제 #2
0
static void
create_primitive (Data *data)
{
  CoglAttribute *attributes[2];
  int i;

  data->attribute_buffer =
    cogl_attribute_buffer_new_with_size (data->context,
                                         sizeof (data->sparks));
  cogl_buffer_set_update_hint (data->attribute_buffer,
                               COGL_BUFFER_UPDATE_HINT_DYNAMIC);

  attributes[0] = cogl_attribute_new (data->attribute_buffer,
                                      "cogl_position_in",
                                      sizeof (Spark),
                                      G_STRUCT_OFFSET (Spark, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[1] = cogl_attribute_new (data->attribute_buffer,
                                      "cogl_color_in",
                                      sizeof (Spark),
                                      G_STRUCT_OFFSET (Spark, color),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);

  data->primitive =
    cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_POINTS,
                                        N_SPARKS,
                                        attributes,
                                        G_N_ELEMENTS (attributes));

  for (i = 0; i < G_N_ELEMENTS (attributes); i++)
    cogl_object_unref (attributes[i]);
}
예제 #3
0
CoglPrimitive *
cogl_primitive_new_p3c4 (CoglContext *ctx,
                         CoglVerticesMode mode,
                         int n_vertices,
                         const CoglVertexP3C4 *data)
{
  CoglAttributeBuffer *attribute_buffer =
    cogl_attribute_buffer_new (ctx, n_vertices * sizeof (CoglVertexP3C4), data);
  CoglAttribute *attributes[2];

  attributes[0] = cogl_attribute_new (attribute_buffer,
                                      "cogl_position_in",
                                      sizeof (CoglVertexP3C4),
                                      offsetof (CoglVertexP3C4, x),
                                      3,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[1] = cogl_attribute_new (attribute_buffer,
                                      "cogl_color_in",
                                      sizeof (CoglVertexP3C4),
                                      offsetof (CoglVertexP3C4, r),
                                      4,
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);

  cogl_object_unref (attribute_buffer);

  return _cogl_primitive_new_with_attributes_unref (mode, n_vertices,
                                                    attributes,
                                                    2);
}
예제 #4
0
static void
test_float_verts (TestState *state, int offset_x, int offset_y)
{
  CoglAttribute *attributes[2];
  CoglAttributeBuffer *buffer;

  static const FloatVert float_verts[] =
    {
      { 0, 10, /**/ 1, 0, 0, 1 },
      { 10, 10, /**/ 1, 0, 0, 1 },
      { 5, 0, /**/ 1, 0, 0, 1 },

      { 10, 10, /**/ 0, 1, 0, 1 },
      { 20, 10, /**/ 0, 1, 0, 1 },
      { 15, 0, /**/ 0, 1, 0, 1 }
    };

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (float_verts), float_verts);
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (FloatVert),
                                      G_STRUCT_OFFSET (FloatVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_SHORT);
  attributes[1] = cogl_attribute_new (buffer,
                                      "color",
                                      sizeof (FloatVert),
                                      G_STRUCT_OFFSET (FloatVert, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb, offset_x, offset_y, 0.0f);

  cogl_framebuffer_draw_attributes (test_fb,
                                    state->pipeline,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    0, /* first_vertex */
                                    6, /* n_vertices */
                                    attributes,
                                    2 /* n_attributes */);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[1]);
  cogl_object_unref (attributes[0]);
  cogl_object_unref (buffer);

  test_utils_check_pixel (test_fb, offset_x + 5, offset_y + 5, 0xff0000ff);
  test_utils_check_pixel (test_fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
}
예제 #5
0
void
_cogl_rectangle_immediate (CoglFramebuffer *framebuffer,
                           CoglPipeline *pipeline,
                           float x_1,
                           float y_1,
                           float x_2,
                           float y_2)
{
  /* Draw a rectangle using the vertex array API to avoid going
     through the journal. This should only be used in cases where the
     code might be called while the journal is already being flushed
     such as when flushing the clip state */
  CoglContext *ctx = framebuffer->context;
  float vertices[8] =
    {
      x_1, y_1,
      x_1, y_2,
      x_2, y_1,
      x_2, y_2
    };
  CoglAttributeBuffer *attribute_buffer;
  CoglAttribute *attributes[1];

  attribute_buffer =
    cogl_attribute_buffer_new (ctx, sizeof (vertices), vertices);
  attributes[0] = cogl_attribute_new (attribute_buffer,
                                      "cogl_position_in",
                                      sizeof (float) * 2, /* stride */
                                      0, /* offset */
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);

  _cogl_framebuffer_draw_attributes (framebuffer,
                                     pipeline,
                                     COGL_VERTICES_MODE_TRIANGLE_STRIP,
                                     0, /* first_index */
                                     4, /* n_vertices */
                                     attributes,
                                     1,
                                     COGL_DRAW_SKIP_JOURNAL_FLUSH |
                                     COGL_DRAW_SKIP_PIPELINE_VALIDATION |
                                     COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH |
                                     COGL_DRAW_SKIP_LEGACY_STATE);


  cogl_object_unref (attributes[0]);
  cogl_object_unref (attribute_buffer);
}
예제 #6
0
파일: cogl-path.c 프로젝트: 3v1n0/cogl
static void
_cogl_path_build_fill_attribute_buffer (CoglPath *path)
{
  CoglPathTesselator tess;
  unsigned int path_start = 0;
  CoglPathData *data = path->data;
  int i;

  /* If we've already got a vbo then we don't need to do anything */
  if (data->fill_attribute_buffer)
    return;

  tess.primitive_type = FALSE;

  /* Generate a vertex for each point on the path */
  tess.vertices = g_array_new (FALSE, FALSE, sizeof (CoglPathTesselatorVertex));
  g_array_set_size (tess.vertices, data->path_nodes->len);
  for (i = 0; i < data->path_nodes->len; i++)
    {
      CoglPathNode *node =
        &g_array_index (data->path_nodes, CoglPathNode, i);
      CoglPathTesselatorVertex *vertex =
        &g_array_index (tess.vertices, CoglPathTesselatorVertex, i);

      vertex->x = node->x;
      vertex->y = node->y;

      /* Add texture coordinates so that a texture would be drawn to
         fit the bounding box of the path and then cropped by the
         path */
      if (data->path_nodes_min.x == data->path_nodes_max.x)
        vertex->s = 0.0f;
      else
        vertex->s = ((node->x - data->path_nodes_min.x)
                     / (data->path_nodes_max.x - data->path_nodes_min.x));
      if (data->path_nodes_min.y == data->path_nodes_max.y)
        vertex->t = 0.0f;
      else
        vertex->t = ((node->y - data->path_nodes_min.y)
                     / (data->path_nodes_max.y - data->path_nodes_min.y));
    }

  tess.indices_type =
    _cogl_path_tesselator_get_indices_type_for_size (data->path_nodes->len);
  _cogl_path_tesselator_allocate_indices_array (&tess);

  tess.glu_tess = gluNewTess ();

  if (data->fill_rule == COGL_PATH_FILL_RULE_EVEN_ODD)
    gluTessProperty (tess.glu_tess, GLU_TESS_WINDING_RULE,
                     GLU_TESS_WINDING_ODD);
  else
    gluTessProperty (tess.glu_tess, GLU_TESS_WINDING_RULE,
                     GLU_TESS_WINDING_NONZERO);

  /* All vertices are on the xy-plane */
  gluTessNormal (tess.glu_tess, 0.0, 0.0, 1.0);

  gluTessCallback (tess.glu_tess, GLU_TESS_BEGIN_DATA,
                   _cogl_path_tesselator_begin);
  gluTessCallback (tess.glu_tess, GLU_TESS_VERTEX_DATA,
                   _cogl_path_tesselator_vertex);
  gluTessCallback (tess.glu_tess, GLU_TESS_END_DATA,
                   _cogl_path_tesselator_end);
  gluTessCallback (tess.glu_tess, GLU_TESS_COMBINE_DATA,
                   _cogl_path_tesselator_combine);

  gluTessBeginPolygon (tess.glu_tess, &tess);

  while (path_start < data->path_nodes->len)
    {
      CoglPathNode *node =
        &g_array_index (data->path_nodes, CoglPathNode, path_start);

      gluTessBeginContour (tess.glu_tess);

      for (i = 0; i < node->path_size; i++)
        {
          double vertex[3] = { node[i].x, node[i].y, 0.0 };
          gluTessVertex (tess.glu_tess, vertex,
                         GINT_TO_POINTER (i + path_start));
        }

      gluTessEndContour (tess.glu_tess);

      path_start += node->path_size;
    }

  gluTessEndPolygon (tess.glu_tess);

  gluDeleteTess (tess.glu_tess);

  data->fill_attribute_buffer =
    cogl_attribute_buffer_new (data->context,
                               sizeof (CoglPathTesselatorVertex) *
                               tess.vertices->len,
                               tess.vertices->data);
  g_array_free (tess.vertices, TRUE);

  data->fill_attributes[0] =
    cogl_attribute_new (data->fill_attribute_buffer,
                        "cogl_position_in",
                        sizeof (CoglPathTesselatorVertex),
                        G_STRUCT_OFFSET (CoglPathTesselatorVertex, x),
                        2, /* n_components */
                        COGL_ATTRIBUTE_TYPE_FLOAT);
  data->fill_attributes[1] =
    cogl_attribute_new (data->fill_attribute_buffer,
                        "cogl_tex_coord0_in",
                        sizeof (CoglPathTesselatorVertex),
                        G_STRUCT_OFFSET (CoglPathTesselatorVertex, s),
                        2, /* n_components */
                        COGL_ATTRIBUTE_TYPE_FLOAT);

  data->fill_vbo_indices = cogl_indices_new (data->context,
                                             tess.indices_type,
                                             tess.indices->data,
                                             tess.indices->len);
  data->fill_vbo_n_indices = tess.indices->len;
  g_array_free (tess.indices, TRUE);
}
예제 #7
0
static void
emit_vertex_buffer_geometry (CoglFramebuffer *fb,
                             CoglPipeline *pipeline,
                             CoglPangoDisplayListNode *node)
{
  CoglContext *ctx = fb->context;

  /* 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.primitive == NULL)
    {
      CoglAttributeBuffer *buffer;
      CoglVertexP2T2 *verts, *v;
      int n_verts;
      CoglBool allocated = FALSE;
      CoglAttribute *attributes[2];
      CoglPrimitive *prim;
      int i;
      CoglError *ignore_error = NULL;

      n_verts = node->d.texture.rectangles->len * 4;

      buffer
        = cogl_attribute_buffer_new_with_size (ctx,
                                               n_verts *
                                               sizeof (CoglVertexP2T2));

      if ((verts = cogl_buffer_map (COGL_BUFFER (buffer),
                                    COGL_BUFFER_ACCESS_WRITE,
                                    COGL_BUFFER_MAP_HINT_DISCARD,
                                    &ignore_error)) == NULL)
        {
          cogl_error_free (ignore_error);
          verts = g_new (CoglVertexP2T2, n_verts);
          allocated = TRUE;
        }

      v = verts;

      /* Copy the rectangles into the buffer and expand into four
         vertices instead of just two */
      for (i = 0; i < node->d.texture.rectangles->len; i++)
        {
          const CoglPangoDisplayListRectangle *rectangle
            = &g_array_index (node->d.texture.rectangles,
                              CoglPangoDisplayListRectangle, i);

          v->x = rectangle->x_1;
          v->y = rectangle->y_1;
          v->s = rectangle->s_1;
          v->t = rectangle->t_1;
          v++;
          v->x = rectangle->x_1;
          v->y = rectangle->y_2;
          v->s = rectangle->s_1;
          v->t = rectangle->t_2;
          v++;
          v->x = rectangle->x_2;
          v->y = rectangle->y_2;
          v->s = rectangle->s_2;
          v->t = rectangle->t_2;
          v++;
          v->x = rectangle->x_2;
          v->y = rectangle->y_1;
          v->s = rectangle->s_2;
          v->t = rectangle->t_1;
          v++;
        }

      if (allocated)
        {
          cogl_buffer_set_data (COGL_BUFFER (buffer),
                                0, /* offset */
                                verts,
                                sizeof (CoglVertexP2T2) * n_verts,
                                NULL);
          g_free (verts);
        }
      else
        cogl_buffer_unmap (COGL_BUFFER (buffer));

      attributes[0] = cogl_attribute_new (buffer,
                                          "cogl_position_in",
                                          sizeof (CoglVertexP2T2),
                                          G_STRUCT_OFFSET (CoglVertexP2T2, x),
                                          2, /* n_components */
                                          COGL_ATTRIBUTE_TYPE_FLOAT);
      attributes[1] = cogl_attribute_new (buffer,
                                          "cogl_tex_coord0_in",
                                          sizeof (CoglVertexP2T2),
                                          G_STRUCT_OFFSET (CoglVertexP2T2, s),
                                          2, /* n_components */
                                          COGL_ATTRIBUTE_TYPE_FLOAT);

      prim = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                 n_verts,
                                                 attributes,
                                                 2 /* n_attributes */);

#ifdef CLUTTER_COGL_HAS_GL
      if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUADS))
        cogl_primitive_set_mode (prim, GL_QUADS);
      else
#endif
        {
          /* GLES doesn't support GL_QUADS so instead we use a VBO
             with indexed vertices to generate GL_TRIANGLES from the
             quads */

          CoglIndices *indices =
            cogl_get_rectangle_indices (ctx, node->d.texture.rectangles->len);

          cogl_primitive_set_indices (prim, indices,
                                      node->d.texture.rectangles->len * 6);
        }

      node->d.texture.primitive = prim;

      cogl_object_unref (buffer);
      cogl_object_unref (attributes[0]);
      cogl_object_unref (attributes[1]);
    }

  cogl_primitive_draw (node->d.texture.primitive,
                       fb,
                       pipeline);
}
예제 #8
0
static CoglPrimitive *
primitive_new_p2t2t2 (CoglContext *ctx,
                      CoglVerticesMode mode,
                      int n_vertices,
                      const VertexP2T2T2 *data)
{
  CoglAttributeBuffer *attribute_buffer =
    cogl_attribute_buffer_new (ctx, n_vertices * sizeof (VertexP2T2T2), data);
  int n_attributes = 7;
  CoglAttribute *attributes[n_attributes];
  CoglPrimitive *primitive;
#ifndef MESA_CONST_ATTRIB_BUG_WORKAROUND
  const float normal[3] = { 0, 0, 1 };
  const float tangent[3] = { 1, 0, 0 };
#endif
  int i;

  attributes[0] = cogl_attribute_new (attribute_buffer,
                                      "cogl_position_in",
                                      sizeof (VertexP2T2T2),
                                      offsetof (VertexP2T2T2, x),
                                      2,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);

  /* coords for shape mask, for rounded corners */
  attributes[1] = cogl_attribute_new (attribute_buffer,
                                      "cogl_tex_coord0_in",
                                      sizeof (VertexP2T2T2),
                                      offsetof (VertexP2T2T2, s0),
                                      2,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  /* coords for primary texture */
  attributes[2] = cogl_attribute_new (attribute_buffer,
                                      "cogl_tex_coord1_in",
                                      sizeof (VertexP2T2T2),
                                      offsetof (VertexP2T2T2, s1),
                                      2,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  /* coords for alpha mask texture */
  attributes[3] = cogl_attribute_new (attribute_buffer,
                                      "cogl_tex_coord4_in",
                                      sizeof (VertexP2T2T2),
                                      offsetof (VertexP2T2T2, s1),
                                      2,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  /* coords for normal map */
  attributes[4] = cogl_attribute_new (attribute_buffer,
                                      "cogl_tex_coord7_in",
                                      sizeof (VertexP2T2T2),
                                      offsetof (VertexP2T2T2, s1),
                                      2,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);

#ifdef MESA_CONST_ATTRIB_BUG_WORKAROUND
  attributes[5] = cogl_attribute_new (attribute_buffer,
                                      "cogl_normal_in",
                                      sizeof (VertexP2T2T2),
                                      offsetof (VertexP2T2T2, Nx),
                                      3,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[6] = cogl_attribute_new (attribute_buffer,
                                      "tangent_in",
                                      sizeof (VertexP2T2T2),
                                      offsetof (VertexP2T2T2, Tx),
                                      3,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
#else
  attributes[5] = cogl_attribute_new_const_3fv (ctx,
                                                "cogl_normal_in",
                                                normal);

  attributes[6] = cogl_attribute_new_const_3fv (ctx,
                                                "tangent_in",
                                                tangent);
#endif

  cogl_object_unref (attribute_buffer);

  primitive = cogl_primitive_new_with_attributes (mode,
                                                  n_vertices,
                                                  attributes,
                                                  n_attributes);

  for (i = 0; i < n_attributes; i++)
    cogl_object_unref (attributes[i]);

  return primitive;
}
예제 #9
0
static void
draw_frame (TestState *state)
{
  CoglTexture *tex = create_texture_3d (test_ctx);
  CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
  typedef struct { float x, y, s, t, r; } Vert;
  CoglPrimitive *primitive;
  CoglAttributeBuffer *attribute_buffer;
  CoglAttribute *attributes[2];
  Vert *verts, *v;
  int i;

  cogl_pipeline_set_layer_texture (pipeline, 0, tex);
  cogl_object_unref (tex);
  cogl_pipeline_set_layer_filters (pipeline, 0,
                                   COGL_PIPELINE_FILTER_NEAREST,
                                   COGL_PIPELINE_FILTER_NEAREST);

  /* Render the texture repeated horizontally twice using a regular
     cogl rectangle. This should end up with the r texture coordinates
     as zero */
  cogl_framebuffer_draw_textured_rectangle (test_fb, pipeline,
                                            0.0f, 0.0f, TEX_WIDTH * 2, TEX_HEIGHT,
                                            0.0f, 0.0f, 2.0f, 1.0f);

  /* Render all of the images in the texture using coordinates from a
     CoglPrimitive */
  v = verts = g_new (Vert, 4 * TEX_DEPTH);
  for (i = 0; i < TEX_DEPTH; i++)
    {
      float r = (i + 0.5f) / TEX_DEPTH;

      v->x = i * TEX_WIDTH;
      v->y = TEX_HEIGHT;
      v->s = 0;
      v->t = 0;
      v->r = r;
      v++;

      v->x = i * TEX_WIDTH;
      v->y = TEX_HEIGHT * 2;
      v->s = 0;
      v->t = 1;
      v->r = r;
      v++;

      v->x = i * TEX_WIDTH + TEX_WIDTH;
      v->y = TEX_HEIGHT * 2;
      v->s = 1;
      v->t = 1;
      v->r = r;
      v++;

      v->x = i * TEX_WIDTH + TEX_WIDTH;
      v->y = TEX_HEIGHT;
      v->s = 1;
      v->t = 0;
      v->r = r;
      v++;
    }

  attribute_buffer = cogl_attribute_buffer_new (test_ctx,
                                                4 * TEX_DEPTH * sizeof (Vert),
                                                verts);
  attributes[0] = cogl_attribute_new (attribute_buffer,
                                      "cogl_position_in",
                                      sizeof (Vert),
                                      G_STRUCT_OFFSET (Vert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[1] = cogl_attribute_new (attribute_buffer,
                                      "cogl_tex_coord_in",
                                      sizeof (Vert),
                                      G_STRUCT_OFFSET (Vert, s),
                                      3, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  6 * TEX_DEPTH,
                                                  attributes,
                                                  2 /* n_attributes */);

  cogl_primitive_set_indices (primitive,
                              cogl_get_rectangle_indices (test_ctx,
                                                          TEX_DEPTH),
                              6 * TEX_DEPTH);

  cogl_primitive_draw (primitive, test_fb, pipeline);

  g_free (verts);

  cogl_object_unref (primitive);
  cogl_object_unref (attributes[0]);
  cogl_object_unref (attributes[1]);
  cogl_object_unref (attribute_buffer);
  cogl_object_unref (pipeline);
}
예제 #10
0
파일: rut-camera.c 프로젝트: cee1/rig
CoglPrimitive *
rut_camera_create_frustum_primitive (RutCamera *camera)
{
  RutVertex4 vertices[8] = {
    /* near plane in projection space */
    {-1, -1, -1, 1, },
    { 1, -1, -1, 1, },
    { 1,  1, -1, 1, },
    {-1,  1, -1, 1, },
    /* far plane in projection space */
    {-1, -1, 1, 1, },
    { 1, -1, 1, 1, },
    { 1,  1, 1, 1, },
    {-1,  1, 1, 1, }
  };
  const CoglMatrix *projection_inv;
  CoglAttributeBuffer *attribute_buffer;
  CoglAttribute *attributes[1];
  CoglPrimitive *primitive;
  CoglIndices *indices;
  unsigned char indices_data[24] = {
      0,1, 1,2, 2,3, 3,0,
      4,5, 5,6, 6,7, 7,4,
      0,4, 1,5, 2,6, 3,7
  };
  int i;

  projection_inv = rut_camera_get_inverse_projection (camera);

  for (i = 0; i < 8; i++)
    {
      cogl_matrix_transform_point (projection_inv,
                                   &vertices[i].x,
                                   &vertices[i].y,
                                   &vertices[i].z,
                                   &vertices[i].w);
      vertices[i].x /= vertices[i].w;
      vertices[i].y /= vertices[i].w;
      vertices[i].z /= vertices[i].w;
      vertices[i].w /= 1.0f;
    }

  attribute_buffer = cogl_attribute_buffer_new (rut_cogl_context,
                                                8 * sizeof (RutVertex4),
                                                vertices);

  attributes[0] = cogl_attribute_new (attribute_buffer,
                                      "cogl_position_in",
                                      sizeof (RutVertex4),
                                      offsetof (RutVertex4, x),
                                      3,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);

  indices = cogl_indices_new (rut_cogl_context,
                              COGL_INDICES_TYPE_UNSIGNED_BYTE,
                              indices_data,
                              G_N_ELEMENTS (indices_data));

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_LINES,
                                                  8, attributes, 1);

  cogl_primitive_set_indices (primitive, indices, G_N_ELEMENTS(indices_data));

  cogl_object_unref (attribute_buffer);
  cogl_object_unref (attributes[0]);
  cogl_object_unref (indices);

  return primitive;
}
예제 #11
0
void
cogl_polygon (const CoglTextureVertex *vertices,
              unsigned int n_vertices,
	      CoglBool use_color)
{
  CoglPipeline *pipeline;
  ValidateState validate_state;
  int n_layers;
  int n_attributes;
  CoglAttribute **attributes;
  int i;
  unsigned int stride;
  size_t stride_bytes;
  CoglAttributeBuffer *attribute_buffer;
  float *v;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  pipeline = cogl_get_source ();

  validate_state.original_pipeline = pipeline;
  validate_state.pipeline = pipeline;
  cogl_pipeline_foreach_layer (pipeline,
                               _cogl_polygon_validate_layer_cb,
                               &validate_state);
  pipeline = validate_state.pipeline;

  n_layers = cogl_pipeline_get_n_layers (pipeline);

  n_attributes = 1 + n_layers + (use_color ? 1 : 0);
  attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);

  /* Our data is arranged like:
   * [X, Y, Z, TX0, TY0, TX1, TY1..., R, G, B, A,...] */
  stride = 3 + (2 * n_layers) + (use_color ? 1 : 0);
  stride_bytes = stride * sizeof (float);

  /* Make sure there is enough space in the global vertex array. This
   * is used so we can render the polygon with a single call to OpenGL
   * but still support any number of vertices */
  g_array_set_size (ctx->polygon_vertices, n_vertices * stride);

  attribute_buffer =
    cogl_attribute_buffer_new (ctx, n_vertices * stride_bytes, NULL);

  attributes[0] = cogl_attribute_new (attribute_buffer,
                                      "cogl_position_in",
                                      stride_bytes,
                                      0,
                                      3,
                                      COGL_ATTRIBUTE_TYPE_FLOAT);

  for (i = 0; i < n_layers; i++)
    {
      static const char *names[] = {
          "cogl_tex_coord0_in",
          "cogl_tex_coord1_in",
          "cogl_tex_coord2_in",
          "cogl_tex_coord3_in",
          "cogl_tex_coord4_in",
          "cogl_tex_coord5_in",
          "cogl_tex_coord6_in",
          "cogl_tex_coord7_in"
      };
      char *allocated_name = NULL;
      const char *name;

      if (i < 8)
        name = names[i];
      else
        name = allocated_name = g_strdup_printf ("cogl_tex_coord%d_in", i);

      attributes[i + 1] = cogl_attribute_new (attribute_buffer,
                                              name,
                                              stride_bytes,
                                              /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */
                                              12 + 8 * i,
                                              2,
                                              COGL_ATTRIBUTE_TYPE_FLOAT);

      g_free (allocated_name);
    }

  if (use_color)
    {
      attributes[n_attributes - 1] =
        cogl_attribute_new (attribute_buffer,
                            "cogl_color_in",
                            stride_bytes,
                            /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */
                            12 + 8 * n_layers,
                            4,
                            COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
    }

  /* Convert the vertices into an array of float vertex attributes */
  v = (float *)ctx->polygon_vertices->data;
  for (i = 0; i < n_vertices; i++)
    {
      AppendTexCoordsState append_tex_coords_state;
      uint8_t *c;

      /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */
      v[0] = vertices[i].x;
      v[1] = vertices[i].y;
      v[2] = vertices[i].z;

      append_tex_coords_state.vertices_in = vertices;
      append_tex_coords_state.vertex = i;
      append_tex_coords_state.layer = 0;
      append_tex_coords_state.vertices_out = v;
      cogl_pipeline_foreach_layer (pipeline,
                                   append_tex_coord_attributes_cb,
                                   &append_tex_coords_state);

      if (use_color)
        {
          /* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */
          c = (uint8_t *) (v + 3 + 2 * n_layers);
          c[0] = cogl_color_get_red_byte (&vertices[i].color);
          c[1] = cogl_color_get_green_byte (&vertices[i].color);
          c[2] = cogl_color_get_blue_byte (&vertices[i].color);
          c[3] = cogl_color_get_alpha_byte (&vertices[i].color);
        }

      v += stride;
    }

  v = (float *)ctx->polygon_vertices->data;
  cogl_buffer_set_data (COGL_BUFFER (attribute_buffer),
                        0,
                        v,
                        ctx->polygon_vertices->len * sizeof (float));

  /* XXX: although this may seem redundant, we need to do this since
   * cogl_polygon() can be used with legacy state and its the source stack
   * which track whether legacy state is enabled.
   *
   * (We only have a CoglDrawFlag to disable legacy state not one
   *  to enable it) */
  cogl_push_source (pipeline);

  _cogl_framebuffer_draw_attributes (cogl_get_draw_framebuffer (),
                                     pipeline,
                                     COGL_VERTICES_MODE_TRIANGLE_FAN,
                                     0, n_vertices,
                                     attributes,
                                     n_attributes,
                                     0 /* no draw flags */);

  cogl_pop_source ();

  if (pipeline != validate_state.original_pipeline)
    cogl_object_unref (pipeline);

  cogl_object_unref (attribute_buffer);

  for (i = 0; i < n_attributes; i++)
    cogl_object_unref (attributes[i]);
}
예제 #12
0
void
test_map_buffer_range (void)
{
  CoglTexture2D *tex;
  CoglPipeline *pipeline;
  int fb_width, fb_height;
  CoglAttributeBuffer *buffer;
  CoglVertexP2T2 *data;
  CoglAttribute *pos_attribute;
  CoglAttribute *tex_coord_attribute;
  CoglPrimitive *primitive;

  tex = cogl_texture_2d_new_from_data (test_ctx,
                                       2, 2, /* width/height */
                                       COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                       COGL_PIXEL_FORMAT_ANY,
                                       2 * 4, /* rowstride */
                                       tex_data,
                                       NULL /* error */);

  pipeline = cogl_pipeline_new (test_ctx);

  cogl_pipeline_set_layer_texture (pipeline, 0, COGL_TEXTURE (tex));
  cogl_pipeline_set_layer_filters (pipeline,
                                   0, /* layer */
                                   COGL_PIPELINE_FILTER_NEAREST,
                                   COGL_PIPELINE_FILTER_NEAREST);
  cogl_pipeline_set_layer_wrap_mode (pipeline,
                                     0, /* layer */
                                     COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);

  fb_width = cogl_framebuffer_get_width (test_fb);
  fb_height = cogl_framebuffer_get_height (test_fb);

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (vertex_data),
                                      vertex_data);

  /* Replace the texture coordinates of the third vertex with the
   * coordinates for a green texel */
  data = cogl_buffer_map_range (COGL_BUFFER (buffer),
                                sizeof (vertex_data[0]) * 2,
                                sizeof (vertex_data[0]),
                                COGL_BUFFER_ACCESS_WRITE,
                                COGL_BUFFER_MAP_HINT_DISCARD_RANGE,
                                NULL); /* don't catch errors */
  g_assert (data != NULL);

  data->x = vertex_data[2].x;
  data->y = vertex_data[2].y;
  data->s = 1.0f;
  data->t = 0.0f;

  cogl_buffer_unmap (COGL_BUFFER (buffer));

  pos_attribute =
    cogl_attribute_new (buffer,
                        "cogl_position_in",
                        sizeof (vertex_data[0]),
                        offsetof (CoglVertexP2T2, x),
                        2, /* n_components */
                        COGL_ATTRIBUTE_TYPE_FLOAT);
  tex_coord_attribute =
    cogl_attribute_new (buffer,
                        "cogl_tex_coord_in",
                        sizeof (vertex_data[0]),
                        offsetof (CoglVertexP2T2, s),
                        2, /* n_components */
                        COGL_ATTRIBUTE_TYPE_FLOAT);

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

  primitive =
    cogl_primitive_new (COGL_VERTICES_MODE_TRIANGLE_STRIP,
                        4, /* n_vertices */
                        pos_attribute,
                        tex_coord_attribute,
                        NULL);
  cogl_primitive_draw (primitive, test_fb, pipeline);
  cogl_object_unref (primitive);

  /* Top left pixel should be the one that is replaced to be green */
  test_utils_check_pixel (test_fb, 1, 1, 0x00ff00ff);
  /* The other three corners should be left as red */
  test_utils_check_pixel (test_fb, fb_width - 2, 1, 0xff0000ff);
  test_utils_check_pixel (test_fb, 1, fb_height - 2, 0xff0000ff);
  test_utils_check_pixel (test_fb, fb_width - 2, fb_height - 2, 0xff0000ff);

  cogl_object_unref (buffer);
  cogl_object_unref (pos_attribute);
  cogl_object_unref (tex_coord_attribute);

  cogl_object_unref (pipeline);
  cogl_object_unref (tex);

  if (cogl_test_verbose ())
    g_print ("OK\n");
}
예제 #13
0
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
// If text or lines are blurry when integrating ImGui in your engine:
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplGtk3Cogl_RenderDrawData(ImDrawData* draw_data)
{
    // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
    ImGuiIO& io = ImGui::GetIO();
    int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
    int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
    if (fb_width == 0 || fb_height == 0)
        return;
    draw_data->ScaleClipRects(io.DisplayFramebufferScale);

    cogl_framebuffer_orthographic(g_Framebuffer, 0, 0,
                                  io.DisplaySize.x, io.DisplaySize.y,
                                  -1, 1);

    CoglContext *context = cogl_framebuffer_get_context(g_Framebuffer);
    for (int n = 0; n < draw_data->CmdListsCount; n++)
    {
        const ImDrawList* cmd_list = draw_data->CmdLists[n];
        int idx_buffer_offset = 0;

        CoglAttributeBuffer *vertices =
            cogl_attribute_buffer_new(context,
                                      cmd_list->VtxBuffer.Size * sizeof(ImDrawVert),
                                      cmd_list->VtxBuffer.Data);

#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
        CoglAttribute *attrs[3] = {
            cogl_attribute_new(vertices, "cogl_position_in",
                               sizeof(ImDrawVert), OFFSETOF(ImDrawVert, pos),
                               2, COGL_ATTRIBUTE_TYPE_FLOAT),
            cogl_attribute_new(vertices, "cogl_tex_coord0_in",
                               sizeof(ImDrawVert), OFFSETOF(ImDrawVert, uv),
                               2, COGL_ATTRIBUTE_TYPE_FLOAT),
            cogl_attribute_new(vertices, "cogl_color_in",
                               sizeof(ImDrawVert), OFFSETOF(ImDrawVert, col),
                               4, COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE)
        };
#undef OFFSETOF

        CoglPrimitive *primitive =
            cogl_primitive_new_with_attributes(COGL_VERTICES_MODE_TRIANGLES,
                                               cmd_list->VtxBuffer.Size,
                                               attrs, 3);

        CoglIndices *indices = cogl_indices_new(context,
                                                sizeof(ImDrawIdx) == 2 ?
                                                COGL_INDICES_TYPE_UNSIGNED_SHORT :
                                                COGL_INDICES_TYPE_UNSIGNED_INT,
                                                cmd_list->IdxBuffer.Data,
                                                cmd_list->IdxBuffer.Size);

        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
        {
            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];

            cogl_indices_set_offset(indices, sizeof(ImDrawIdx) * idx_buffer_offset);
            cogl_primitive_set_indices(primitive, indices, pcmd->ElemCount);

            if (pcmd->UserCallback)
            {
                pcmd->UserCallback(cmd_list, pcmd);
            }
            else
            {
                bool has_texture = pcmd->TextureId != NULL;
                CoglPipeline *pipeline =
                    has_texture ?
                    (cogl_is_pipeline(pcmd->TextureId) ?
                     (CoglPipeline *) pcmd->TextureId : g_ImagePipeline) :
                    g_ColorPipeline;

                if (has_texture && pipeline == g_ImagePipeline) {
                    cogl_pipeline_set_layer_texture(g_ImagePipeline, 0,
                                                    COGL_TEXTURE(pcmd->TextureId));
                }

                cogl_framebuffer_push_scissor_clip(g_Framebuffer,
                                                   pcmd->ClipRect.x,
                                                   pcmd->ClipRect.y,
                                                   pcmd->ClipRect.z - pcmd->ClipRect.x,
                                                   pcmd->ClipRect.w - pcmd->ClipRect.y);
                cogl_primitive_draw(primitive, g_Framebuffer, pipeline);
                cogl_framebuffer_pop_clip(g_Framebuffer);
            }
            idx_buffer_offset += pcmd->ElemCount;
        }

        for (int i = 0; i < 3; i++)
            cogl_object_unref(attrs[i]);
        cogl_object_unref(primitive);
        cogl_object_unref(vertices);
        cogl_object_unref(indices);
    }
}
예제 #14
0
파일: cogl-path.c 프로젝트: 3v1n0/cogl
static void
_cogl_path_build_stroke_attribute_buffer (CoglPath *path)
{
  CoglPathData *data = path->data;
  CoglBuffer *buffer;
  unsigned int n_attributes = 0;
  unsigned int path_start;
  CoglPathNode *node;
  floatVec2 *buffer_p;
  unsigned int i;

  /* If we've already got a cached vbo then we don't need to do anything */
  if (data->stroke_attribute_buffer)
    return;

  data->stroke_attribute_buffer =
    cogl_attribute_buffer_new_with_size (data->context,
                                         data->path_nodes->len *
                                         sizeof (floatVec2));

  buffer = COGL_BUFFER (data->stroke_attribute_buffer);
  buffer_p = _cogl_buffer_map_for_fill_or_fallback (buffer);

  /* Copy the vertices in and count the number of sub paths. Each sub
     path will form a separate attribute so we can paint the disjoint
     line strips */
  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);

      for (i = 0; i < node->path_size; i++)
        {
          buffer_p[path_start + i].x = node[i].x;
          buffer_p[path_start + i].y = node[i].y;
        }

      n_attributes++;
    }

  _cogl_buffer_unmap_for_fill_or_fallback (buffer);

  data->stroke_attributes = g_new (CoglAttribute *, n_attributes);

  /* Now we can loop the sub paths again to create the attributes */
  for (i = 0, path_start = 0;
       path_start < data->path_nodes->len;
       i++, path_start += node->path_size)
    {
      node = &g_array_index (data->path_nodes, CoglPathNode, path_start);

      data->stroke_attributes[i] =
        cogl_attribute_new (data->stroke_attribute_buffer,
                            "cogl_position_in",
                            sizeof (floatVec2),
                            path_start * sizeof (floatVec2),
                            2, /* n_components */
                            COGL_ATTRIBUTE_TYPE_FLOAT);
    }

  data->stroke_n_attributes = n_attributes;
}
예제 #15
0
static void
test_short_verts (TestState *state, int offset_x, int offset_y)
{
  CoglAttribute *attributes[2];
  CoglAttributeBuffer *buffer;
  CoglPipeline *pipeline, *pipeline2;
  CoglSnippet *snippet;
  CoglPrimitive *primitive;

  static const ShortVert short_verts[] =
    {
      { -10, -10, /**/ 0xffff, 0, 0, 0xffff },
      { -1, -10,  /**/ 0xffff, 0, 0, 0xffff },
      { -5, -1, /**/ 0xffff, 0, 0, 0xffff }
    };


  pipeline = cogl_pipeline_copy (state->pipeline);

  cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (short_verts), short_verts);
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_SHORT);
  attributes[1] = cogl_attribute_new (buffer,
                                      "color",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT);
  cogl_attribute_set_normalized (attributes[1], TRUE);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f,
                              offset_y + 10.0f,
                              0.0f);

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  3, /* n_vertices */
                                                  attributes,
                                                  2); /* n_attributes */
  cogl_primitive_draw (primitive, test_fb, pipeline);
  cogl_object_unref (primitive);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  /* Test again treating the attribute as unsigned */
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT);

  /* XXX: this is a hack to force the pipeline to use the glsl backend
   * because we know it's not possible to test short vertex position
   * components with the legacy GL backend since which might otherwise
   * be used internally... */
  pipeline2 = cogl_pipeline_new (test_ctx);
  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
                              "attribute vec4 color;",
                              "cogl_color_out = vec4 (0.0, 1.0, 0.0, 1.0);");
  cogl_pipeline_add_snippet (pipeline2, snippet);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f - 65525.0f,
                              offset_y - 65525,
                              0.0f);

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  3, /* n_vertices */
                                                  attributes,
                                                  1); /* n_attributes */
  cogl_primitive_draw (primitive, test_fb, pipeline2);
  cogl_object_unref (primitive);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  cogl_object_unref (pipeline2);
  cogl_object_unref (pipeline);
  cogl_object_unref (buffer);

  test_utils_check_pixel (test_fb, offset_x + 5, offset_y + 5, 0xff0000ff);
  test_utils_check_pixel (test_fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
}
예제 #16
0
static void
test_short_verts (TestState *state, int offset_x, int offset_y)
{
  CoglAttribute *attributes[1];
  CoglAttributeBuffer *buffer;
  CoglPipeline *pipeline, *pipeline2;
  CoglSnippet *snippet;

  static const ShortVert short_verts[] =
    {
      { -10, -10 },
      { -1, -10 },
      { -5, -1 }
    };

  pipeline = cogl_pipeline_new (test_ctx);
  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_TRANSFORM,
                              "attribute vec2 pos;",
                              NULL);
  cogl_snippet_set_replace (snippet,
                            "cogl_position_out = "
                            "cogl_modelview_projection_matrix * "
                            "vec4 (pos, 0.0, 1.0);");
  cogl_pipeline_add_snippet (pipeline, snippet);
  cogl_object_unref (snippet);

  cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (short_verts), short_verts);
  attributes[0] = cogl_attribute_new (buffer,
                                      "pos",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_SHORT);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f,
                              offset_y + 10.0f,
                              0.0f);

  cogl_framebuffer_draw_attributes (test_fb,
                                    pipeline,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    0, /* first_vertex */
                                    3, /* n_vertices */
                                    attributes,
                                    1 /* n_attributes */);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  /* Test again treating the attribute as unsigned */
  attributes[0] = cogl_attribute_new (buffer,
                                      "pos",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT);

  pipeline2 = cogl_pipeline_copy (pipeline);
  cogl_pipeline_set_color4ub (pipeline2, 0, 255, 0, 255);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f - 65525.0f,
                              offset_y - 65525,
                              0.0f);

  cogl_framebuffer_draw_attributes (test_fb,
                                    pipeline2,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    0, /* first_vertex */
                                    3, /* n_vertices */
                                    attributes,
                                    1 /* n_attributes */);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  cogl_object_unref (pipeline2);
  cogl_object_unref (pipeline);
  cogl_object_unref (buffer);

  test_utils_check_pixel (test_fb, offset_x + 5, offset_y + 5, 0xff0000ff);
  test_utils_check_pixel (test_fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
}
예제 #17
0
static void
clutter_deform_effect_init_arrays (ClutterDeformEffect *self)
{
  ClutterDeformEffectPrivate *priv = self->priv;
  gint x, y, direction, n_indices;
  CoglAttribute *attributes[3];
  guint16 *static_indices;
  CoglContext *ctx =
    clutter_backend_get_cogl_context (clutter_get_default_backend ());
  CoglIndices *indices;
  guint16 *idx;
  int i;

  clutter_deform_effect_free_arrays (self);

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

  static_indices = g_new (guint16, n_indices);

#define MESH_INDEX(x,y) ((y) * (priv->x_tiles + 1) + (x))

  /* compute all the triangles from the various tiles */
  direction = 1;

  idx = static_indices;
  idx[0] = MESH_INDEX (0, 0);
  idx[1] = MESH_INDEX (0, 1);
  idx += 2;

  for (y = 0; y < priv->y_tiles; y++)
    {
      for (x = 0; x < priv->x_tiles; x++)
        {
          if (direction)
            {
              idx[0] = MESH_INDEX (x + 1, y);
              idx[1] = MESH_INDEX (x + 1, y + 1);
            }
          else
            {
              idx[0] = MESH_INDEX (priv->x_tiles - x - 1, y);
              idx[1] = MESH_INDEX (priv->x_tiles - x - 1, y + 1);
            }

          idx += 2;
        }

      if (y == (priv->y_tiles - 1))
        break;

      if (direction)
        {
          idx[0] = MESH_INDEX (priv->x_tiles, y + 1);
          idx[1] = MESH_INDEX (priv->x_tiles, y + 1);
          idx[2] = MESH_INDEX (priv->x_tiles, y + 2);
        }
      else
        {
          idx[0] = MESH_INDEX (0, y + 1);
          idx[1] = MESH_INDEX (0, y + 1);
          idx[2] = MESH_INDEX (0, y + 2);
        }

      idx += 3;

      direction = !direction;
    }

#undef MESH_INDEX

  indices = cogl_indices_new (ctx,
                              COGL_INDICES_TYPE_UNSIGNED_SHORT,
                              static_indices,
                              n_indices);

  g_free (static_indices);

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

  priv->buffer =
    cogl_attribute_buffer_new (ctx,
                               sizeof (CoglVertexP3T2C4) *
                               priv->n_vertices,
                               NULL);

  /* The application is expected to continuously modify the vertices
     so we should give a hint to Cogl about that */
  cogl_buffer_set_update_hint (COGL_BUFFER (priv->buffer),
                               COGL_BUFFER_UPDATE_HINT_DYNAMIC);

  attributes[0] = cogl_attribute_new (priv->buffer,
                                      "cogl_position_in",
                                      sizeof (CoglVertexP3T2C4),
                                      G_STRUCT_OFFSET (CoglVertexP3T2C4, x),
                                      3, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[1] = cogl_attribute_new (priv->buffer,
                                      "cogl_tex_coord0_in",
                                      sizeof (CoglVertexP3T2C4),
                                      G_STRUCT_OFFSET (CoglVertexP3T2C4, s),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[2] = cogl_attribute_new (priv->buffer,
                                      "cogl_color_in",
                                      sizeof (CoglVertexP3T2C4),
                                      G_STRUCT_OFFSET (CoglVertexP3T2C4, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);

  priv->primitive =
    cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP,
                                        priv->n_vertices,
                                        attributes,
                                        3 /* n_attributes */);
  cogl_primitive_set_indices (priv->primitive,
                              indices,
                              n_indices);

  if (G_UNLIKELY (clutter_paint_debug_flags & CLUTTER_DEBUG_PAINT_DEFORM_TILES))
    {
      priv->lines_primitive =
        cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_LINE_STRIP,
                                            priv->n_vertices,
                                            attributes,
                                            2 /* n_attributes */);
      cogl_primitive_set_indices (priv->lines_primitive,
                                  indices,
                                  n_indices);
    }

  cogl_object_unref (indices);

  for (i = 0; i < 3; i++)
    cogl_object_unref (attributes[i]);

  priv->is_dirty = TRUE;
}
예제 #18
0
static void
test_byte_verts (TestState *state, int offset_x, int offset_y)
{
  CoglAttribute *attributes[2];
  CoglAttributeBuffer *buffer, *unnorm_buffer;

  static const ByteVert norm_verts[] =
    {
      { 0, 10, /**/ 255, 0, 0, 255 },
      { 10, 10, /**/ 255, 0, 0, 255 },
      { 5, 0, /**/ 255, 0, 0, 255 },

      { 10, 10, /**/ 0, 255, 0, 255 },
      { 20, 10, /**/ 0, 255, 0, 255 },
      { 15, 0, /**/ 0, 255, 0, 255 }
    };

  static const ByteVert unnorm_verts[] =
    {
      { 0, 0, /**/ 0, 0, 1, 1 },
      { 0, 0, /**/ 0, 0, 1, 1 },
      { 0, 0, /**/ 0, 0, 1, 1 },
    };

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (norm_verts), norm_verts);
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (ByteVert),
                                      G_STRUCT_OFFSET (ByteVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_SHORT);
  attributes[1] = cogl_attribute_new (buffer,
                                      "color",
                                      sizeof (ByteVert),
                                      G_STRUCT_OFFSET (ByteVert, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
  cogl_attribute_set_normalized (attributes[1], TRUE);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb, offset_x, offset_y, 0.0f);

  cogl_framebuffer_draw_attributes (test_fb,
                                    state->pipeline,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    0, /* first_vertex */
                                    6, /* n_vertices */
                                    attributes,
                                    2 /* n_attributes */);

  cogl_object_unref (attributes[1]);

  /* Test again with unnormalized attributes */
  unnorm_buffer = cogl_attribute_buffer_new (test_ctx,
                                             sizeof (unnorm_verts),
                                             unnorm_verts);
  attributes[1] = cogl_attribute_new (unnorm_buffer,
                                      "color",
                                      sizeof (ByteVert),
                                      G_STRUCT_OFFSET (ByteVert, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_BYTE);

  cogl_framebuffer_translate (test_fb, 20, 0, 0);

  cogl_framebuffer_draw_attributes (test_fb,
                                    state->pipeline,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    0, /* first_vertex */
                                    3, /* n_vertices */
                                    attributes,
                                    2 /* n_attributes */);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);
  cogl_object_unref (attributes[1]);
  cogl_object_unref (buffer);
  cogl_object_unref (unnorm_buffer);

  test_utils_check_pixel (test_fb, offset_x + 5, offset_y + 5, 0xff0000ff);
  test_utils_check_pixel (test_fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
  test_utils_check_pixel (test_fb, offset_x + 25, offset_y + 5, 0x0000ffff);
}
예제 #19
0
static gboolean
mash_ply_loader_load (MashDataLoader *data_loader,
                      MashDataFlags flags,
                      const gchar *filename,
                      GError **error)
{
  CoglContext *context;
  CoglIndices *indices;
  MashPlyLoader *self = MASH_PLY_LOADER (data_loader);
  MashPlyLoaderPrivate *priv;
  MashPlyLoaderData data;
  gchar *display_name;
  gboolean ret;

  priv = self->priv;

  context = es_get_cogl_context ();

  data.error = NULL;
  data.n_vertex_bytes = 0;
  data.available_props = 0;
  data.got_props = 0;
  data.vertices = g_byte_array_new ();
  data.faces = NULL;
  data.min_vertex.x = G_MAXFLOAT;
  data.min_vertex.y = G_MAXFLOAT;
  data.min_vertex.z = G_MAXFLOAT;
  data.max_vertex.x = -G_MAXFLOAT;
  data.max_vertex.y = -G_MAXFLOAT;
  data.max_vertex.z = -G_MAXFLOAT;
  data.flags = flags;

  display_name = g_filename_display_name (filename);

  if ((data.ply = ply_open (filename,
                            mash_ply_loader_error_cb,
                            &data)) == NULL)
    mash_ply_loader_check_unknown_error (&data);
  else
    {
      if (!ply_read_header (data.ply))
        mash_ply_loader_check_unknown_error (&data);
      else
        {
          int i;

          for (i = 0; i < G_N_ELEMENTS (mash_ply_loader_properties); i++)
            if (ply_set_read_cb (data.ply, "vertex",
                                 mash_ply_loader_properties[i].name,
                                 mash_ply_loader_vertex_read_cb,
                                 &data, i))
              {
                data.prop_map[i] = data.n_vertex_bytes;
                data.n_vertex_bytes += mash_ply_loader_properties[i].size;
                data.available_props |= 1 << i;
              }

          /* Align the size of a vertex to 32 bits */
          data.n_vertex_bytes = (data.n_vertex_bytes + 3) & ~(guint) 3;

          if ((data.available_props & MASH_PLY_LOADER_VERTEX_PROPS)
              != MASH_PLY_LOADER_VERTEX_PROPS)
            g_set_error (&data.error, MASH_DATA_ERROR,
                         MASH_DATA_ERROR_MISSING_PROPERTY,
                         "PLY file %s is missing the vertex properties",
                         display_name);
          else if (!ply_set_read_cb (data.ply, "face", "vertex_indices",
                                     mash_ply_loader_face_read_cb,
                                     &data, i))
            g_set_error (&data.error, MASH_DATA_ERROR,
                         MASH_DATA_ERROR_MISSING_PROPERTY,
                         "PLY file %s is missing face property "
                         "'vertex_indices'",
                         display_name);
          else if (mash_ply_loader_get_indices_type (&data, &data.error)
                   && !ply_read (data.ply))
            mash_ply_loader_check_unknown_error (&data);
        }

      ply_close (data.ply);
    }

  if (data.error)
    {
      g_propagate_error (error, data.error);
      ret = FALSE;
    }
  else if (data.faces->len < 3)
    {
      g_set_error (error, MASH_DATA_ERROR,
                   MASH_DATA_ERROR_INVALID,
                   "No faces found in %s",
                   display_name);
      ret = FALSE;
    }
  else
    {
      CoglAttributeBuffer *attribute_buffer;
      CoglAttribute *attributes[4];
      int n_attributes = 0, i;

      /* Get rid of the old primitive (if any) */
      mash_ply_loader_free_primitive (self);

      /* Create a new attribute buffer for the vertices */
      attribute_buffer = cogl_attribute_buffer_new (context,
                                                    data.vertices->len,
                                                    data.vertices->data);

      /* And describe the attributes */
      if ((data.available_props & MASH_PLY_LOADER_VERTEX_PROPS) ==
          MASH_PLY_LOADER_VERTEX_PROPS)
        {
          attributes[n_attributes++] =
            cogl_attribute_new (attribute_buffer,
                                "cogl_position_in",
                                data.n_vertex_bytes,
                                data.prop_map[0],
                                3,
                                COGL_ATTRIBUTE_TYPE_FLOAT);
        }

      if ((data.available_props & MASH_PLY_LOADER_NORMAL_PROPS) ==
          MASH_PLY_LOADER_NORMAL_PROPS)
        {
          attributes[n_attributes++] =
            cogl_attribute_new (attribute_buffer,
                                "cogl_normal_in",
                                data.n_vertex_bytes,
                                data.prop_map[3],
                                3,
                                COGL_ATTRIBUTE_TYPE_FLOAT);
        }

      if ((data.available_props & MASH_PLY_LOADER_TEX_COORD_PROPS) ==
          MASH_PLY_LOADER_TEX_COORD_PROPS)
        {
          attributes[n_attributes++] =
            cogl_attribute_new (attribute_buffer,
                                "cogl_tex_coord0_in",
                                data.n_vertex_bytes,
                                data.prop_map[6],
                                2,
                                COGL_ATTRIBUTE_TYPE_FLOAT);
        }

      if ((data.available_props & MASH_PLY_LOADER_COLOR_PROPS) ==
          MASH_PLY_LOADER_COLOR_PROPS)
        {
          attributes[n_attributes++] =
            cogl_attribute_new (attribute_buffer,
                                "cogl_color_in",
                                data.n_vertex_bytes,
                                data.prop_map[8],
                                3,
                                COGL_ATTRIBUTE_TYPE_FLOAT);
        }

      priv->primitive =
        cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                            data.vertices->len,
                                            attributes, n_attributes);
      for (i = 0; i < n_attributes; i++)
        cogl_object_unref (attributes[i]);

      indices = cogl_indices_new (context,
                                  data.indices_type,
                                  data.faces->data,
                                  data.faces->len);
      cogl_primitive_set_indices (priv->primitive,
                                  indices,
                                  data.faces->len);
      cogl_object_unref (indices);

      priv->min_vertex = data.min_vertex;
      priv->max_vertex = data.max_vertex;

      ret = TRUE;
    }

  g_free (display_name);
  g_byte_array_free (data.vertices, TRUE);
  if (data.faces)
    g_array_free (data.faces, TRUE);

  return ret;
}