Bug 1189 - Backface culling
authorNeil Roberts <neil@openedhand.com>
Mon, 27 Oct 2008 14:36:52 +0000 (14:36 +0000)
committerNeil Roberts <neil@openedhand.com>
Mon, 27 Oct 2008 14:36:52 +0000 (14:36 +0000)
* clutter/cogl/gl/cogl-texture.c (cogl_texture_polygon)
(_cogl_texture_quad_sw, _cogl_texture_quad_hw):
* clutter/cogl/gles/cogl-texture.c (cogl_texture_polygon)
(_cogl_texture_quad_sw, _cogl_texture_quad_hw): Enable backface
culling in GL if it is requested.

* clutter/cogl/gles/cogl-texture.c (_cogl_texture_quad_sw)
(_cogl_texture_quad_hw):
* clutter/cogl/gl/cogl-texture.c (_cogl_texture_quad_sw)
(_cogl_texture_quad_hw): Reorder the
vertices so that they are counter-clockwise.

* clutter/cogl/gles/cogl-context.h (CoglContext):
* clutter/cogl/gl/cogl-context.h (CoglContext): Added a flag to
store whether backface culling is currently enabled.

* clutter/cogl/gles/cogl.c (cogl_enable_backface_culling):
* clutter/cogl/gl/cogl.c (cogl_enable_backface_culling): New
function

* doc/reference/cogl/cogl-sections.txt: Add
cogl_enable_backface_culling

ChangeLog
clutter/cogl/cogl.h.in
clutter/cogl/gl/cogl-context.h
clutter/cogl/gl/cogl-internal.h
clutter/cogl/gl/cogl-texture.c
clutter/cogl/gl/cogl.c
clutter/cogl/gles/cogl-context.h
clutter/cogl/gles/cogl-internal.h
clutter/cogl/gles/cogl-texture.c
clutter/cogl/gles/cogl.c
doc/reference/cogl/cogl-sections.txt

index 762f845..d460eb0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,32 @@
 2008-10-27  Neil Roberts  <neil@linux.intel.com>
 
+       Bug 1189 - Backface culling
+
+       * clutter/cogl/gl/cogl-texture.c (cogl_texture_polygon)
+       (_cogl_texture_quad_sw, _cogl_texture_quad_hw):
+       * clutter/cogl/gles/cogl-texture.c (cogl_texture_polygon)
+       (_cogl_texture_quad_sw, _cogl_texture_quad_hw): Enable backface
+       culling in GL if it is requested.
+
+       * clutter/cogl/gles/cogl-texture.c (_cogl_texture_quad_sw)
+       (_cogl_texture_quad_hw):
+       * clutter/cogl/gl/cogl-texture.c (_cogl_texture_quad_sw)
+       (_cogl_texture_quad_hw): Reorder the
+       vertices so that they are counter-clockwise.
+
+       * clutter/cogl/gles/cogl-context.h (CoglContext): 
+       * clutter/cogl/gl/cogl-context.h (CoglContext): Added a flag to
+       store whether backface culling is currently enabled.
+
+       * clutter/cogl/gles/cogl.c (cogl_enable_backface_culling): 
+       * clutter/cogl/gl/cogl.c (cogl_enable_backface_culling): New
+       function
+
+       * doc/reference/cogl/cogl-sections.txt: Add
+       cogl_enable_backface_culling
+
+2008-10-27  Neil Roberts  <neil@linux.intel.com>
+
        Bug 1196 - Texture border drawing problems
 
        * clutter/cogl/gl/cogl-texture.c (_cogl_texture_upload_subregion_to_gl)
index 814ca33..ac3aa34 100644 (file)
@@ -580,6 +580,18 @@ void            cogl_clip_stack_restore       (void);
 void            cogl_enable_depth_test        (gboolean            setting);
 
 /**
+ * cogl_enable_backface_culling:
+ * @setting: %TRUE to enable backface culling or %FALSE to disable.
+ *
+ * Sets whether textures positioned so that their backface is showing
+ * should be hidden. This can be used to efficiently draw two-sided
+ * textures or fully closed cubes without enabling depth testing. Only
+ * calls to cogl_texture_rectangle() and cogl_texture_polygon() are
+ * affected. Backface culling is disabled by default.
+ */
+void            cogl_enable_backface_culling  (gboolean            setting);
+
+/**
  * cogl_alpha_func:
  * @func: the comparison function to use, one of CGL_NEVER, CGL_LESS,
  * CGL_EQUAL, CGL_LEQUAL, CGL_GREATER, CGL_NOTEQUAL, CGL_GEQUAL and GL_ALWAYS.
index 96b3199..4b442ec 100644 (file)
@@ -40,6 +40,8 @@ typedef struct
   guint8            color_alpha;
   COGLenum          blend_src_factor;
   COGLenum          blend_dst_factor;
+
+  gboolean          enable_backface_culling;
   
   /* Primitives */
   CoglFixedVec2     path_start;
index 19fc37c..bfc7cc7 100644 (file)
@@ -56,6 +56,7 @@ const char *_cogl_error_string(GLenum errorCode);
 #define COGL_ENABLE_TEXTURE_RECT      (1<<4)
 #define COGL_ENABLE_VERTEX_ARRAY      (1<<5)
 #define COGL_ENABLE_TEXCOORD_ARRAY    (1<<6)
+#define COGL_ENABLE_BACKFACE_CULLING  (1<<7)
 
 gint
 _cogl_get_format_bpp (CoglPixelFormat format);
index 3bdf3bd..11f91cf 100644 (file)
@@ -1949,6 +1949,9 @@ _cogl_texture_quad_sw (CoglTexture *tex,
     {
       enable_flags |= COGL_ENABLE_BLEND;
     }
+
+  if (ctx->enable_backface_culling)
+    enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
   
   cogl_enable (enable_flags);
   
@@ -2050,21 +2053,21 @@ _cogl_texture_quad_sw (CoglTexture *tex,
          
          /* Draw textured quad */
          glBegin (GL_QUADS);
-         
+
          glTexCoord2f (CFX_F(slice_tx1), CFX_F(slice_ty1));
          glVertex2f   (CFX_F(slice_qx1), CFX_F(slice_qy1));
-         
-         glTexCoord2f (CFX_F(slice_tx2), CFX_F(slice_ty1));
-         glVertex2f   (CFX_F(slice_qx2), CFX_F(slice_qy1));
-         
-         glTexCoord2f (CFX_F(slice_tx2), CFX_F(slice_ty2));
-         glVertex2f   (CFX_F(slice_qx2), CFX_F(slice_qy2));
-         
+
          glTexCoord2f (CFX_F(slice_tx1), CFX_F(slice_ty2));
          glVertex2f   (CFX_F(slice_qx1), CFX_F(slice_qy2));
-         
+
+         glTexCoord2f (CFX_F(slice_tx2), CFX_F(slice_ty2));
+         glVertex2f   (CFX_F(slice_qx2), CFX_F(slice_qy2));
+
+         glTexCoord2f (CFX_F(slice_tx2), CFX_F(slice_ty1));
+         glVertex2f   (CFX_F(slice_qx2), CFX_F(slice_qy1));
+
          GE( glEnd () );
-         
+
 #undef CFX_F
        }
     }
@@ -2101,6 +2104,9 @@ _cogl_texture_quad_hw (CoglTexture *tex,
       enable_flags |= COGL_ENABLE_BLEND;
     }
   
+  if (ctx->enable_backface_culling)
+    enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
+
   cogl_enable (enable_flags);
   
   /* Pick and bind opengl texture object */
@@ -2117,24 +2123,24 @@ _cogl_texture_quad_hw (CoglTexture *tex,
   ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size;
 
 #define CFX_F(x) CLUTTER_FIXED_TO_FLOAT(x)
-  
+
   /* Draw textured quad */
   glBegin (GL_QUADS);
-  
+
   glTexCoord2f (CFX_F(tx1), CFX_F(ty1));
   glVertex2f   (CFX_F(x1),  CFX_F(y1));
-  
-  glTexCoord2f (CFX_F(tx2), CFX_F(ty1));
-  glVertex2f   (CFX_F(x2),  CFX_F(y1));
-  
-  glTexCoord2f (CFX_F(tx2), CFX_F(ty2));
-  glVertex2f   (CFX_F(x2),  CFX_F(y2));
-  
+
   glTexCoord2f (CFX_F(tx1), CFX_F(ty2));
   glVertex2f   (CFX_F(x1),  CFX_F(y2));
-  
+
+  glTexCoord2f (CFX_F(tx2), CFX_F(ty2));
+  glVertex2f   (CFX_F(x2),  CFX_F(y2));
+
+  glTexCoord2f (CFX_F(tx2), CFX_F(ty1));
+  glVertex2f   (CFX_F(x2),  CFX_F(y1));
+
   GE( glEnd () );
-  
+
 #undef CFX_F
 }
 
@@ -2231,6 +2237,9 @@ cogl_texture_polygon (CoglHandle         handle,
   int               i, x, y, vnum;
   GLuint            gl_handle;
   CoglTexSliceSpan *y_span, *x_span;
+  gulong            enable_flags;
+
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
 
   /* Check if valid texture */
   if (!cogl_is_texture (handle))
@@ -2261,7 +2270,12 @@ cogl_texture_polygon (CoglHandle         handle,
   tex = _cogl_texture_pointer_from_handle (handle);
   
   /* Prepare GL state */
-  cogl_enable (COGL_ENABLE_TEXTURE_2D | COGL_ENABLE_BLEND);
+  enable_flags = COGL_ENABLE_TEXTURE_2D | COGL_ENABLE_BLEND;
+
+  if (ctx->enable_backface_culling)
+    enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
+
+  cogl_enable (enable_flags);
 
   /* Temporarily change the wrapping mode on all of the slices to use
      a transparent border */
index 6906927..567d292 100644 (file)
@@ -314,6 +314,10 @@ cogl_enable (gulong flags)
   cogl_toggle_flag (ctx, flags,
                    COGL_ENABLE_TEXTURE_2D,
                    GL_TEXTURE_2D);
+
+  cogl_toggle_flag (ctx, flags,
+                    COGL_ENABLE_BACKFACE_CULLING,
+                    GL_CULL_FACE);
   
   cogl_toggle_client_flag (ctx, flags,
                           COGL_ENABLE_VERTEX_ARRAY,
@@ -368,6 +372,14 @@ cogl_enable_depth_test (gboolean setting)
 }
 
 void
+cogl_enable_backface_culling (gboolean setting)
+{
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  ctx->enable_backface_culling = setting;
+}
+
+void
 cogl_color (const ClutterColor *color)
 {
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
index cc2e4cf..6efa790 100644 (file)
@@ -49,6 +49,8 @@ typedef struct
   guint8               color_alpha;
   COGLenum             blend_src_factor;
   COGLenum             blend_dst_factor;
+
+  gboolean             enable_backface_culling;
   
   /* Primitives */
   CoglFixedVec2        path_start;
index 8a6b638..9275f4b 100644 (file)
@@ -57,6 +57,7 @@ const char *_cogl_error_string(GLenum errorCode);
 #define COGL_ENABLE_VERTEX_ARRAY      (1<<5)
 #define COGL_ENABLE_TEXCOORD_ARRAY    (1<<6)
 #define COGL_ENABLE_COLOR_ARRAY       (1<<7)
+#define COGL_ENABLE_BACKFACE_CULLING  (1<<8)
 
 gint
 _cogl_get_format_bpp (CoglPixelFormat format);
index 97cd258..395f980 100644 (file)
@@ -1924,6 +1924,9 @@ _cogl_texture_quad_sw (CoglTexture *tex,
       enable_flags |= COGL_ENABLE_BLEND;
     }
   
+  if (ctx->enable_backface_culling)
+    enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
+
   cogl_enable (enable_flags);
   
   GE( cogl_wrap_glTexCoordPointer (2, GL_FIXED, 0, tex_coords) );
@@ -2021,18 +2024,18 @@ _cogl_texture_quad_sw (CoglTexture *tex,
          
          GE( cogl_gles2_wrapper_bind_texture (tex->gl_target, gl_handle,
                                               tex->gl_intformat) );
-         
+
          /* Draw textured quad */
-         tex_coords[0] = slice_tx1; tex_coords[1] = slice_ty1;
-         tex_coords[2] = slice_tx2; tex_coords[3] = slice_ty1;
-         tex_coords[4] = slice_tx1; tex_coords[5] = slice_ty2;
-         tex_coords[6] = slice_tx2; tex_coords[7] = slice_ty2;
-         
-         quad_coords[0] = slice_qx1; quad_coords[1] = slice_qy1;
-         quad_coords[2] = slice_qx2; quad_coords[3] = slice_qy1;
-         quad_coords[4] = slice_qx1; quad_coords[5] = slice_qy2;
-         quad_coords[6] = slice_qx2; quad_coords[7] = slice_qy2;
-         
+          tex_coords[0] = slice_tx1; tex_coords[1] = slice_ty2;
+          tex_coords[2] = slice_tx2; tex_coords[3] = slice_ty2;
+          tex_coords[4] = slice_tx1; tex_coords[5] = slice_ty1;
+          tex_coords[6] = slice_tx2; tex_coords[7] = slice_ty1;
+
+          quad_coords[0] = slice_qx1; quad_coords[1] = slice_qy2;
+          quad_coords[2] = slice_qx2; quad_coords[3] = slice_qy2;
+          quad_coords[4] = slice_qx1; quad_coords[5] = slice_qy1;
+          quad_coords[6] = slice_qx2; quad_coords[7] = slice_qy1;
+
          GE (cogl_wrap_glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
        }
     }
@@ -2071,6 +2074,9 @@ _cogl_texture_quad_hw (CoglTexture *tex,
       enable_flags |= COGL_ENABLE_BLEND;
     }
   
+  if (ctx->enable_backface_culling)
+    enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
+
   cogl_enable (enable_flags);
   
   GE( cogl_wrap_glTexCoordPointer (2, GL_FIXED, 0, tex_coords) );
@@ -2090,16 +2096,16 @@ _cogl_texture_quad_hw (CoglTexture *tex,
   ty2 = ty2 * (y_span->size - y_span->waste) / y_span->size;
 
   /* Draw textured quad */
-  tex_coords[0] = tx1; tex_coords[1] = ty1;
-  tex_coords[2] = tx2; tex_coords[3] = ty1;
-  tex_coords[4] = tx1; tex_coords[5] = ty2;
-  tex_coords[6] = tx2; tex_coords[7] = ty2;
-  
-  quad_coords[0] = x1; quad_coords[1] = y1;
-  quad_coords[2] = x2; quad_coords[3] = y1;
-  quad_coords[4] = x1; quad_coords[5] = y2;
-  quad_coords[6] = x2; quad_coords[7] = y2;
-  
+  tex_coords[0] = tx1; tex_coords[1] = ty2;
+  tex_coords[2] = tx2; tex_coords[3] = ty2;
+  tex_coords[4] = tx1; tex_coords[5] = ty1;
+  tex_coords[6] = tx2; tex_coords[7] = ty1;
+
+  quad_coords[0] = x1; quad_coords[1] = y2;
+  quad_coords[2] = x2; quad_coords[3] = y2;
+  quad_coords[4] = x1; quad_coords[5] = y1;
+  quad_coords[6] = x2; quad_coords[7] = y1;
+
   GE (cogl_wrap_glDrawArrays (GL_TRIANGLE_STRIP, 0, 4) );
 }
 
@@ -2258,6 +2264,9 @@ cogl_texture_polygon (CoglHandle         handle,
   else if (ctx->color_alpha < 255)
     enable_flags |= COGL_ENABLE_BLEND;
 
+  if (ctx->enable_backface_culling)
+    enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
+
   if (use_color)
     {
       enable_flags |= COGL_ENABLE_COLOR_ARRAY;
index 7259680..82cbeed 100644 (file)
@@ -222,7 +222,11 @@ cogl_enable (gulong flags)
   cogl_toggle_flag (ctx, flags,
                    COGL_ENABLE_TEXTURE_2D,
                    GL_TEXTURE_2D);
-  
+
+  cogl_toggle_flag (ctx, flags,
+                    COGL_ENABLE_BACKFACE_CULLING,
+                    GL_CULL_FACE);
+
   cogl_toggle_client_flag (ctx, flags,
                           COGL_ENABLE_VERTEX_ARRAY,
                           GL_VERTEX_ARRAY);
@@ -279,6 +283,14 @@ cogl_enable_depth_test (gboolean setting)
 }
 
 void
+cogl_enable_backface_culling (gboolean setting)
+{
+  _COGL_GET_CONTEXT (ctx, NO_RETVAL);
+
+  ctx->enable_backface_culling = setting;
+}
+
+void
 cogl_color (const ClutterColor *color)
 {
   _COGL_GET_CONTEXT (ctx, NO_RETVAL);
index ed873ce..c7c751f 100644 (file)
@@ -34,6 +34,7 @@ cogl_clip_stack_save
 cogl_clip_stack_restore
 <SUBSECTION>
 cogl_enable_depth_test
+cogl_enable_backface_culling
 cogl_alpha_func
 cogl_fog_set
 </SECTION>