mirror of
https://github.com/brl/mutter.git
synced 2024-11-10 07:56:14 -05:00
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:
commit
a0c5690d55
@ -416,6 +416,29 @@ void cogl_material_rectangle (CoglFixed x1,
|
||||
gint tex_coords_len,
|
||||
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
|
||||
|
||||
#endif /* __COGL_TEXTURE_H__ */
|
||||
|
72
cogl-types.h
72
cogl-types.h
@ -86,27 +86,29 @@ typedef struct _CoglTextureVertex CoglTextureVertex;
|
||||
|
||||
/**
|
||||
* CoglPixelFormat:
|
||||
* @COGL_PIXEL_FORMAT_ANY:
|
||||
* @COGL_PIXEL_FORMAT_A_8:
|
||||
* @COGL_PIXEL_FORMAT_RGB_888:
|
||||
* @COGL_PIXEL_FORMAT_BGR_888:
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888:
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888:
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888:
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888:
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888_PRE:
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888_PRE:
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888_PRE:
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888_PRE:
|
||||
* @COGL_PIXEL_FORMAT_RGB_565:
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444:
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551:
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444_PRE:
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551_PRE:
|
||||
* @COGL_PIXEL_FORMAT_YUV:
|
||||
* @COGL_PIXEL_FORMAT_G_8:
|
||||
* @COGL_PIXEL_FORMAT_ANY: Any format
|
||||
* @COGL_PIXEL_FORMAT_A_8: 8 bits alpha mask
|
||||
* @COGL_PIXEL_FORMAT_RGB_565: RGB, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444: RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551: RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_YUV: FIXME
|
||||
* @COGL_PIXEL_FORMAT_G_8: FIXME
|
||||
* @COGL_PIXEL_FORMAT_RGB_888: RGB, 24 bits
|
||||
* @COGL_PIXEL_FORMAT_BGR_888: BGR, 24 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888: RGBA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888: BGRA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888: ARGB, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888: ABGR, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_8888_PRE: Premultiplied RGBA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_BGRA_8888_PRE: Premultiplied BGRA, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ARGB_8888_PRE: Premultiplied ARGB, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_ABGR_8888_PRE: Premultiplied ABGR, 32 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_4444_PRE: Premultiplied RGBA, 16 bits
|
||||
* @COGL_PIXEL_FORMAT_RGBA_5551_PRE: Premultiplied RGBA, 16 bits
|
||||
*
|
||||
* Pixel formats used by COGL.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@ -173,19 +175,21 @@ typedef enum
|
||||
|
||||
/**
|
||||
* CoglFeatureFlags:
|
||||
* @COGL_FEATURE_TEXTURE_RECTANGLE:
|
||||
* @COGL_FEATURE_TEXTURE_NPOT:
|
||||
* @COGL_FEATURE_TEXTURE_YUV:
|
||||
* @COGL_FEATURE_TEXTURE_READ_PIXELS:
|
||||
* @COGL_FEATURE_SHADERS_GLSL:
|
||||
* @COGL_FEATURE_OFFSCREEN:
|
||||
* @COGL_FEATURE_OFFSCREEN_MULTISAMPLE:
|
||||
* @COGL_FEATURE_OFFSCREEN_BLIT:
|
||||
* @COGL_FEATURE_FOUR_CLIP_PLANES:
|
||||
* @COGL_FEATURE_STENCIL_BUFFER:
|
||||
* @COGL_FEATURE_VBOS:
|
||||
* @COGL_FEATURE_TEXTURE_RECTANGLE: ARB_texture_rectangle support
|
||||
* @COGL_FEATURE_TEXTURE_NPOT: ARB_texture_non_power_of_two support
|
||||
* @COGL_FEATURE_TEXTURE_YUV: ycbcr conversion support
|
||||
* @COGL_FEATURE_TEXTURE_READ_PIXELS: glReadPixels() support
|
||||
* @COGL_FEATURE_SHADERS_GLSL: GLSL support
|
||||
* @COGL_FEATURE_OFFSCREEN: FBO support
|
||||
* @COGL_FEATURE_OFFSCREEN_MULTISAMPLE: Multisample support on FBOs
|
||||
* @COGL_FEATURE_OFFSCREEN_BLIT: Blit support on FBOs
|
||||
* @COGL_FEATURE_FOUR_CLIP_PLANES: At least 4 clip planes available
|
||||
* @COGL_FEATURE_STENCIL_BUFFER: Stencil buffer support
|
||||
* @COGL_FEATURE_VBOS: VBO support
|
||||
*
|
||||
* Flags for the supported features.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
@ -204,11 +208,13 @@ typedef enum
|
||||
|
||||
/**
|
||||
* CoglBufferTarget:
|
||||
* @COGL_WINDOW_BUFFER:
|
||||
* @COGL_MASK_BUFFER:
|
||||
* @COGL_OFFSCREEN_BUFFER:
|
||||
* @COGL_WINDOW_BUFFER: FIXME
|
||||
* @COGL_MASK_BUFFER: FIXME
|
||||
* @COGL_OFFSCREEN_BUFFER: FIXME
|
||||
*
|
||||
* Target flags for FBOs.
|
||||
*
|
||||
* Since: 0.8
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ INCLUDES = \
|
||||
-I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \
|
||||
-I$(top_builddir)/clutter \
|
||||
-I$(top_builddir)/clutter/cogl \
|
||||
-DG_LOG_DOMAIN=\"Cogl-Common\" \
|
||||
-DCLUTTER_COMPILATION \
|
||||
$(CLUTTER_CFLAGS) \
|
||||
$(CLUTTER_DEBUG_CFLAGS) \
|
||||
|
@ -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
|
||||
* attributes too.
|
||||
*
|
||||
* Return value: a new #CoglHandle
|
||||
*/
|
||||
CoglHandle
|
||||
cogl_mesh_new (guint n_vertices)
|
||||
|
@ -120,6 +120,7 @@ cogl_texture_set_region
|
||||
cogl_texture_ref
|
||||
cogl_texture_unref
|
||||
cogl_texture_rectangle
|
||||
cogl_texture_multiple_rectangles
|
||||
cogl_texture_polygon
|
||||
</SECTION>
|
||||
|
||||
|
@ -22,6 +22,7 @@ INCLUDES = \
|
||||
-I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \
|
||||
-I$(top_builddir)/clutter \
|
||||
-I$(top_builddir)/clutter/cogl \
|
||||
-DG_LOG_DOMAIN=\"Cogl-GL\" \
|
||||
-DCLUTTER_COMPILATION \
|
||||
$(CLUTTER_CFLAGS) \
|
||||
$(CLUTTER_DEBUG_CFLAGS) \
|
||||
|
@ -56,8 +56,10 @@ cogl_create_context ()
|
||||
_context->last_path = 0;
|
||||
|
||||
_context->texture_handles = NULL;
|
||||
_context->texture_vertices_size = 0;
|
||||
_context->texture_vertices = NULL;
|
||||
_context->texture_vertices = g_array_new (FALSE, FALSE,
|
||||
sizeof (CoglTextureGLVertex));
|
||||
_context->texture_indices = g_array_new (FALSE, FALSE,
|
||||
sizeof (GLushort));
|
||||
|
||||
_context->material_handles = NULL;
|
||||
_context->material_layer_handles = NULL;
|
||||
@ -153,6 +155,11 @@ cogl_destroy_context ()
|
||||
if (_context->program_handles)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -63,8 +63,14 @@ typedef struct
|
||||
|
||||
/* Textures */
|
||||
GArray *texture_handles;
|
||||
CoglTextureGLVertex *texture_vertices;
|
||||
gulong texture_vertices_size;
|
||||
GArray *texture_vertices;
|
||||
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 */
|
||||
GArray *material_handles;
|
||||
|
@ -1911,6 +1911,95 @@ cogl_texture_get_data (CoglHandle handle,
|
||||
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
|
||||
_cogl_texture_quad_sw (CoglTexture *tex,
|
||||
CoglFixed x1,
|
||||
@ -1931,11 +2020,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
CoglFixed slice_tx2 , slice_ty2;
|
||||
CoglFixed slice_qx1 , slice_qy1;
|
||||
CoglFixed slice_qx2 , slice_qy2;
|
||||
GLfloat tex_coords[8];
|
||||
GLfloat quad_coords[8];
|
||||
GLuint gl_handle;
|
||||
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
|
||||
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -1943,26 +2028,13 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
|
||||
#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
|
||||
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);
|
||||
ctx->texture_wrap_mode = GL_CLAMP_TO_EDGE;
|
||||
|
||||
/* If the texture coordinates are backwards then swap both the
|
||||
geometry and texture coordinates so that the texture will be
|
||||
@ -1987,9 +2059,6 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
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 */
|
||||
tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
|
||||
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_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
|
||||
|
||||
/* Draw textured quad */
|
||||
tex_coords[0] = CFX_F(slice_tx1); tex_coords[1] = CFX_F(slice_ty2);
|
||||
tex_coords[2] = CFX_F(slice_tx2); tex_coords[3] = CFX_F(slice_ty2);
|
||||
tex_coords[4] = CFX_F(slice_tx1); tex_coords[5] = CFX_F(slice_ty1);
|
||||
tex_coords[6] = CFX_F(slice_tx2); tex_coords[7] = CFX_F(slice_ty1);
|
||||
|
||||
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
|
||||
_cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1),
|
||||
COGL_FIXED_TO_FLOAT (slice_qy1),
|
||||
COGL_FIXED_TO_FLOAT (slice_qx2),
|
||||
COGL_FIXED_TO_FLOAT (slice_qy2),
|
||||
COGL_FIXED_TO_FLOAT (slice_tx1),
|
||||
COGL_FIXED_TO_FLOAT (slice_ty1),
|
||||
COGL_FIXED_TO_FLOAT (slice_tx2),
|
||||
COGL_FIXED_TO_FLOAT (slice_ty2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2120,13 +2187,10 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
||||
CoglFixed tx2,
|
||||
CoglFixed ty2)
|
||||
{
|
||||
GLfloat tex_coords[8];
|
||||
GLfloat quad_coords[8];
|
||||
GLuint gl_handle;
|
||||
CoglTexSliceSpan *x_span;
|
||||
CoglTexSliceSpan *y_span;
|
||||
gulong enable_flags = (COGL_ENABLE_VERTEX_ARRAY
|
||||
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||
GLenum wrap_mode;
|
||||
|
||||
#if COGL_DEBUG
|
||||
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
|
||||
@ -2134,24 +2198,6 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
||||
|
||||
_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
|
||||
clamp the coords to the edge otherwise it can pull in edge pixels
|
||||
from the wrong side when scaled */
|
||||
@ -2159,16 +2205,24 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
||||
&& tx2 >= 0 && tx2 <= COGL_FIXED_1
|
||||
&& ty1 >= 0 && ty1 <= 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
|
||||
_cogl_texture_set_wrap_mode_parameter (tex, GL_REPEAT);
|
||||
|
||||
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
|
||||
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
|
||||
wrap_mode = GL_REPEAT;
|
||||
|
||||
/* Pick and bind opengl texture object */
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
#define CFX_F(x) COGL_FIXED_TO_FLOAT(x)
|
||||
|
||||
/* Draw textured quad */
|
||||
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);
|
||||
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
|
||||
_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_rectangle (CoglHandle handle,
|
||||
CoglFixed x1,
|
||||
CoglFixed y1,
|
||||
CoglFixed x2,
|
||||
CoglFixed y2,
|
||||
CoglFixed tx1,
|
||||
CoglFixed ty1,
|
||||
CoglFixed tx2,
|
||||
CoglFixed ty2)
|
||||
cogl_texture_multiple_rectangles (CoglHandle handle,
|
||||
const CoglFixed *verts,
|
||||
guint n_rects)
|
||||
{
|
||||
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 */
|
||||
if (!cogl_is_texture (handle))
|
||||
@ -2235,22 +2279,73 @@ cogl_texture_rectangle (CoglHandle handle,
|
||||
if (tex->slice_gl_handles->len == 0)
|
||||
return;
|
||||
|
||||
if (tx1 == tx2 || ty1 == ty2)
|
||||
return;
|
||||
|
||||
/* 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);
|
||||
/* Prepare GL state */
|
||||
if (tex->gl_target == CGL_TEXTURE_RECTANGLE_ARB)
|
||||
enable_flags |= COGL_ENABLE_TEXTURE_RECT;
|
||||
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
|
||||
@ -2299,22 +2394,8 @@ cogl_texture_polygon (CoglHandle handle,
|
||||
/* Make sure there is enough space in the global texture vertex
|
||||
array. This is used so we can render the polygon with a single
|
||||
call to OpenGL but still support any number of vertices */
|
||||
if (ctx->texture_vertices_size < n_vertices)
|
||||
{
|
||||
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));
|
||||
}
|
||||
g_array_set_size (ctx->texture_vertices, n_vertices);
|
||||
p = (CoglTextureGLVertex *) ctx->texture_vertices->data;
|
||||
|
||||
/* Prepare GL state */
|
||||
enable_flags = (COGL_ENABLE_VERTEX_ARRAY
|
||||
@ -2332,14 +2413,12 @@ cogl_texture_polygon (CoglHandle handle,
|
||||
if (use_color)
|
||||
{
|
||||
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
|
||||
GE( glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (CoglTextureGLVertex),
|
||||
ctx->texture_vertices[0].c) );
|
||||
GE( glColorPointer (4, GL_UNSIGNED_BYTE,
|
||||
sizeof (CoglTextureGLVertex), p->c) );
|
||||
}
|
||||
|
||||
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex),
|
||||
ctx->texture_vertices[0].v) );
|
||||
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex),
|
||||
ctx->texture_vertices[0].t) );
|
||||
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), p->v ) );
|
||||
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex), p->t ) );
|
||||
|
||||
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++);
|
||||
|
||||
p = (CoglTextureGLVertex *) ctx->texture_vertices->data;
|
||||
|
||||
/* Convert the vertices into an array of GLfloats ready to pass to
|
||||
OpenGL */
|
||||
for (i = 0, p = ctx->texture_vertices; i < n_vertices; i++, p++)
|
||||
for (i = 0; i < n_vertices; i++, p++)
|
||||
{
|
||||
CoglFixed tx, ty;
|
||||
|
||||
|
@ -22,6 +22,7 @@ INCLUDES = \
|
||||
-I$(top_srcdir)/clutter/cogl/$(CLUTTER_COGL) \
|
||||
-I$(top_builddir)/clutter \
|
||||
-I$(top_builddir)/clutter/cogl \
|
||||
-DG_LOG_DOMAIN=\"Cogl-GLES\" \
|
||||
-DCLUTTER_COMPILATION \
|
||||
$(CLUTTER_CFLAGS) \
|
||||
$(CLUTTER_DEBUG_CFLAGS) \
|
||||
|
@ -59,8 +59,11 @@ cogl_create_context ()
|
||||
_context->last_path = 0;
|
||||
|
||||
_context->texture_handles = NULL;
|
||||
_context->texture_vertices_size = 0;
|
||||
_context->texture_vertices = NULL;
|
||||
_context->texture_vertices = g_array_new (FALSE, FALSE,
|
||||
sizeof (CoglTextureGLVertex));
|
||||
_context->texture_indices = g_array_new (FALSE, FALSE,
|
||||
sizeof (GLushort));
|
||||
|
||||
_context->material_handles = NULL;
|
||||
_context->material_layer_handles = NULL;
|
||||
_context->source_material = COGL_INVALID_HANDLE;
|
||||
@ -107,8 +110,10 @@ cogl_destroy_context ()
|
||||
#endif
|
||||
|
||||
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)
|
||||
g_array_free (_context->texture_handles, TRUE);
|
||||
if (_context->fbo_handles)
|
||||
|
@ -65,9 +65,14 @@ typedef struct
|
||||
|
||||
/* Textures */
|
||||
GArray *texture_handles;
|
||||
CoglTextureGLVertex *texture_vertices;
|
||||
gulong texture_vertices_size;
|
||||
|
||||
GArray *texture_vertices;
|
||||
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 */
|
||||
GArray *material_handles;
|
||||
GArray *material_layer_handles;
|
||||
|
@ -2050,6 +2050,94 @@ cogl_texture_get_data (CoglHandle handle,
|
||||
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
|
||||
_cogl_texture_quad_sw (CoglTexture *tex,
|
||||
CoglFixed x1,
|
||||
@ -2070,31 +2158,13 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
CoglFixed slice_tx2 , slice_ty2;
|
||||
CoglFixed slice_qx1 , slice_qy1;
|
||||
CoglFixed slice_qx2 , slice_qy2;
|
||||
GLfloat tex_coords[8];
|
||||
GLfloat quad_coords[8];
|
||||
GLuint gl_handle;
|
||||
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
|
||||
| COGL_ENABLE_VERTEX_ARRAY
|
||||
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
#if COGL_DEBUG
|
||||
printf("=== Drawing Tex Quad (Software Tiling Mode) ===\n");
|
||||
#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
|
||||
geometry and texture coordinates so that the texture will be
|
||||
@ -2118,10 +2188,7 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
ty1 = ty2;
|
||||
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 */
|
||||
tw = COGL_FIXED_FROM_INT (tex->bitmap.width);
|
||||
th = COGL_FIXED_FROM_INT (tex->bitmap.height);
|
||||
@ -2161,17 +2228,16 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
|
||||
slice_qy2 = first_qy +
|
||||
COGL_FIXED_MUL (iter_y.intersect_end - first_ty, tqy);
|
||||
|
||||
|
||||
/* Localize slice texture coordinates */
|
||||
slice_ty1 = iter_y.intersect_start - iter_y.pos;
|
||||
slice_ty2 = iter_y.intersect_end - iter_y.pos;
|
||||
|
||||
|
||||
/* Normalize texture coordinates to current slice
|
||||
(rectangle texture targets take denormalized) */
|
||||
slice_ty1 /= iter_y.span->size;
|
||||
slice_ty2 /= iter_y.span->size;
|
||||
|
||||
|
||||
|
||||
/* Iterate until whole quad width covered */
|
||||
for (_cogl_span_iter_begin (&iter_x, tex->slice_x_spans,
|
||||
first_tx, tx1, tx2) ;
|
||||
@ -2191,12 +2257,12 @@ _cogl_texture_quad_sw (CoglTexture *tex,
|
||||
/* Localize slice texture coordinates */
|
||||
slice_tx1 = iter_x.intersect_start - iter_x.pos;
|
||||
slice_tx2 = iter_x.intersect_end - iter_x.pos;
|
||||
|
||||
|
||||
/* Normalize texture coordinates to current slice
|
||||
(rectangle texture targets take denormalized) */
|
||||
slice_tx1 /= iter_x.span->size;
|
||||
slice_tx2 /= iter_x.span->size;
|
||||
|
||||
|
||||
#if COGL_DEBUG
|
||||
printf("~~~~~ slice (%d,%d)\n", iter_x.index, iter_y.index);
|
||||
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,
|
||||
iter_y.index * iter_x.array->len +
|
||||
iter_x.index);
|
||||
|
||||
GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
|
||||
tex->gl_intformat) );
|
||||
|
||||
#define CFX_F COGL_FIXED_TO_FLOAT
|
||||
|
||||
/* Draw textured quad */
|
||||
tex_coords[0] = CFX_F(slice_tx1); tex_coords[1] = CFX_F(slice_ty2);
|
||||
tex_coords[2] = CFX_F(slice_tx2); tex_coords[3] = CFX_F(slice_ty2);
|
||||
tex_coords[4] = CFX_F(slice_tx1); tex_coords[5] = CFX_F(slice_ty1);
|
||||
tex_coords[6] = CFX_F(slice_tx2); tex_coords[7] = CFX_F(slice_ty1);
|
||||
/* 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;
|
||||
|
||||
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
|
||||
_cogl_texture_add_quad_vertices (COGL_FIXED_TO_FLOAT (slice_qx1),
|
||||
COGL_FIXED_TO_FLOAT (slice_qy1),
|
||||
COGL_FIXED_TO_FLOAT (slice_qx2),
|
||||
COGL_FIXED_TO_FLOAT (slice_qy2),
|
||||
COGL_FIXED_TO_FLOAT (slice_tx1),
|
||||
COGL_FIXED_TO_FLOAT (slice_ty1),
|
||||
COGL_FIXED_TO_FLOAT (slice_tx2),
|
||||
COGL_FIXED_TO_FLOAT (slice_ty2));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2248,41 +2311,27 @@ _cogl_texture_quad_hw (CoglTexture *tex,
|
||||
CoglFixed tx2,
|
||||
CoglFixed ty2)
|
||||
{
|
||||
GLfloat tex_coords[8];
|
||||
GLfloat quad_coords[8];
|
||||
GLuint gl_handle;
|
||||
CoglTexSliceSpan *x_span;
|
||||
CoglTexSliceSpan *y_span;
|
||||
gulong enable_flags = (COGL_ENABLE_TEXTURE_2D
|
||||
| COGL_ENABLE_VERTEX_ARRAY
|
||||
| COGL_ENABLE_TEXCOORD_ARRAY);
|
||||
|
||||
#if COGL_DEBUG
|
||||
printf("=== Drawing Tex Quad (Hardware Tiling Mode) ===\n");
|
||||
#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);
|
||||
|
||||
GE( glTexCoordPointer (2, GL_FLOAT, 0, tex_coords) );
|
||||
GE( glVertexPointer (2, GL_FLOAT, 0, quad_coords) );
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* Pick and bind opengl texture object */
|
||||
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 */
|
||||
x_span = &g_array_index (tex->slice_x_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;
|
||||
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 */
|
||||
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);
|
||||
cogl_clip_ensure ();
|
||||
|
||||
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);
|
||||
tex = _cogl_texture_pointer_from_handle (handle);
|
||||
|
||||
/* Make sure we got stuff to draw */
|
||||
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
|
||||
@ -2322,47 +2429,18 @@ cogl_texture_rectangle (CoglHandle handle,
|
||||
CoglFixed tx2,
|
||||
CoglFixed ty2)
|
||||
{
|
||||
CoglTexture *tex;
|
||||
|
||||
/* Check if valid texture */
|
||||
if (!cogl_is_texture (handle))
|
||||
return;
|
||||
CoglFixed verts[8];
|
||||
|
||||
cogl_clip_ensure ();
|
||||
|
||||
tex = _cogl_texture_pointer_from_handle (handle);
|
||||
|
||||
/* Make sure we got stuff to draw */
|
||||
if (tex->slice_gl_handles == NULL)
|
||||
return;
|
||||
|
||||
if (tex->slice_gl_handles->len == 0)
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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
|
||||
@ -2408,23 +2486,9 @@ cogl_texture_polygon (CoglHandle handle,
|
||||
/* Make sure there is enough space in the global texture vertex
|
||||
array. This is used so we can render the polygon with a single
|
||||
call to OpenGL but still support any number of vertices */
|
||||
if (ctx->texture_vertices_size < n_vertices)
|
||||
{
|
||||
guint nsize = ctx->texture_vertices_size;
|
||||
|
||||
if (nsize == 0)
|
||||
nsize = 1;
|
||||
do
|
||||
nsize *= 2;
|
||||
while (nsize < n_vertices);
|
||||
|
||||
ctx->texture_vertices_size = nsize;
|
||||
g_array_set_size (ctx->texture_vertices, n_vertices);
|
||||
p = (CoglTextureGLVertex *) ctx->texture_vertices->data;
|
||||
|
||||
ctx->texture_vertices = g_realloc (ctx->texture_vertices,
|
||||
nsize
|
||||
* sizeof (CoglTextureGLVertex));
|
||||
}
|
||||
|
||||
/* Prepare GL state */
|
||||
enable_flags = (COGL_ENABLE_TEXTURE_2D
|
||||
| COGL_ENABLE_VERTEX_ARRAY
|
||||
@ -2450,14 +2514,12 @@ cogl_texture_polygon (CoglHandle handle,
|
||||
if (use_color)
|
||||
{
|
||||
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
|
||||
GE( glColorPointer (4, GL_UNSIGNED_BYTE, sizeof (CoglTextureGLVertex),
|
||||
ctx->texture_vertices[0].c) );
|
||||
}
|
||||
GE( glColorPointer (4, GL_UNSIGNED_BYTE,
|
||||
sizeof (CoglTextureGLVertex), p->c) );
|
||||
}
|
||||
|
||||
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex),
|
||||
ctx->texture_vertices[0].v) );
|
||||
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex),
|
||||
ctx->texture_vertices[0].t) );
|
||||
GE( glVertexPointer (3, GL_FLOAT, sizeof (CoglTextureGLVertex), p->v ) );
|
||||
GE( glTexCoordPointer (2, GL_FLOAT, sizeof (CoglTextureGLVertex), p->t ) );
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user