Use glDrawRangeElements to share vertices

When drawing a quad from cogl_texture_multiple_rectangles share two of
the vertices in each triangle by using indices.
This commit is contained in:
Neil Roberts 2008-12-09 13:02:28 +00:00
parent 3b5eb3afeb
commit 778a9f7d67
3 changed files with 88 additions and 74 deletions

View File

@ -58,6 +58,8 @@ cogl_create_context ()
_context->texture_handles = NULL; _context->texture_handles = NULL;
_context->texture_vertices = g_array_new (FALSE, FALSE, _context->texture_vertices = g_array_new (FALSE, FALSE,
sizeof (CoglTextureGLVertex)); sizeof (CoglTextureGLVertex));
_context->texture_indices = g_array_new (FALSE, FALSE,
sizeof (GLushort));
_context->fbo_handles = NULL; _context->fbo_handles = NULL;
_context->draw_buffer = COGL_WINDOW_BUFFER; _context->draw_buffer = COGL_WINDOW_BUFFER;
@ -150,6 +152,8 @@ cogl_destroy_context ()
if (_context->texture_vertices) if (_context->texture_vertices)
g_array_free (_context->texture_vertices, TRUE); g_array_free (_context->texture_vertices, TRUE);
if (_context->texture_indices)
g_array_free (_context->texture_indices, TRUE);
g_free (_context); g_free (_context);
} }

View File

@ -64,6 +64,7 @@ typedef struct
/* Textures */ /* Textures */
GArray *texture_handles; GArray *texture_handles;
GArray *texture_vertices; GArray *texture_vertices;
GArray *texture_indices;
/* The gl texture number that the above vertices apply to. This to /* The gl texture number that the above vertices apply to. This to
detect when a different slice is encountered so that the vertices detect when a different slice is encountered so that the vertices
can be flushed */ can be flushed */

View File

@ -1927,12 +1927,64 @@ _cogl_texture_flush_vertices (void)
sizeof (CoglTextureGLVertex), p->t ) ); sizeof (CoglTextureGLVertex), p->t ) );
GE( glBindTexture (ctx->texture_target, ctx->texture_current) ); GE( glBindTexture (ctx->texture_target, ctx->texture_current) );
GE( glDrawArrays (GL_TRIANGLES, 0, ctx->texture_vertices->len) ); GE( ctx->pf_glDrawRangeElements (GL_TRIANGLES,
0, ctx->texture_vertices->len - 1,
ctx->texture_indices->len,
GL_UNSIGNED_SHORT,
ctx->texture_indices->data) );
g_array_set_size (ctx->texture_vertices, 0); g_array_set_size (ctx->texture_vertices, 0);
g_array_set_size (ctx->texture_indices, 0);
} }
} }
static void
_cogl_texture_add_quad_vertices (GLfloat x1, GLfloat y1,
GLfloat x2, GLfloat y2,
GLfloat tx1, GLfloat ty1,
GLfloat tx2, GLfloat ty2)
{
CoglTextureGLVertex *p;
GLushort first_vert;
GLushort *q;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Add the four vertices of the quad to the list of queued
vertices */
first_vert = ctx->texture_vertices->len;
g_array_set_size (ctx->texture_vertices, first_vert + 4);
p = &g_array_index (ctx->texture_vertices, CoglTextureGLVertex, first_vert);
p->v[0] = x1; p->v[1] = y1;
p->t[0] = tx1; p->t[1] = ty1;
p++;
p->v[0] = x1; p->v[1] = y2;
p->t[0] = tx1; p->t[1] = ty2;
p++;
p->v[0] = x2; p->v[1] = y2;
p->t[0] = tx2; p->t[1] = ty2;
p++;
p->v[0] = x2; p->v[1] = y1;
p->t[0] = tx2; p->t[1] = ty1;
p++;
/* Add two triangles to the list of indices. That makes six new
indices but two of the vertices in the triangles are shared. */
g_array_set_size (ctx->texture_indices,
ctx->texture_indices->len + 6);
q = &g_array_index (ctx->texture_indices, GLushort,
ctx->texture_indices->len - 6);
*(q++) = first_vert + 0;
*(q++) = first_vert + 1;
*(q++) = first_vert + 3;
*(q++) = first_vert + 1;
*(q++) = first_vert + 2;
*(q++) = first_vert + 3;
}
static void static void
_cogl_texture_quad_sw (CoglTexture *tex, _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed x1, CoglFixed x1,
@ -1944,17 +1996,16 @@ _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed tx2, CoglFixed tx2,
CoglFixed ty2) CoglFixed ty2)
{ {
CoglSpanIter iter_x , iter_y; CoglSpanIter iter_x , iter_y;
CoglFixed tw , th; CoglFixed tw , th;
CoglFixed tqx , tqy; CoglFixed tqx , tqy;
CoglFixed first_tx , first_ty; CoglFixed first_tx , first_ty;
CoglFixed first_qx , first_qy; CoglFixed first_qx , first_qy;
CoglFixed slice_tx1 , slice_ty1; CoglFixed slice_tx1 , slice_ty1;
CoglFixed slice_tx2 , slice_ty2; CoglFixed slice_tx2 , slice_ty2;
CoglFixed slice_qx1 , slice_qy1; CoglFixed slice_qx1 , slice_qy1;
CoglFixed slice_qx2 , slice_qy2; CoglFixed slice_qx2 , slice_qy2;
GLuint gl_handle; GLuint gl_handle;
CoglTextureGLVertex *p;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -2098,35 +2149,14 @@ _cogl_texture_quad_sw (CoglTexture *tex,
ctx->texture_target = tex->gl_target; ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle; ctx->texture_current = gl_handle;
/* Add the quad to the list of queued vertices */ _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1),
g_array_set_size (ctx->texture_vertices, COGL_FIXED_TO_FLOAT (slice_qy1),
ctx->texture_vertices->len + 6); COGL_FIXED_TO_FLOAT (slice_qx2),
p = &g_array_index (ctx->texture_vertices, CoglTextureGLVertex, COGL_FIXED_TO_FLOAT (slice_qy2),
ctx->texture_vertices->len - 6); COGL_FIXED_TO_FLOAT (slice_tx1),
COGL_FIXED_TO_FLOAT (slice_ty1),
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x) COGL_FIXED_TO_FLOAT (slice_tx2),
COGL_FIXED_TO_FLOAT (slice_ty2));
p->v[0] = CFX_F (slice_qx1); p->v[1] = CFX_F (slice_qy2);
p->t[0] = CFX_F (slice_tx1); p->t[1] = CFX_F (slice_ty2);
p++;
p->v[0] = CFX_F (slice_qx2); p->v[1] = CFX_F (slice_qy2);
p->t[0] = CFX_F (slice_tx2); p->t[1] = CFX_F (slice_ty2);
p++;
p->v[0] = CFX_F (slice_qx1); p->v[1] = CFX_F (slice_qy1);
p->t[0] = CFX_F (slice_tx1); p->t[1] = CFX_F (slice_ty1);
p++;
p->v[0] = CFX_F (slice_qx1); p->v[1] = CFX_F (slice_qy1);
p->t[0] = CFX_F (slice_tx1); p->t[1] = CFX_F (slice_ty1);
p++;
p->v[0] = CFX_F (slice_qx2); p->v[1] = CFX_F (slice_qy2);
p->t[0] = CFX_F (slice_tx2); p->t[1] = CFX_F (slice_ty2);
p++;
p->v[0] = CFX_F (slice_qx2); p->v[1] = CFX_F (slice_qy1);
p->t[0] = CFX_F (slice_tx2); p->t[1] = CFX_F (slice_ty1);
p++;
#undef CFX_F
} }
} }
} }
@ -2142,11 +2172,10 @@ _cogl_texture_quad_hw (CoglTexture *tex,
CoglFixed tx2, CoglFixed tx2,
CoglFixed ty2) CoglFixed ty2)
{ {
GLuint gl_handle; GLuint gl_handle;
CoglTexSliceSpan *x_span; CoglTexSliceSpan *x_span;
CoglTexSliceSpan *y_span; CoglTexSliceSpan *y_span;
CoglTextureGLVertex *p; GLenum wrap_mode;
GLenum wrap_mode;
#if COGL_DEBUG #if COGL_DEBUG
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
@ -2190,11 +2219,6 @@ _cogl_texture_quad_hw (CoglTexture *tex,
ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size; ty1 = ty1 * (y_span->size - y_span->waste) / y_span->size;
ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size; ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size;
/* Add the quad to the list of queued vertices */
g_array_set_size (ctx->texture_vertices, ctx->texture_vertices->len + 6);
p = &g_array_index (ctx->texture_vertices, CoglTextureGLVertex,
ctx->texture_vertices->len - 6);
/* Denormalize texture coordinates for rectangle textures */ /* Denormalize texture coordinates for rectangle textures */
if (tex->gl_target == GL_TEXTURE_RECTANGLE_ARB) if (tex->gl_target == GL_TEXTURE_RECTANGLE_ARB)
{ {
@ -2204,29 +2228,14 @@ _cogl_texture_quad_hw (CoglTexture *tex,
ty2 *= y_span->size; ty2 *= y_span->size;
} }
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x) _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (x1),
COGL_FIXED_TO_FLOAT (y1),
p->v[0] = CFX_F (x1); p->v[1] = CFX_F (y2); COGL_FIXED_TO_FLOAT (x2),
p->t[0] = CFX_F (tx1); p->t[1] = CFX_F (ty2); COGL_FIXED_TO_FLOAT (y2),
p++; COGL_FIXED_TO_FLOAT (tx1),
p->v[0] = CFX_F (x2); p->v[1] = CFX_F (y2); COGL_FIXED_TO_FLOAT (ty1),
p->t[0] = CFX_F (tx2); p->t[1] = CFX_F (ty2); COGL_FIXED_TO_FLOAT (tx2),
p++; COGL_FIXED_TO_FLOAT (ty2));
p->v[0] = CFX_F (x1); p->v[1] = CFX_F (y1);
p->t[0] = CFX_F (tx1); p->t[1] = CFX_F (ty1);
p++;
p->v[0] = CFX_F (x1); p->v[1] = CFX_F (y1);
p->t[0] = CFX_F (tx1); p->t[1] = CFX_F (ty1);
p++;
p->v[0] = CFX_F (x2); p->v[1] = CFX_F (y2);
p->t[0] = CFX_F (tx2); p->t[1] = CFX_F (ty2);
p++;
p->v[0] = CFX_F (x2); p->v[1] = CFX_F (y1);
p->t[0] = CFX_F (tx2); p->t[1] = CFX_F (ty1);
p++;
#undef CFX_F
} }
void void