Merge commit 'origin/master' into cogl-material

Conflicts:

	clutter/clutter-texture.c
	clutter/cogl/cogl-texture.h
	clutter/cogl/gles/cogl-context.c
	clutter/cogl/gles/cogl-context.h
This commit is contained in:
Robert Bragg 2009-01-13 13:37:38 +00:00
commit a0c5690d55
13 changed files with 526 additions and 325 deletions

View File

@ -416,6 +416,29 @@ void cogl_material_rectangle (CoglFixed x1,
gint tex_coords_len, gint tex_coords_len,
const CoglFixed *tex_coords); const CoglFixed *tex_coords);
/**
* cogl_texture_multiple_rectangles:
* @handle: a @CoglHandle.
* @verts: an array of vertices
* @n_rects: number of rectangles to draw
*
* Draws a series of rectangles in the same way that
* cogl_texture_rectangle() does. In some situations it can give a
* significant performance boost to use this function rather than
* calling cogl_texture_rectangle() separately for each rectangle.
*
* @verts should point to an array of #CoglFixed<!-- -->s with
* @n_rects * 8 elements. Each group of 8 values corresponds to the
* parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same
* meaning as in cogl_texture_rectangle().
*
* Since: 1.0
*/
void cogl_texture_multiple_rectangles
(CoglHandle handle,
const CoglFixed *verts,
guint n_rects);
G_END_DECLS G_END_DECLS
#endif /* __COGL_TEXTURE_H__ */ #endif /* __COGL_TEXTURE_H__ */

View File

@ -86,27 +86,29 @@ typedef struct _CoglTextureVertex CoglTextureVertex;
/** /**
* CoglPixelFormat: * CoglPixelFormat:
* @COGL_PIXEL_FORMAT_ANY: * @COGL_PIXEL_FORMAT_ANY: Any format
* @COGL_PIXEL_FORMAT_A_8: * @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask
* @COGL_PIXEL_FORMAT_RGB_888: * @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
* @COGL_PIXEL_FORMAT_BGR_888: * @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
* @COGL_PIXEL_FORMAT_RGBA_8888: * @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
* @COGL_PIXEL_FORMAT_BGRA_8888: * @COGL_PIXEL_FORMAT_YUV: FIXME
* @COGL_PIXEL_FORMAT_ARGB_8888: * @COGL_PIXEL_FORMAT_G_8: FIXME
* @COGL_PIXEL_FORMAT_ABGR_8888: * @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
* @COGL_PIXEL_FORMAT_RGBA_8888_PRE: * @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
* @COGL_PIXEL_FORMAT_BGRA_8888_PRE: * @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits
* @COGL_PIXEL_FORMAT_ARGB_8888_PRE: * @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits
* @COGL_PIXEL_FORMAT_ABGR_8888_PRE: * @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits
* @COGL_PIXEL_FORMAT_RGB_565: * @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits
* @COGL_PIXEL_FORMAT_RGBA_4444: * @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits
* @COGL_PIXEL_FORMAT_RGBA_5551: * @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits
* @COGL_PIXEL_FORMAT_RGBA_4444_PRE: * @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits
* @COGL_PIXEL_FORMAT_RGBA_5551_PRE: * @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits
* @COGL_PIXEL_FORMAT_YUV: * @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits
* @COGL_PIXEL_FORMAT_G_8: * @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits
* *
* Pixel formats used by COGL. * Pixel formats used by COGL.
*
* Since: 0.8
*/ */
typedef enum typedef enum
{ {
@ -173,19 +175,21 @@ typedef enum
/** /**
* CoglFeatureFlags: * CoglFeatureFlags:
* @COGL_FEATURE_TEXTURE_RECTANGLE: * @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support
* @COGL_FEATURE_TEXTURE_NPOT: * @COGL_FEATURE_TEXTURE_NPOT: ARB_texture_non_power_of_two support
* @COGL_FEATURE_TEXTURE_YUV: * @COGL_FEATURE_TEXTURE_YUV: ycbcr conversion support
* @COGL_FEATURE_TEXTURE_READ_PIXELS: * @COGL_FEATURE_TEXTURE_READ_PIXELS: glReadPixels() support
* @COGL_FEATURE_SHADERS_GLSL: * @COGL_FEATURE_SHADERS_GLSL: GLSL support
* @COGL_FEATURE_OFFSCREEN: * @COGL_FEATURE_OFFSCREEN: FBO support
* @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: * @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: Multisample support on FBOs
* @COGL_FEATURE_OFFSCREEN_BLIT: * @COGL_FEATURE_OFFSCREEN_BLIT: Blit support on FBOs
* @COGL_FEATURE_FOUR_CLIP_PLANES: * @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available
* @COGL_FEATURE_STENCIL_BUFFER: * @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support
* @COGL_FEATURE_VBOS: * @COGL_FEATURE_VBOS: VBO support
* *
* Flags for the supported features. * Flags for the supported features.
*
* Since: 0.8
*/ */
typedef enum typedef enum
{ {
@ -204,11 +208,13 @@ typedef enum
/** /**
* CoglBufferTarget: * CoglBufferTarget:
* @COGL_WINDOW_BUFFER: * @COGL_WINDOW_BUFFER: FIXME
* @COGL_MASK_BUFFER: * @COGL_MASK_BUFFER: FIXME
* @COGL_OFFSCREEN_BUFFER: * @COGL_OFFSCREEN_BUFFER: FIXME
* *
* Target flags for FBOs.
* *
* Since: 0.8
*/ */
typedef enum typedef enum
{ {

View File

@ -5,6 +5,7 @@ INCLUDES = \
-I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \ -I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \
-I$(top_builddir)/clutter \ -I$(top_builddir)/clutter \
-I$(top_builddir)/clutter/cogl \ -I$(top_builddir)/clutter/cogl \
-DG_LOG_DOMAIN=\"Cogl-Common\" \
-DCLUTTER_COMPILATION \ -DCLUTTER_COMPILATION \
$(CLUTTER_CFLAGS) \ $(CLUTTER_CFLAGS) \
$(CLUTTER_DEBUG_CFLAGS) \ $(CLUTTER_DEBUG_CFLAGS) \

View File

@ -209,6 +209,8 @@ COGL_HANDLE_DEFINE (Mesh, mesh, mesh_handles);
* *
* This creates a Cogl handle for a new mesh that you can then start to add * This creates a Cogl handle for a new mesh that you can then start to add
* attributes too. * attributes too.
*
* Return value: a new #CoglHandle
*/ */
CoglHandle CoglHandle
cogl_mesh_new (guint n_vertices) cogl_mesh_new (guint n_vertices)

View File

@ -120,6 +120,7 @@ cogl_texture_set_region
cogl_texture_ref cogl_texture_ref
cogl_texture_unref cogl_texture_unref
cogl_texture_rectangle cogl_texture_rectangle
cogl_texture_multiple_rectangles
cogl_texture_polygon cogl_texture_polygon
</SECTION> </SECTION>

View File

@ -22,6 +22,7 @@ INCLUDES = \
-I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \ -I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \
-I$(top_builddir)/clutter \ -I$(top_builddir)/clutter \
-I$(top_builddir)/clutter/cogl \ -I$(top_builddir)/clutter/cogl \
-DG_LOG_DOMAIN=\"Cogl-GL\" \
-DCLUTTER_COMPILATION \ -DCLUTTER_COMPILATION \
$(CLUTTER_CFLAGS) \ $(CLUTTER_CFLAGS) \
$(CLUTTER_DEBUG_CFLAGS) \ $(CLUTTER_DEBUG_CFLAGS) \

View File

@ -56,8 +56,10 @@ cogl_create_context ()
_context->last_path = 0; _context->last_path = 0;
_context->texture_handles = NULL; _context->texture_handles = NULL;
_context->texture_vertices_size = 0; _context->texture_vertices = g_array_new (FALSE, FALSE,
_context->texture_vertices = NULL; sizeof (CoglTextureGLVertex));
_context->texture_indices = g_array_new (FALSE, FALSE,
sizeof (GLushort));
_context->material_handles = NULL; _context->material_handles = NULL;
_context->material_layer_handles = NULL; _context->material_layer_handles = NULL;
@ -153,6 +155,11 @@ cogl_destroy_context ()
if (_context->program_handles) if (_context->program_handles)
g_array_free (_context->program_handles, TRUE); g_array_free (_context->program_handles, TRUE);
if (_context->texture_vertices)
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

@ -63,8 +63,14 @@ typedef struct
/* Textures */ /* Textures */
GArray *texture_handles; GArray *texture_handles;
CoglTextureGLVertex *texture_vertices; GArray *texture_vertices;
gulong texture_vertices_size; GArray *texture_indices;
/* The gl texture number that the above vertices apply to. This to
detect when a different slice is encountered so that the vertices
can be flushed */
GLuint texture_current;
GLenum texture_target;
GLenum texture_wrap_mode;
/* Materials */ /* Materials */
GArray *material_handles; GArray *material_handles;

View File

@ -1911,6 +1911,95 @@ cogl_texture_get_data (CoglHandle handle,
return byte_size; return byte_size;
} }
static void
_cogl_texture_flush_vertices (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->texture_vertices->len > 0)
{
int needed_indices;
CoglTextureGLVertex *p
= (CoglTextureGLVertex *) ctx->texture_vertices->data;
/* The indices are always the same sequence regardless of the
vertices so we only need to change it if there are more
vertices than ever before */
needed_indices = ctx->texture_vertices->len / 4 * 6;
if (needed_indices > ctx->texture_indices->len)
{
int old_len = ctx->texture_indices->len;
int vert_num = old_len / 6 * 4;
int i;
GLushort *q;
/* Add two triangles for each quad 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, needed_indices);
q = &g_array_index (ctx->texture_indices, GLushort, old_len);
for (i = old_len;
i < ctx->texture_indices->len;
i += 6, vert_num += 4)
{
*(q++) = vert_num + 0;
*(q++) = vert_num + 1;
*(q++) = vert_num + 3;
*(q++) = vert_num + 1;
*(q++) = vert_num + 2;
*(q++) = vert_num + 3;
}
}
GE( glVertexPointer (2, GL_FLOAT,
sizeof (CoglTextureGLVertex), p->v ) );
GE( glTexCoordPointer (2, GL_FLOAT,
sizeof (CoglTextureGLVertex), p->t ) );
GE( glBindTexture (ctx->texture_target, ctx->texture_current) );
GE( ctx->pf_glDrawRangeElements (GL_TRIANGLES,
0, ctx->texture_vertices->len - 1,
needed_indices,
GL_UNSIGNED_SHORT,
ctx->texture_indices->data) );
g_array_set_size (ctx->texture_vertices, 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;
_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++;
}
static void static void
_cogl_texture_quad_sw (CoglTexture *tex, _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed x1, CoglFixed x1,
@ -1931,11 +2020,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
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;
GLfloat tex_coords[8];
GLfloat quad_coords[8];
GLuint gl_handle; GLuint gl_handle;
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY);
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1943,26 +2028,13 @@ _cogl_texture_quad_sw (CoglTexture *tex,
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
#endif #endif
/* Prepare GL state */
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
else
enable_flags |= COGL_ENABLE_TEXTURE_2D;
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
{
enable_flags |= COGL_ENABLE_BLEND;
}
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
/* We can't use hardware repeat so we need to set clamp to edge /* We can't use hardware repeat so we need to set clamp to edge
otherwise it might pull in edge pixels from the other side */ otherwise it might pull in edge pixels from the other side */
if (ctx->texture_vertices->len > 0
&& ctx->texture_wrap_mode != GL_CLAMP_TO_EDGE)
_cogl_texture_flush_vertices ();
_cogl_texture_set_wrap_mode_parameter (tex, GL_CLAMP_TO_EDGE); _cogl_texture_set_wrap_mode_parameter (tex, GL_CLAMP_TO_EDGE);
ctx->texture_wrap_mode = GL_CLAMP_TO_EDGE;
/* If the texture coordinates are backwards then swap both the /* If the texture coordinates are backwards then swap both the
geometry and texture coordinates so that the texture will be geometry and texture coordinates so that the texture will be
@ -1987,9 +2059,6 @@ _cogl_texture_quad_sw (CoglTexture *tex,
ty2 = temp; ty2 = temp;
} }
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
/* Scale ratio from texture to quad widths */ /* Scale ratio from texture to quad widths */
tw = COGL_FIXED_FROM_INT (tex->bitmap.width); tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
th = COGL_FIXED_FROM_INT (tex->bitmap.height); th = COGL_FIXED_FROM_INT (tex->bitmap.height);
@ -2087,24 +2156,22 @@ _cogl_texture_quad_sw (CoglTexture *tex,
iter_y.index * iter_x.array->len + iter_y.index * iter_x.array->len +
iter_x.index); iter_x.index);
GE( glBindTexture (tex->gl_target, gl_handle) ); /* If we're using a different texture from the one already queued
then flush the vertices */
if (ctx->texture_vertices->len > 0
&& gl_handle != ctx->texture_current)
_cogl_texture_flush_vertices ();
ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle;
#define CFX_F COGL_FIXED_TO_FLOAT _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1),
COGL_FIXED_TO_FLOAT (slice_qy1),
/* Draw textured quad */ COGL_FIXED_TO_FLOAT (slice_qx2),
tex_coords[0] = CFX_F(slice_tx1); tex_coords[1] = CFX_F(slice_ty2); COGL_FIXED_TO_FLOAT (slice_qy2),
tex_coords[2] = CFX_F(slice_tx2); tex_coords[3] = CFX_F(slice_ty2); COGL_FIXED_TO_FLOAT (slice_tx1),
tex_coords[4] = CFX_F(slice_tx1); tex_coords[5] = CFX_F(slice_ty1); COGL_FIXED_TO_FLOAT (slice_ty1),
tex_coords[6] = CFX_F(slice_tx2); tex_coords[7] = CFX_F(slice_ty1); COGL_FIXED_TO_FLOAT (slice_tx2),
COGL_FIXED_TO_FLOAT (slice_ty2));
quad_coords[0] = CFX_F(slice_qx1); quad_coords[1] = CFX_F(slice_qy2);
quad_coords[2] = CFX_F(slice_qx2); quad_coords[3] = CFX_F(slice_qy2);
quad_coords[4] = CFX_F(slice_qx1); quad_coords[5] = CFX_F(slice_qy1);
quad_coords[6] = CFX_F(slice_qx2); quad_coords[7] = CFX_F(slice_qy1);
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
#undef CFX_F
} }
} }
} }
@ -2120,13 +2187,10 @@ _cogl_texture_quad_hw (CoglTexture *tex,
CoglFixed tx2, CoglFixed tx2,
CoglFixed ty2) CoglFixed ty2)
{ {
GLfloat tex_coords[8];
GLfloat quad_coords[8];
GLuint gl_handle; GLuint gl_handle;
CoglTexSliceSpan *x_span; CoglTexSliceSpan *x_span;
CoglTexSliceSpan *y_span; CoglTexSliceSpan *y_span;
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY GLenum wrap_mode;
| COGL_ENABLE_TEXCOORD_ARRAY);
#if COGL_DEBUG #if COGL_DEBUG
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
@ -2134,24 +2198,6 @@ _cogl_texture_quad_hw (CoglTexture *tex,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Prepare GL state */
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
else
enable_flags |= COGL_ENABLE_TEXTURE_2D;
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
{
enable_flags |= COGL_ENABLE_BLEND;
}
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
/* If the texture coords are all in the range [0,1] then we want to /* If the texture coords are all in the range [0,1] then we want to
clamp the coords to the edge otherwise it can pull in edge pixels clamp the coords to the edge otherwise it can pull in edge pixels
from the wrong side when scaled */ from the wrong side when scaled */
@ -2159,16 +2205,24 @@ _cogl_texture_quad_hw (CoglTexture *tex,
&& tx2 >= 0 && tx2 <= COGL_FIXED_1 && tx2 >= 0 && tx2 <= COGL_FIXED_1
&& ty1 >= 0 && ty1 <= COGL_FIXED_1 && ty1 >= 0 && ty1 <= COGL_FIXED_1
&& ty2 >= 0 && ty2 <= COGL_FIXED_1) && ty2 >= 0 && ty2 <= COGL_FIXED_1)
_cogl_texture_set_wrap_mode_parameter (tex, GL_CLAMP_TO_EDGE); wrap_mode = GL_CLAMP_TO_EDGE;
else else
_cogl_texture_set_wrap_mode_parameter (tex, GL_REPEAT); wrap_mode = GL_REPEAT;
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
/* Pick and bind opengl texture object */ /* Pick and bind opengl texture object */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0); gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
GE( glBindTexture (tex->gl_target, gl_handle) );
/* If we're using a different texture from the one already queued
then flush the vertices */
if (ctx->texture_vertices->len > 0
&& (gl_handle != ctx->texture_current
|| ctx->texture_wrap_mode != wrap_mode))
_cogl_texture_flush_vertices ();
ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle;
ctx->texture_wrap_mode = wrap_mode;
_cogl_texture_set_wrap_mode_parameter (tex, wrap_mode);
/* Don't include the waste in the texture coordinates */ /* Don't include the waste in the texture coordinates */
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0); x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
@ -2189,36 +2243,26 @@ _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),
/* Draw textured quad */ COGL_FIXED_TO_FLOAT (x2),
tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2); COGL_FIXED_TO_FLOAT (y2),
tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2); COGL_FIXED_TO_FLOAT (tx1),
tex_coords[4] = CFX_F(tx1); tex_coords[5] = CFX_F(ty1); COGL_FIXED_TO_FLOAT (ty1),
tex_coords[6] = CFX_F(tx2); tex_coords[7] = CFX_F(ty1); COGL_FIXED_TO_FLOAT (tx2),
COGL_FIXED_TO_FLOAT (ty2));
quad_coords[0] = CFX_F(x1); quad_coords[1] = CFX_F(y2);
quad_coords[2] = CFX_F(x2); quad_coords[3] = CFX_F(y2);
quad_coords[4] = CFX_F(x1); quad_coords[5] = CFX_F(y1);
quad_coords[6] = CFX_F(x2); quad_coords[7] = CFX_F(y1);
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
#undef CFX_F
} }
void void
cogl_texture_rectangle (CoglHandle handle, cogl_texture_multiple_rectangles (CoglHandle handle,
CoglFixed x1, const CoglFixed *verts,
CoglFixed y1, guint n_rects)
CoglFixed x2,
CoglFixed y2,
CoglFixed tx1,
CoglFixed ty1,
CoglFixed tx2,
CoglFixed ty2)
{ {
CoglTexture *tex; CoglTexture *tex;
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Check if valid texture */ /* Check if valid texture */
if (!cogl_is_texture (handle)) if (!cogl_is_texture (handle))
@ -2235,22 +2279,73 @@ cogl_texture_rectangle (CoglHandle handle,
if (tex->slice_gl_handles->len == 0) if (tex->slice_gl_handles->len == 0)
return; return;
if (tx1 == tx2 || ty1 == ty2) /* Prepare GL state */
return; if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
/* If there is only one GL texture and either the texture is NPOT
(no waste) or all of the coordinates are in the range [0,1] then
we can use hardware tiling */
if (tex->slice_gl_handles->len == 1
&& ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
&& tex->gl_target == GL_TEXTURE_2D)
|| (tx1 >= 0 && tx1 <= COGL_FIXED_1
&& tx2 >= 0 && tx2 <= COGL_FIXED_1
&& ty1 >= 0 && ty1 <= COGL_FIXED_1
&& ty2 >= 0 && ty2 <= COGL_FIXED_1)))
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
else else
_cogl_texture_quad_sw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2); enable_flags |= COGL_ENABLE_TEXTURE_2D;
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
enable_flags |= COGL_ENABLE_BLEND;
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
g_array_set_size (ctx->texture_vertices, 0);
while (n_rects-- > 0)
{
if (verts[4] != verts[6] && verts[5] != verts[7])
{
/* If there is only one GL texture and either the texture is
NPOT (no waste) or all of the coordinates are in the
range [0,1] then we can use hardware tiling */
if (tex->slice_gl_handles->len == 1
&& ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
&& tex->gl_target == GL_TEXTURE_2D)
|| (verts[4] >= 0 && verts[4] <= COGL_FIXED_1
&& verts[6] >= 0 && verts[6] <= COGL_FIXED_1
&& verts[5] >= 0 && verts[5] <= COGL_FIXED_1
&& verts[7] >= 0 && verts[7] <= COGL_FIXED_1)))
_cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]);
else
_cogl_texture_quad_sw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]);
}
verts += 8;
}
_cogl_texture_flush_vertices ();
}
void
cogl_texture_rectangle (CoglHandle handle,
CoglFixed x1,
CoglFixed y1,
CoglFixed x2,
CoglFixed y2,
CoglFixed tx1,
CoglFixed ty1,
CoglFixed tx2,
CoglFixed ty2)
{
CoglFixed verts[8];
verts[0] = x1;
verts[1] = y1;
verts[2] = x2;
verts[3] = y2;
verts[4] = tx1;
verts[5] = ty1;
verts[6] = tx2;
verts[7] = ty2;
cogl_texture_multiple_rectangles (handle, verts, 1);
} }
void void
@ -2299,22 +2394,8 @@ cogl_texture_polygon (CoglHandle handle,
/* Make sure there is enough space in the global texture vertex /* Make sure there is enough space in the global texture vertex
array. This is used so we can render the polygon with a single array. This is used so we can render the polygon with a single
call to OpenGL but still support any number of vertices */ call to OpenGL but still support any number of vertices */
if (ctx->texture_vertices_size < n_vertices) g_array_set_size (ctx->texture_vertices, n_vertices);
{ p = (CoglTextureGLVertex *) ctx->texture_vertices->data;
guint nsize = ctx->texture_vertices_size;
if (nsize == 0)
nsize = 1;
do
nsize *= 2;
while (nsize < n_vertices);
ctx->texture_vertices_size = nsize;
ctx->texture_vertices = g_realloc (ctx->texture_vertices,
nsize
* sizeof (CoglTextureGLVertex));
}
/* Prepare GL state */ /* Prepare GL state */
enable_flags = (COGL_ENABLE_VERTEX_ARRAY enable_flags = (COGL_ENABLE_VERTEX_ARRAY
@ -2332,14 +2413,12 @@ cogl_texture_polygon (CoglHandle handle,
if (use_color) if (use_color)
{ {
enable_flags |= COGL_ENABLE_COLOR_ARRAY; enable_flags |= COGL_ENABLE_COLOR_ARRAY;
GE( glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (CoglTextureGLVertex), GE( glColorPointer (4, GL_UNSIGNED_BYTE,
ctx->texture_vertices[0].c) ); sizeof (CoglTextureGLVertex), p->c) );
} }
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), p->v ) );
ctx->texture_vertices[0].v) ); GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex), p->t ) );
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex),
ctx->texture_vertices[0].t) );
cogl_enable (enable_flags); cogl_enable (enable_flags);
@ -2362,9 +2441,11 @@ cogl_texture_polygon (CoglHandle handle,
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, tex_num++); gl_handle = g_array_index (tex->slice_gl_handles, GLuint, tex_num++);
p = (CoglTextureGLVertex *) ctx->texture_vertices->data;
/* Convert the vertices into an array of GLfloats ready to pass to /* Convert the vertices into an array of GLfloats ready to pass to
OpenGL */ OpenGL */
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++) for (i = 0; i < n_vertices; i++, p++)
{ {
CoglFixed tx, ty; CoglFixed tx, ty;

View File

@ -22,6 +22,7 @@ INCLUDES = \
-I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \ -I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \
-I$(top_builddir)/clutter \ -I$(top_builddir)/clutter \
-I$(top_builddir)/clutter/cogl \ -I$(top_builddir)/clutter/cogl \
-DG_LOG_DOMAIN=\"Cogl-GLES\" \
-DCLUTTER_COMPILATION \ -DCLUTTER_COMPILATION \
$(CLUTTER_CFLAGS) \ $(CLUTTER_CFLAGS) \
$(CLUTTER_DEBUG_CFLAGS) \ $(CLUTTER_DEBUG_CFLAGS) \

View File

@ -59,8 +59,11 @@ cogl_create_context ()
_context->last_path = 0; _context->last_path = 0;
_context->texture_handles = NULL; _context->texture_handles = NULL;
_context->texture_vertices_size = 0; _context->texture_vertices = g_array_new (FALSE, FALSE,
_context->texture_vertices = NULL; sizeof (CoglTextureGLVertex));
_context->texture_indices = g_array_new (FALSE, FALSE,
sizeof (GLushort));
_context->material_handles = NULL; _context->material_handles = NULL;
_context->material_layer_handles = NULL; _context->material_layer_handles = NULL;
_context->source_material = COGL_INVALID_HANDLE; _context->source_material = COGL_INVALID_HANDLE;
@ -107,8 +110,10 @@ cogl_destroy_context ()
#endif #endif
if (_context->texture_vertices) if (_context->texture_vertices)
g_free (_context->texture_vertices); g_array_free (_context->texture_vertices, TRUE);
if (_context->texture_indices)
g_array_free (_context->texture_indices, TRUE);
if (_context->texture_handles) if (_context->texture_handles)
g_array_free (_context->texture_handles, TRUE); g_array_free (_context->texture_handles, TRUE);
if (_context->fbo_handles) if (_context->fbo_handles)

View File

@ -65,9 +65,14 @@ typedef struct
/* Textures */ /* Textures */
GArray *texture_handles; GArray *texture_handles;
CoglTextureGLVertex *texture_vertices; GArray *texture_vertices;
gulong texture_vertices_size; GArray *texture_indices;
/* The gl texture number that the above vertices apply to. This to
detect when a different slice is encountered so that the vertices
can be flushed */
GLuint texture_current;
GLenum texture_target;
/* Materials */ /* Materials */
GArray *material_handles; GArray *material_handles;
GArray *material_layer_handles; GArray *material_layer_handles;

View File

@ -2050,6 +2050,94 @@ cogl_texture_get_data (CoglHandle handle,
return byte_size; return byte_size;
} }
static void
_cogl_texture_flush_vertices (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->texture_vertices->len > 0)
{
int needed_indices;
CoglTextureGLVertex *p
= (CoglTextureGLVertex *) ctx->texture_vertices->data;
/* The indices are always the same sequence regardless of the
vertices so we only need to change it if there are more
vertices than ever before */
needed_indices = ctx->texture_vertices->len / 4 * 6;
if (needed_indices > ctx->texture_indices->len)
{
int old_len = ctx->texture_indices->len;
int vert_num = old_len / 6 * 4;
int i;
GLushort *q;
/* Add two triangles for each quad 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, needed_indices);
q = &g_array_index (ctx->texture_indices, GLushort, old_len);
for (i = old_len;
i < ctx->texture_indices->len;
i += 6, vert_num += 4)
{
*(q++) = vert_num + 0;
*(q++) = vert_num + 1;
*(q++) = vert_num + 3;
*(q++) = vert_num + 1;
*(q++) = vert_num + 2;
*(q++) = vert_num + 3;
}
}
GE( glVertexPointer (2, GL_FLOAT,
sizeof (CoglTextureGLVertex), p->v ) );
GE( glTexCoordPointer (2, GL_FLOAT,
sizeof (CoglTextureGLVertex), p->t ) );
GE( glBindTexture (ctx->texture_target, ctx->texture_current) );
GE( glDrawElements (GL_TRIANGLES,
needed_indices,
GL_UNSIGNED_SHORT,
ctx->texture_indices->data) );
g_array_set_size (ctx->texture_vertices, 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;
_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++;
}
static void static void
_cogl_texture_quad_sw (CoglTexture *tex, _cogl_texture_quad_sw (CoglTexture *tex,
CoglFixed x1, CoglFixed x1,
@ -2070,31 +2158,13 @@ _cogl_texture_quad_sw (CoglTexture *tex,
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;
GLfloat tex_coords[8];
GLfloat quad_coords[8];
GLuint gl_handle; GLuint gl_handle;
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
| COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY);
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
#if COGL_DEBUG #if COGL_DEBUG
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
#endif #endif
/* Prepare GL state */
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
{
enable_flags |= COGL_ENABLE_BLEND;
}
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
/* If the texture coordinates are backwards then swap both the /* If the texture coordinates are backwards then swap both the
geometry and texture coordinates so that the texture will be geometry and texture coordinates so that the texture will be
@ -2118,10 +2188,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
ty1 = ty2; ty1 = ty2;
ty2 = temp; ty2 = temp;
} }
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
/* Scale ratio from texture to quad widths */ /* Scale ratio from texture to quad widths */
tw = COGL_FIXED_FROM_INT (tex->bitmap.width); tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
th = COGL_FIXED_FROM_INT (tex->bitmap.height); th = COGL_FIXED_FROM_INT (tex->bitmap.height);
@ -2161,17 +2228,16 @@ _cogl_texture_quad_sw (CoglTexture *tex,
slice_qy2 = first_qy + slice_qy2 = first_qy +
COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy); COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy);
/* Localize slice texture coordinates */ /* Localize slice texture coordinates */
slice_ty1 = iter_y.intersect_start - iter_y.pos; slice_ty1 = iter_y.intersect_start - iter_y.pos;
slice_ty2 = iter_y.intersect_end - iter_y.pos; slice_ty2 = iter_y.intersect_end - iter_y.pos;
/* Normalize texture coordinates to current slice /* Normalize texture coordinates to current slice
(rectangle texture targets take denormalized) */ (rectangle texture targets take denormalized) */
slice_ty1 /= iter_y.span->size; slice_ty1 /= iter_y.span->size;
slice_ty2 /= iter_y.span->size; slice_ty2 /= iter_y.span->size;
/* Iterate until whole quad width covered */ /* Iterate until whole quad width covered */
for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans, for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans,
first_tx, tx1, tx2) ; first_tx, tx1, tx2) ;
@ -2191,12 +2257,12 @@ _cogl_texture_quad_sw (CoglTexture *tex,
/* Localize slice texture coordinates */ /* Localize slice texture coordinates */
slice_tx1 = iter_x.intersect_start - iter_x.pos; slice_tx1 = iter_x.intersect_start - iter_x.pos;
slice_tx2 = iter_x.intersect_end - iter_x.pos; slice_tx2 = iter_x.intersect_end - iter_x.pos;
/* Normalize texture coordinates to current slice /* Normalize texture coordinates to current slice
(rectangle texture targets take denormalized) */ (rectangle texture targets take denormalized) */
slice_tx1 /= iter_x.span->size; slice_tx1 /= iter_x.span->size;
slice_tx2 /= iter_x.span->size; slice_tx2 /= iter_x.span->size;
#if COGL_DEBUG #if COGL_DEBUG
printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index); printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index);
printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1)); printf("qx1: %f\n", COGL_FIXED_TO_FLOAT (slice_qx1));
@ -2213,26 +2279,23 @@ _cogl_texture_quad_sw (CoglTexture *tex,
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, gl_handle = g_array_index (tex->slice_gl_handles, GLuint,
iter_y.index * iter_x.array->len + iter_y.index * iter_x.array->len +
iter_x.index); iter_x.index);
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
tex->gl_intformat) );
#define CFX_F COGL_FIXED_TO_FLOAT /* If we're using a different texture from the one already queued
then flush the vertices */
/* Draw textured quad */ if (ctx->texture_vertices->len > 0
tex_coords[0] = CFX_F(slice_tx1); tex_coords[1] = CFX_F(slice_ty2); && gl_handle != ctx->texture_current)
tex_coords[2] = CFX_F(slice_tx2); tex_coords[3] = CFX_F(slice_ty2); _cogl_texture_flush_vertices ();
tex_coords[4] = CFX_F(slice_tx1); tex_coords[5] = CFX_F(slice_ty1); ctx->texture_target = tex->gl_target;
tex_coords[6] = CFX_F(slice_tx2); tex_coords[7] = CFX_F(slice_ty1); ctx->texture_current = gl_handle;
quad_coords[0] = CFX_F(slice_qx1); quad_coords[1] = CFX_F(slice_qy2); _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1),
quad_coords[2] = CFX_F(slice_qx2); quad_coords[3] = CFX_F(slice_qy2); COGL_FIXED_TO_FLOAT (slice_qy1),
quad_coords[4] = CFX_F(slice_qx1); quad_coords[5] = CFX_F(slice_qy1); COGL_FIXED_TO_FLOAT (slice_qx2),
quad_coords[6] = CFX_F(slice_qx2); quad_coords[7] = CFX_F(slice_qy1); COGL_FIXED_TO_FLOAT (slice_qy2),
COGL_FIXED_TO_FLOAT (slice_tx1),
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) ); COGL_FIXED_TO_FLOAT (slice_ty1),
COGL_FIXED_TO_FLOAT (slice_tx2),
#undef CFX_F COGL_FIXED_TO_FLOAT (slice_ty2));
} }
} }
} }
@ -2248,41 +2311,27 @@ _cogl_texture_quad_hw (CoglTexture *tex,
CoglFixed tx2, CoglFixed tx2,
CoglFixed ty2) CoglFixed ty2)
{ {
GLfloat tex_coords[8];
GLfloat quad_coords[8];
GLuint gl_handle; GLuint gl_handle;
CoglTexSliceSpan *x_span; CoglTexSliceSpan *x_span;
CoglTexSliceSpan *y_span; CoglTexSliceSpan *y_span;
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
| COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY);
#if COGL_DEBUG #if COGL_DEBUG
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n"); printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
#endif #endif
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Prepare GL state */
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
{
enable_flags |= COGL_ENABLE_BLEND;
}
if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
/* Pick and bind opengl texture object */ /* Pick and bind opengl texture object */
gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0); gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
tex->gl_intformat) ); /* If we're using a different texture from the one already queued
then flush the vertices */
if (ctx->texture_vertices->len > 0
&& gl_handle != ctx->texture_current)
_cogl_texture_flush_vertices ();
ctx->texture_target = tex->gl_target;
ctx->texture_current = gl_handle;
/* Don't include the waste in the texture coordinates */ /* Don't include the waste in the texture coordinates */
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0); x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, 0); y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, 0);
@ -2293,22 +2342,80 @@ _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;
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x) _cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (x1),
COGL_FIXED_TO_FLOAT (y1),
COGL_FIXED_TO_FLOAT (x2),
COGL_FIXED_TO_FLOAT (y2),
COGL_FIXED_TO_FLOAT (tx1),
COGL_FIXED_TO_FLOAT (ty1),
COGL_FIXED_TO_FLOAT (tx2),
COGL_FIXED_TO_FLOAT (ty2));
}
void
cogl_texture_multiple_rectangles (CoglHandle handle,
const CoglFixed *verts,
guint n_rects)
{
CoglTexture *tex;
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
| COGL_ENABLE_TEXCOORD_ARRAY
| COGL_ENABLE_TEXTURE_2D);
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Check if valid texture */
if (!cogl_is_texture (handle))
return;
/* Draw textured quad */ cogl_clip_ensure ();
tex_coords[0] = CFX_F(tx1); tex_coords[1] = CFX_F(ty2);
tex_coords[2] = CFX_F(tx2); tex_coords[3] = CFX_F(ty2);
tex_coords[4] = CFX_F(tx1); tex_coords[5] = CFX_F(ty1);
tex_coords[6] = CFX_F(tx2); tex_coords[7] = CFX_F(ty1);
quad_coords[0] = CFX_F(x1); quad_coords[1] = CFX_F(y2); tex = _cogl_texture_pointer_from_handle (handle);
quad_coords[2] = CFX_F(x2); quad_coords[3] = CFX_F(y2);
quad_coords[4] = CFX_F(x1); quad_coords[5] = CFX_F(y1); /* Make sure we got stuff to draw */
quad_coords[6] = CFX_F(x2); quad_coords[7] = CFX_F(y1); if (tex->slice_gl_handles == NULL)
return;
if (tex->slice_gl_handles->len == 0)
return;
GE (glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) ); /* Prepare GL state */
if (ctx->color_alpha < 255
|| tex->bitmap.format & COGL_A_BIT)
enable_flags |= COGL_ENABLE_BLEND;
#undef CFX_F if (ctx->enable_backface_culling)
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
cogl_enable (enable_flags);
g_array_set_size (ctx->texture_vertices, 0);
while (n_rects-- > 0)
{
if (verts[4] != verts[6] && verts[5] != verts[7])
{
/* If there is only one GL texture and either the texture is
NPOT (no waste) or all of the coordinates are in the
range [0,1] then we can use hardware tiling */
if (tex->slice_gl_handles->len == 1
&& ((cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
&& tex->gl_target == GL_TEXTURE_2D)
|| (verts[4] >= 0 && verts[4] <= COGL_FIXED_1
&& verts[6] >= 0 && verts[6] <= COGL_FIXED_1
&& verts[5] >= 0 && verts[5] <= COGL_FIXED_1
&& verts[7] >= 0 && verts[7] <= COGL_FIXED_1)))
_cogl_texture_quad_hw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]);
else
_cogl_texture_quad_sw (tex, verts[0],verts[1], verts[2],verts[3],
verts[4],verts[5], verts[6],verts[7]);
}
verts += 8;
}
_cogl_texture_flush_vertices ();
} }
void void
@ -2322,47 +2429,18 @@ cogl_texture_rectangle (CoglHandle handle,
CoglFixed tx2, CoglFixed tx2,
CoglFixed ty2) CoglFixed ty2)
{ {
CoglTexture *tex; CoglFixed verts[8];
/* Check if valid texture */
if (!cogl_is_texture (handle))
return;
cogl_clip_ensure (); verts[0] = x1;
verts[1] = y1;
tex = _cogl_texture_pointer_from_handle (handle); verts[2] = x2;
verts[3] = y2;
/* Make sure we got stuff to draw */ verts[4] = tx1;
if (tex->slice_gl_handles == NULL) verts[5] = ty1;
return; verts[6] = tx2;
verts[7] = ty2;
if (tex->slice_gl_handles->len == 0)
return; cogl_texture_multiple_rectangles (handle, verts, 1);
if (tx1 == tx2 || ty1 == ty2)
return;
/* Pick tiling mode according to hw support */
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
&& tex->slice_gl_handles->len == 1)
{
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
}
else
{
if (tex->slice_gl_handles->len == 1
&& tx1 >= -COGL_FIXED_1
&& tx2 <= COGL_FIXED_1
&& ty1 >= -COGL_FIXED_1
&& ty2 <= COGL_FIXED_1)
{
_cogl_texture_quad_hw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
}
else
{
_cogl_texture_quad_sw (tex, x1,y1, x2,y2, tx1,ty1, tx2,ty2);
}
}
} }
void void
@ -2408,23 +2486,9 @@ cogl_texture_polygon (CoglHandle handle,
/* Make sure there is enough space in the global texture vertex /* Make sure there is enough space in the global texture vertex
array. This is used so we can render the polygon with a single array. This is used so we can render the polygon with a single
call to OpenGL but still support any number of vertices */ call to OpenGL but still support any number of vertices */
if (ctx->texture_vertices_size < n_vertices) g_array_set_size (ctx->texture_vertices, n_vertices);
{ p = (CoglTextureGLVertex *) ctx->texture_vertices->data;
guint nsize = ctx->texture_vertices_size;
if (nsize == 0)
nsize = 1;
do
nsize *= 2;
while (nsize < n_vertices);
ctx->texture_vertices_size = nsize;
ctx->texture_vertices = g_realloc (ctx->texture_vertices,
nsize
* sizeof (CoglTextureGLVertex));
}
/* Prepare GL state */ /* Prepare GL state */
enable_flags = (COGL_ENABLE_TEXTURE_2D enable_flags = (COGL_ENABLE_TEXTURE_2D
| COGL_ENABLE_VERTEX_ARRAY | COGL_ENABLE_VERTEX_ARRAY
@ -2450,14 +2514,12 @@ cogl_texture_polygon (CoglHandle handle,
if (use_color) if (use_color)
{ {
enable_flags |= COGL_ENABLE_COLOR_ARRAY; enable_flags |= COGL_ENABLE_COLOR_ARRAY;
GE( glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (CoglTextureGLVertex), GE( glColorPointer (4, GL_UNSIGNED_BYTE,
ctx->texture_vertices[0].c) ); sizeof (CoglTextureGLVertex), p->c) );
} }
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), p->v ) );
ctx->texture_vertices[0].v) ); GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex), p->t ) );
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex),
ctx->texture_vertices[0].t) );
cogl_enable (enable_flags); cogl_enable (enable_flags);
@ -2467,7 +2529,7 @@ cogl_texture_polygon (CoglHandle handle,
/* Convert the vertices into an array of GLfloats ready to pass to /* Convert the vertices into an array of GLfloats ready to pass to
OpenGL */ OpenGL */
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++) for (i = 0; i < n_vertices; i++, p++)
{ {
#define CFX_F COGL_FIXED_TO_FLOAT #define CFX_F COGL_FIXED_TO_FLOAT