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
This commit is contained in:
Neil Roberts 2008-10-27 14:36:52 +00:00
parent c8b4de2d6d
commit 153f5ea73f
10 changed files with 110 additions and 44 deletions

View File

@ -579,6 +579,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,

View 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>

View 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;

View 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);

View 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 */

View 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,
@ -367,6 +371,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)
{

View 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;

View 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);

View 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;

View 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);
@ -278,6 +282,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)
{