Adds support for a mirrored repeat wrap mode

This adds COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT enum so that mirrored
texture repeating can be used. This also adds support for emulating the
MIRRORED_REPEAT mode via the cogl-spans API so it can also be used with
meta textures such as sliced and atlas textures.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
Robert Bragg 2011-10-13 14:02:37 +01:00
parent 1d8fd64e1c
commit 1a30f4fb15
8 changed files with 54 additions and 8 deletions

View File

@ -41,6 +41,9 @@
#ifndef GL_CLAMP_TO_BORDER #ifndef GL_CLAMP_TO_BORDER
#define GL_CLAMP_TO_BORDER 0x812d #define GL_CLAMP_TO_BORDER 0x812d
#endif #endif
#ifndef GL_MIRRORED_REPEAT
#define GL_MIRRORED_REPEAT 0x8370
#endif
typedef struct _CoglPipelineLayer CoglPipelineLayer; typedef struct _CoglPipelineLayer CoglPipelineLayer;
#define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT) #define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT)
@ -54,6 +57,7 @@ typedef struct _CoglPipelineLayer CoglPipelineLayer;
typedef enum _CoglPipelineWrapModeInternal typedef enum _CoglPipelineWrapModeInternal
{ {
COGL_PIPELINE_WRAP_MODE_INTERNAL_REPEAT = GL_REPEAT, COGL_PIPELINE_WRAP_MODE_INTERNAL_REPEAT = GL_REPEAT,
COGL_PIPELINE_WRAP_MODE_INTERNAL_MIRRORED_REPEAT = GL_MIRRORED_REPEAT,
COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE, COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER, COGL_PIPELINE_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER,
COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC = GL_ALWAYS COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC = GL_ALWAYS

View File

@ -111,8 +111,9 @@ typedef enum {
*/ */
typedef enum { typedef enum {
COGL_PIPELINE_WRAP_MODE_REPEAT = 0x2901, COGL_PIPELINE_WRAP_MODE_REPEAT = 0x2901,
COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT = 0x8370,
COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE = 0x812F, COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE = 0x812F,
COGL_PIPELINE_WRAP_MODE_AUTOMATIC = 0x0207 COGL_PIPELINE_WRAP_MODE_AUTOMATIC = 0x0207 /* GL_ALWAYS */
} CoglPipelineWrapMode; } CoglPipelineWrapMode;
/* NB: these values come from the equivalents in gl.h */ /* NB: these values come from the equivalents in gl.h */

View File

@ -368,10 +368,10 @@ _cogl_texture_quad_multiple_primitives (CoglTexture *texture,
state.v_to_q_scale_x = fabs (state.quad_len_x / (tx_2 - tx_1)); state.v_to_q_scale_x = fabs (state.quad_len_x / (tx_2 - tx_1));
state.v_to_q_scale_y = fabs (state.quad_len_y / (ty_2 - ty_1)); state.v_to_q_scale_y = fabs (state.quad_len_y / (ty_2 - ty_1));
/* cogl_meta_texture_foreach_in_region only allows WRAP_MODE_REPEAT. /* cogl_meta_texture_foreach_in_region only allows WRAP_MODE_REPEAT
* If CLAMP_TO_EDGE is in use then we have already dealt with * and WRAP_MODE_MIRRORED_REPEAT. If CLAMP_TO_EDGE is in use then we
* emulation for that and we can just pass WRAP_MODE_REPEAT here... * have already dealt with emulation for that and we can just pass
*/ * WRAP_MODE_REPEAT here... */
if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC || if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC ||
wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE) wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE)
wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT; wrap_s = COGL_PIPELINE_WRAP_MODE_REPEAT;

View File

@ -77,9 +77,9 @@ _cogl_span_iter_begin (CoglSpanIter *iter,
/* XXX: If CLAMP_TO_EDGE needs to be emulated then it needs to be /* XXX: If CLAMP_TO_EDGE needs to be emulated then it needs to be
* done at a higher level than here... */ * done at a higher level than here... */
g_return_if_fail (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT); g_return_if_fail (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT ||
wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT);
iter->index = 0;
iter->span = NULL; iter->span = NULL;
iter->spans = spans; iter->spans = spans;
@ -109,6 +109,25 @@ _cogl_span_iter_begin (CoglSpanIter *iter,
iter->wrap_mode = wrap_mode; iter->wrap_mode = wrap_mode;
if (wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT)
iter->index = 0;
else if (wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT)
{
if ((int)iter->origin % 2)
{
iter->index = iter->n_spans - 1;
iter->mirror_direction = -1;
iter->flipped = !iter->flipped;
}
else
{
iter->index = 0;
iter->mirror_direction = 1;
}
}
else
g_warn_if_reached ();
iter->cover_start = cover_start; iter->cover_start = cover_start;
iter->cover_end = cover_end; iter->cover_end = cover_end;
iter->pos = iter->origin; iter->pos = iter->origin;
@ -126,7 +145,20 @@ _cogl_span_iter_next (CoglSpanIter *iter)
/* Move current position */ /* Move current position */
iter->pos = iter->next_pos; iter->pos = iter->next_pos;
if (iter->wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT)
iter->index = (iter->index + 1) % iter->n_spans; iter->index = (iter->index + 1) % iter->n_spans;
else if (iter->wrap_mode == COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT)
{
iter->index += iter->mirror_direction;
if (iter->index == iter->n_spans || iter->index == -1)
{
iter->mirror_direction = -iter->mirror_direction;
iter->index += iter->mirror_direction;
iter->flipped = !iter->flipped;
}
}
else
g_warn_if_reached ();
/* Update intersection */ /* Update intersection */
_cogl_span_iter_update (iter); _cogl_span_iter_update (iter);

View File

@ -50,6 +50,7 @@ typedef struct _CoglSpanIter
gboolean intersects; gboolean intersects;
gboolean flipped; gboolean flipped;
CoglPipelineWrapMode wrap_mode; CoglPipelineWrapMode wrap_mode;
int mirror_direction;
} CoglSpanIter; } CoglSpanIter;
void void

View File

@ -198,6 +198,8 @@ cogl_features_available (CoglFeatureFlags features);
* supported with CoglBufferAccess including read support. * supported with CoglBufferAccess including read support.
* @COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is * @COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is
* supported with CoglBufferAccess including write support. * supported with CoglBufferAccess including write support.
* @COGL_FEATURE_ID_MIRRORED_REPEAT: Whether
* %COGL_PIPELINE_WRAP_MODE_MIRRORED_REPEAT is supported.
* *
* *
* All the capabilities that can vary between different GPUs supported * All the capabilities that can vary between different GPUs supported
@ -224,6 +226,7 @@ typedef enum _CoglFeatureID
COGL_FEATURE_ID_POINT_SPRITE, COGL_FEATURE_ID_POINT_SPRITE,
COGL_FEATURE_ID_MAP_BUFFER_FOR_READ, COGL_FEATURE_ID_MAP_BUFFER_FOR_READ,
COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE, COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE,
COGL_FEATURE_ID_MIRRORED_REPEAT,
/*< private > */ /*< private > */
_COGL_N_FEATURE_IDS _COGL_N_FEATURE_IDS

View File

@ -164,6 +164,9 @@ _cogl_gl_update_features (CoglContext *context,
COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE); COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE); COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 1, 4))
COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
gl_extensions = (const char *)ctx->glGetString (GL_EXTENSIONS); gl_extensions = (const char *)ctx->glGetString (GL_EXTENSIONS);
_cogl_feature_check_ext_functions (context, _cogl_feature_check_ext_functions (context,

View File

@ -94,6 +94,8 @@ _cogl_gles_update_features (CoglContext *context,
COGL_FLAGS_SET (context->features, COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE); COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE); COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
} }
private_flags |= COGL_PRIVATE_FEATURE_VBOS; private_flags |= COGL_PRIVATE_FEATURE_VBOS;