Clutter Wiki

Views
From ClutterProject
Jump to: navigation, search

Note: this is very much a work in progress, but any review is still welcome

Contents

Overview

Cogl needs a new API for submitting large amounts of vertex data to the GPU for processing. The cogl_vertex_buffer API is higher level than we often desire (it abstracts away the underlying buffer allocations and automatically sets the usage hints) and in trying to be familiar to OpenGL developers it's frankly ugly because so many arguments need to be passed to cogl_vertex_buffer_add.

The new API needs to give more raw control over allocating buffers and describing their contents similar to the control that the vertex_buffer API for OpenGL gives, but hopefully with a nicer API.

Notable Requirements:

These are currently mostly just reminders for key requirements that have affected the current design.

  1. vertex arrays should have a config step and a separate allocate step so we can keep the opportunity to give the driver hints about how the memory should be allocated. By default you don't have to care because the allocate step can be done automatically if the user chooses not to do it explicitly but notably we don't have cogl_vertex_array_new return an error state since that would imply doing the allocation up front.
  1. We specifically considered the case of having multiple gl_Color attributes in the same buffer so they can be switched between without having to bind a new buffer.

Dependencies

CoglBuffer
is an abstract base class which CoglVertexArray derives from.

Design

It's a CoglBuffer sub class.

Initially it'll mostly just be a token sub-class of CoglBuffer that implies the data contains vertices.

vertex_array_new (bytes);

Note: by having a separation between instantiating a vertex array and allocating it we can give hints to the driver here.

vertex_array_allocate (&error)

This call is optional. If's not called explicitly then it will be done automatically when drawing or setting data. By explicitly controlling the allocate though an application can gracefully handle failures, e.g. due to a lack of resources.


CoglVertexAttributes

See the page CoglVertexAttribute for details of how to describe attributes contained inside a vertex array.

CoglVertexIndices:

Another CoglBuffer subclass

cogl_vertex_indices_new (type, client_array, len)
cogl_vertex_indices_new_from_buffer (buffer, type, offset, len)
  • Can be used if you want indices in a CoglVertexArray
cogl_get_indices_for_quads

Drawing example

typedef struct
{
  float x, y;
  guint8 r, g, b, a;
} MyVertex;

MyVertex vertices[] = {..};

CoglVertexArray *array = vertex_array_new (sizeof (vertices));

CoglVertexAttribute *attrib0 = cogl_vertex_attribute_new (array,
                                                          "gl_Position",
                                                          sizeof (MyVertex),
                                                          offsetof (MyVertex, x),
                                                          2,
                                                          COGL_VERTEX_ATTRIBUTE_TYPE_FLOAT);
CoglVertexAttribute *attrib1 = cogl_vertex_attribute_new (array,
                                                          "gl_Color",
                                                          sizeof (MyVertex),
                                                          offsetof (MyVertex, r),
                                                          4,
                                                          COGL_VERTEX_ATTRIBUTE_TYPE_UNSIGNED_BYTE);

cogl_object_unref (array);

cogl_vertex_attributes_draw (COGL_DRAW_MODE_TRIANGLES, 4, attrib0, attrib1, NULL);

cogl_object_unref (attrib0);
cogl_object_unref (attrib1);

Example with two color attributes to toggle between:

MyVertex vertices[] = 
{
    V2T2C4C4
};

CoglVertexArray *array = vertex_array_new (sizeof (vertices));

CoglVertexAttribute *attrib0 = 
  cogl_vertex_attribute_new (array, "gl_Position", sizeof (MyVertex), offsetof (x), 2, FLOAT)
CoglVertexAttribute *attrib1 =
  cogl_vertex_attribute_new (array, "gl_MultiTexCoord0", sizeof (MyVertex), offsetof (s), 2, FLOAT)
CoglVertexAttribute *attrib2 =
  cogl_vertex_attribute_new (array, "gl_Color", sizeof (MyVertex), offsetof (r0), 4, UBYTE)
CoglVertexAttribute *attrib3 =
  cogl_vertex_attribute_new (array, "gl_Color", sizeof (MyVertex), offsetof (r1), 4, UBYTE)

cogl_object_unref (array);

cogl_vertex_attributes_draw (COGL_DRAW_MODE_TRIANGLES, 4, attrib0, attrib1, attrib2, NULL);
cogl_vertex_attributes_draw (COGL_DRAW_MODE_TRIANGLES, 4, attrib0, attrib1, attrib3, NULL);

cogl_object_unref (attrib0);
cogl_object_unref (attrib1);
cogl_object_unref (attrib2);
cogl_object_unref (attrib3);

Example with indices:

FIXME

cogl_vertex_attributes_draw_with_indices ()
cogl_vertex_attributes_draw_range_with_indices ()

Issues:

  • inconsistent use of "with_indices" or "indexed"
  • Its unclear if additional convenience APIs are needed?
  • Make sure the design will work in a renderlist scenario. I.e. will we be able to handle copy-on-write as needs be for retained CoglVertices objects in a renderlist if someone tries to modify any of the attributes?

Future api additions:

It would be possible to cast a pixel array into a vertex array if we had a function like:

vertex_array_new_from_buffer ()
Personal tools