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
#define GL_CLAMP_TO_BORDER 0x812d
#endif
#ifndef GL_MIRRORED_REPEAT
#define GL_MIRRORED_REPEAT 0x8370
#endif
typedef struct _CoglPipelineLayer CoglPipelineLayer;
#define COGL_PIPELINE_LAYER(OBJECT) ((CoglPipelineLayer *)OBJECT)
@ -54,6 +57,7 @@ typedef struct _CoglPipelineLayer CoglPipelineLayer;
typedef enum _CoglPipelineWrapModeInternal
{
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_BORDER = GL_CLAMP_TO_BORDER,
COGL_PIPELINE_WRAP_MODE_INTERNAL_AUTOMATIC = GL_ALWAYS

View File

@ -111,8 +111,9 @@ typedef enum {
*/
typedef enum {
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_AUTOMATIC = 0x0207
COGL_PIPELINE_WRAP_MODE_AUTOMATIC = 0x0207 /* GL_ALWAYS */
} CoglPipelineWrapMode;
/* 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_y = fabs (state.quad_len_y / (ty_2 - ty_1));
/* cogl_meta_texture_foreach_in_region only allows WRAP_MODE_REPEAT.
* If CLAMP_TO_EDGE is in use then we have already dealt with
* emulation for that and we can just pass WRAP_MODE_REPEAT here...
*/
/* cogl_meta_texture_foreach_in_region only allows WRAP_MODE_REPEAT
* and WRAP_MODE_MIRRORED_REPEAT. If CLAMP_TO_EDGE is in use then we
* have already dealt with emulation for that and we can just pass
* WRAP_MODE_REPEAT here... */
if (wrap_s == COGL_PIPELINE_WRAP_MODE_AUTOMATIC ||
wrap_s == COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE)
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
* 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->spans = spans;
@ -109,6 +109,25 @@ _cogl_span_iter_begin (CoglSpanIter *iter,
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_end = cover_end;
iter->pos = iter->origin;
@ -126,7 +145,20 @@ _cogl_span_iter_next (CoglSpanIter *iter)
/* Move current position */
iter->pos = iter->next_pos;
if (iter->wrap_mode == COGL_PIPELINE_WRAP_MODE_REPEAT)
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 */
_cogl_span_iter_update (iter);

View File

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

View File

@ -198,6 +198,8 @@ cogl_features_available (CoglFeatureFlags features);
* supported with CoglBufferAccess including read support.
* @COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is
* 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
@ -224,6 +226,7 @@ typedef enum _CoglFeatureID
COGL_FEATURE_ID_POINT_SPRITE,
COGL_FEATURE_ID_MAP_BUFFER_FOR_READ,
COGL_FEATURE_ID_MAP_BUFFER_FOR_WRITE,
COGL_FEATURE_ID_MIRRORED_REPEAT,
/*< private > */
_COGL_N_FEATURE_IDS

View File

@ -164,6 +164,9 @@ _cogl_gl_update_features (CoglContext *context,
COGL_FEATURE_ID_UNSIGNED_INT_INDICES, 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);
_cogl_feature_check_ext_functions (context,

View File

@ -94,6 +94,8 @@ _cogl_gles_update_features (CoglContext *context,
COGL_FLAGS_SET (context->features,
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_MIRRORED_REPEAT, TRUE);
}
private_flags |= COGL_PRIVATE_FEATURE_VBOS;