[cogl/wip/rib/master-next: 27/35] Adds support for a mirrored repeat wrap mode



commit 6d5f979cae4058ddedd3c15504f06a0b8c378a1a
Author: Robert Bragg <robert linux intel com>
Date:   Thu Oct 13 14:02:37 2011 +0100

    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.

 cogl/cogl-pipeline-layer-private.h |    4 +++
 cogl/cogl-pipeline-layer-state.h   |    3 +-
 cogl/cogl-primitives.c             |    8 +++---
 cogl/cogl-spans.c                  |   38 +++++++++++++++++++++++++++++++++--
 cogl/cogl-spans.h                  |    1 +
 cogl/cogl.h                        |    5 +++-
 cogl/driver/gl/cogl-gl.c           |    1 +
 cogl/driver/gles/cogl-gles.c       |    2 +
 8 files changed, 53 insertions(+), 9 deletions(-)
---
diff --git a/cogl/cogl-pipeline-layer-private.h b/cogl/cogl-pipeline-layer-private.h
index 5df32c4..76fcf23 100644
--- a/cogl/cogl-pipeline-layer-private.h
+++ b/cogl/cogl-pipeline-layer-private.h
@@ -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
diff --git a/cogl/cogl-pipeline-layer-state.h b/cogl/cogl-pipeline-layer-state.h
index cf31bf5..b1f5736 100644
--- a/cogl/cogl-pipeline-layer-state.h
+++ b/cogl/cogl-pipeline-layer-state.h
@@ -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 */
 
diff --git a/cogl/cogl-primitives.c b/cogl/cogl-primitives.c
index 27707bb..84b6bb4 100644
--- a/cogl/cogl-primitives.c
+++ b/cogl/cogl-primitives.c
@@ -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;
diff --git a/cogl/cogl-spans.c b/cogl/cogl-spans.c
index 1b2586c..c98a93d 100644
--- a/cogl/cogl-spans.c
+++ b/cogl/cogl-spans.c
@@ -78,9 +78,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;
@@ -110,6 +110,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;
@@ -127,7 +146,20 @@ _cogl_span_iter_next (CoglSpanIter *iter)
   /* Move current position */
   iter->pos = iter->next_pos;
 
-  iter->index = (iter->index + 1) % iter->n_spans;
+  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);
diff --git a/cogl/cogl-spans.h b/cogl/cogl-spans.h
index e69833e..767f94a 100644
--- a/cogl/cogl-spans.h
+++ b/cogl/cogl-spans.h
@@ -50,6 +50,7 @@ typedef struct _CoglSpanIter
   gboolean intersects;
   gboolean flipped;
   CoglPipelineWrapMode wrap_mode;
+  int mirror_direction;
 } CoglSpanIter;
 
 void
diff --git a/cogl/cogl.h b/cogl/cogl.h
index 946fb1a..ecca354 100644
--- a/cogl/cogl.h
+++ b/cogl/cogl.h
@@ -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
@@ -223,7 +225,8 @@ typedef enum _CoglFeatureID
   COGL_FEATURE_ID_DEPTH_RANGE,
   COGL_FEATURE_ID_POINT_SPRITE,
   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
 } CoglFeatureID;
 
 
diff --git a/cogl/driver/gl/cogl-gl.c b/cogl/driver/gl/cogl-gl.c
index f1bea59..0f76363 100644
--- a/cogl/driver/gl/cogl-gl.c
+++ b/cogl/driver/gl/cogl-gl.c
@@ -163,6 +163,7 @@ _cogl_gl_update_features (CoglContext *context,
   _cogl_bitmask_set (&ctx->features,
                      COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
   _cogl_bitmask_set (&ctx->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
+  _cogl_bitmask_set (&ctx->features, COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
 
   gl_extensions = (const char *)ctx->glGetString (GL_EXTENSIONS);
 
diff --git a/cogl/driver/gles/cogl-gles.c b/cogl/driver/gles/cogl-gles.c
index da969ac..5774b33 100644
--- a/cogl/driver/gles/cogl-gles.c
+++ b/cogl/driver/gles/cogl-gles.c
@@ -94,6 +94,8 @@ _cogl_gles_update_features (CoglContext *context,
       _cogl_bitmask_set (&context->features,
                          COGL_FEATURE_ID_TEXTURE_NPOT_BASIC, TRUE);
       _cogl_bitmask_set (&context->features, COGL_FEATURE_ID_DEPTH_RANGE, TRUE);
+      _cogl_bitmask_set (&context->features,
+                         COGL_FEATURE_ID_MIRRORED_REPEAT, TRUE);
     }
 
   private_flags |= COGL_PRIVATE_FEATURE_VBOS;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]