[cogl-vertex-buffer] Add cogl_vertex_buffer_indices_get_for_quads

This function can be used as an efficient way of drawing groups of
quads without using GL_QUADS. It generates a VBO containing the
indices needed to render using pairs of GL_TRIANGLES. The VBO is
globally cached so that it only needs to be uploaded whenever more
indices are requested than ever before.
This commit is contained in:
Neil Roberts
2009-05-28 13:47:18 +01:00
parent 2f319ad839
commit 39cb36ba01
7 changed files with 151 additions and 1 deletions

View File

@@ -1880,3 +1880,83 @@ _cogl_vertex_buffer_free (CoglVertexBuffer *buffer)
g_slice_free (CoglVertexBuffer, buffer);
}
CoglHandle
cogl_vertex_buffer_indices_get_for_quads (guint n_indices)
{
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
/* Check if the indices would fit in a byte array */
if (n_indices <= 256 / 4 * 6)
{
/* Generate the byte array if we haven't already */
if (ctx->quad_indices_byte == COGL_INVALID_HANDLE)
{
guint8 *byte_array = g_malloc (256 / 4 * 6 * sizeof (guint8));
guint8 *p = byte_array;
int i, vert_num = 0;
for (i = 0; i < 256 / 4; i++)
{
*(p++) = vert_num + 0;
*(p++) = vert_num + 1;
*(p++) = vert_num + 2;
*(p++) = vert_num + 0;
*(p++) = vert_num + 2;
*(p++) = vert_num + 3;
vert_num += 4;
}
ctx->quad_indices_byte
= cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_BYTE,
byte_array,
256 / 4 * 6);
g_free (byte_array);
}
return ctx->quad_indices_byte;
}
else
{
if (ctx->quad_indices_short_len < n_indices)
{
guint16 *short_array;
guint16 *p;
int i, vert_num = 0;
if (ctx->quad_indices_short != COGL_INVALID_HANDLE)
cogl_handle_unref (ctx->quad_indices_short);
/* Pick a power of two >= MAX (512, n_indices) */
if (ctx->quad_indices_short_len == 0)
ctx->quad_indices_short_len = 512;
while (ctx->quad_indices_short_len < n_indices)
ctx->quad_indices_short_len *= 2;
/* Over-allocate to generate a whole number of quads */
p = short_array = g_malloc ((ctx->quad_indices_short_len
+ 5) / 6 * 6
* sizeof (guint16));
/* Fill in the complete quads */
for (i = 0; i < ctx->quad_indices_short_len; i += 6)
{
*(p++) = vert_num + 0;
*(p++) = vert_num + 1;
*(p++) = vert_num + 2;
*(p++) = vert_num + 0;
*(p++) = vert_num + 2;
*(p++) = vert_num + 3;
vert_num += 4;
}
ctx->quad_indices_short
= cogl_vertex_buffer_indices_new (COGL_INDICES_TYPE_UNSIGNED_SHORT,
short_array,
ctx->quad_indices_short_len);
g_free (short_array);
}
return ctx->quad_indices_short;
}
}