* clutter/cogl/gles/cogl-gles2-wrapper.h (CoglGles2Wrapper): Added

uniforms for alpha testing.

	* clutter/cogl/gles/cogl-gles2-wrapper.c
	(cogl_gles2_wrapper_init): Get the uniforms for alpha testing
	settings.
	(cogl_wrap_glEnable, cogl_wrap_glDisable): Enable/disable alpha
	testing.
	(cogl_wrap_glAlphaFunc): Filled in the wrapper.

	* clutter/cogl/gles/cogl-fixed-fragment-shader.glsl: Added alpha
	testing.

	* clutter/cogl/gles/cogl-gles2-wrapper.h:
	* clutter/cogl/gles/cogl-gles2-wrapper.c
	(cogl_wrap_glGetIntegerv): Added a wrapper for glGetIntegerv so
	that it can report zero clip planes.

	* clutter/cogl/gles/cogl.c:
	* clutter/cogl/gles/cogl-texture.c: Use the wrapped version of
	glGetIntegerv

	* clutter/cogl/gles/cogl-primitives.c (_cogl_path_fill_nodes): Use
	_cogl_features_available to check for the stencil buffer instead
	of an #ifdef. The stencil buffer is available in the default
	profile for the GLES 2 simulator.
This commit is contained in:
Neil Roberts 2008-05-29 13:29:04 +00:00
parent 38c9d46a0e
commit 559495caf7
6 changed files with 275 additions and 172 deletions

View File

@ -12,6 +12,20 @@ uniform bool alpha_only;
uniform bool fog_enabled; uniform bool fog_enabled;
uniform vec4 fog_color; uniform vec4 fog_color;
/* Alpha test options */
uniform bool alpha_test_enabled;
uniform int alpha_test_func;
uniform float alpha_test_ref;
/* Alpha test functions */
const int GL_NEVER = 0x0200;
const int GL_LESS = 0x0201;
const int GL_EQUAL = 0x0202;
const int GL_LEQUAL = 0x0203;
const int GL_GREATER = 0x0204;
const int GL_NOTEQUAL = 0x0205;
const int GL_GEQUAL = 0x0206;
void void
main (void) main (void)
{ {
@ -35,4 +49,41 @@ main (void)
if (fog_enabled) if (fog_enabled)
/* Mix the calculated color with the fog color */ /* Mix the calculated color with the fog color */
gl_FragColor.rgb = mix (fog_color.rgb, gl_FragColor.rgb, fog_amount); gl_FragColor.rgb = mix (fog_color.rgb, gl_FragColor.rgb, fog_amount);
/* Alpha testing */
if (alpha_test_enabled)
{
if (alpha_test_func == GL_NEVER)
discard;
else if (alpha_test_func == GL_LESS)
{
if (gl_FragColor.a >= alpha_test_ref)
discard;
}
else if (alpha_test_func == GL_EQUAL)
{
if (gl_FragColor.a != alpha_test_ref)
discard;
}
else if (alpha_test_func == GL_LEQUAL)
{
if (gl_FragColor.a > alpha_test_ref)
discard;
}
else if (alpha_test_func == GL_GREATER)
{
if (gl_FragColor.a <= alpha_test_ref)
discard;
}
else if (alpha_test_func == GL_NOTEQUAL)
{
if (gl_FragColor.a == alpha_test_ref)
discard;
}
else if (alpha_test_func == GL_GEQUAL)
{
if (gl_FragColor.a < alpha_test_ref)
discard;
}
}
} }

View File

@ -164,6 +164,13 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
wrapper->fog_color_uniform wrapper->fog_color_uniform
= glGetUniformLocation (wrapper->program, "fog_color"); = glGetUniformLocation (wrapper->program, "fog_color");
wrapper->alpha_test_enabled_uniform
= glGetUniformLocation (wrapper->program, "alpha_test_enabled");
wrapper->alpha_test_func_uniform
= glGetUniformLocation (wrapper->program, "alpha_test_func");
wrapper->alpha_test_ref_uniform
= glGetUniformLocation (wrapper->program, "alpha_test_ref");
/* Always use the first texture unit */ /* Always use the first texture unit */
glUniform1i (wrapper->bound_texture_uniform, 0); glUniform1i (wrapper->bound_texture_uniform, 0);
@ -184,6 +191,10 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
cogl_wrap_glFogx (GL_FOG_START, 0); cogl_wrap_glFogx (GL_FOG_START, 0);
cogl_wrap_glFogx (GL_FOG_END, 1); cogl_wrap_glFogx (GL_FOG_END, 1);
cogl_wrap_glFogxv (GL_FOG_COLOR, default_fog_color); cogl_wrap_glFogxv (GL_FOG_COLOR, default_fog_color);
/* Initialize alpha testing */
cogl_wrap_glDisable (GL_ALPHA_TEST);
cogl_wrap_glAlphaFunc (GL_ALWAYS, 0.0f);
} }
void void
@ -567,6 +578,10 @@ cogl_wrap_glEnable (GLenum cap)
glUniform1i (w->fog_enabled_uniform, GL_TRUE); glUniform1i (w->fog_enabled_uniform, GL_TRUE);
break; break;
case GL_ALPHA_TEST:
glUniform1i (w->alpha_test_enabled_uniform, GL_TRUE);
break;
default: default:
glEnable (cap); glEnable (cap);
} }
@ -587,6 +602,10 @@ cogl_wrap_glDisable (GLenum cap)
glUniform1i (w->fog_enabled_uniform, GL_FALSE); glUniform1i (w->fog_enabled_uniform, GL_FALSE);
break; break;
case GL_ALPHA_TEST:
glUniform1i (w->alpha_test_enabled_uniform, GL_FALSE);
break;
default: default:
glDisable (cap); glDisable (cap);
} }
@ -629,7 +648,15 @@ cogl_wrap_glDisableClientState (GLenum array)
void void
cogl_wrap_glAlphaFunc (GLenum func, GLclampf ref) cogl_wrap_glAlphaFunc (GLenum func, GLclampf ref)
{ {
/* FIXME */ _COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
if (ref < 0.0f)
ref = 0.0f;
else if (ref > 1.0f)
ref = 1.0f;
glUniform1i (w->alpha_test_func_uniform, func);
glUniform1f (w->alpha_test_ref_uniform, ref);
} }
void void
@ -656,6 +683,23 @@ cogl_gles2_float_array_to_fixed (int size, const GLfloat *floats,
*(fixeds++) = CLUTTER_FLOAT_TO_FIXED (*(floats++)); *(fixeds++) = CLUTTER_FLOAT_TO_FIXED (*(floats++));
} }
void
cogl_wrap_glGetIntegerv (GLenum pname, GLint *params)
{
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
switch (pname)
{
case GL_MAX_CLIP_PLANES:
*params = 0;
break;
default:
glGetIntegerv (pname, params);
break;
}
}
void void
cogl_wrap_glGetFixedv (GLenum pname, GLfixed *params) cogl_wrap_glGetFixedv (GLenum pname, GLfixed *params)
{ {

View File

@ -57,6 +57,10 @@ struct _CoglGles2Wrapper
GLint fog_end_uniform; GLint fog_end_uniform;
GLint fog_color_uniform; GLint fog_color_uniform;
GLint alpha_test_enabled_uniform;
GLint alpha_test_func_uniform;
GLint alpha_test_ref_uniform;
GLuint matrix_mode; GLuint matrix_mode;
GLfloat modelview_stack[COGL_GLES2_MODELVIEW_STACK_SIZE * 16]; GLfloat modelview_stack[COGL_GLES2_MODELVIEW_STACK_SIZE * 16];
GLuint modelview_stack_pos; GLuint modelview_stack_pos;
@ -149,6 +153,7 @@ void cogl_wrap_glColor4x (GLclampx r, GLclampx g, GLclampx b, GLclampx a);
void cogl_wrap_glClipPlanex (GLenum plane, GLfixed *equation); void cogl_wrap_glClipPlanex (GLenum plane, GLfixed *equation);
void cogl_wrap_glGetIntegerv (GLenum pname, GLint *params);
void cogl_wrap_glGetFixedv (GLenum pname, GLfixed *params); void cogl_wrap_glGetFixedv (GLenum pname, GLfixed *params);
void cogl_wrap_glFogx (GLenum pname, GLfixed param); void cogl_wrap_glFogx (GLenum pname, GLfixed param);
@ -191,6 +196,7 @@ void cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
#define cogl_wrap_glAlphaFunc glAlphaFunc #define cogl_wrap_glAlphaFunc glAlphaFunc
#define cogl_wrap_glColor4x glColor4x #define cogl_wrap_glColor4x glColor4x
#define cogl_wrap_glClipPlanex glClipPlanex #define cogl_wrap_glClipPlanex glClipPlanex
#define cogl_wrap_glGetIntegerv glGetIntegerv
#define cogl_wrap_glGetFixedv glGetFixedv #define cogl_wrap_glGetFixedv glGetFixedv
#define cogl_wrap_glFogx glFogx #define cogl_wrap_glFogx glFogx
#define cogl_wrap_glFogxv glFogxv #define cogl_wrap_glFogxv glFogxv

View File

@ -172,186 +172,188 @@ _cogl_path_fill_nodes ()
bounds_w = CLUTTER_FIXED_CEIL (ctx->path_nodes_max.x - ctx->path_nodes_min.x); bounds_w = CLUTTER_FIXED_CEIL (ctx->path_nodes_max.x - ctx->path_nodes_min.x);
bounds_h = CLUTTER_FIXED_CEIL (ctx->path_nodes_max.y - ctx->path_nodes_min.y); bounds_h = CLUTTER_FIXED_CEIL (ctx->path_nodes_max.y - ctx->path_nodes_min.y);
#if GOT_WORKING_STENCIL_BUFFER if (cogl_features_available (COGL_FEATURE_STENCIL_BUFFER))
{
GE( glClear (GL_STENCIL_BUFFER_BIT) ); GE( glClear (GL_STENCIL_BUFFER_BIT) );
GE( cogl_wrap_glEnable (GL_STENCIL_TEST) ); GE( cogl_wrap_glEnable (GL_STENCIL_TEST) );
GE( glStencilFunc (GL_ALWAYS, 0x0, 0x0) ); GE( glStencilFunc (GL_ALWAYS, 0x0, 0x0) );
GE( glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT) ); GE( glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT) );
GE( glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE) ); GE( glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE) );
cogl_enable (COGL_ENABLE_VERTEX_ARRAY cogl_enable (COGL_ENABLE_VERTEX_ARRAY
| (ctx->color_alpha < 255 ? COGL_ENABLE_BLEND : 0)); | (ctx->color_alpha < 255 ? COGL_ENABLE_BLEND : 0));
GE( cogl_wrap_glVertexPointer (2, GL_FIXED, 0, ctx->path_nodes) ); GE( cogl_wrap_glVertexPointer (2, GL_FIXED, 0, ctx->path_nodes) );
GE( cogl_wrap_glDrawArrays (GL_TRIANGLE_FAN, 0, ctx->path_nodes_size) ); GE( cogl_wrap_glDrawArrays (GL_TRIANGLE_FAN, 0, ctx->path_nodes_size) );
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) ); GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
GE( glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) ); GE( glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) );
GE( glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) ); GE( glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) );
cogl_rectangle (bounds_x, bounds_y, bounds_w, bounds_h);
cogl_rectangle (bounds_x, bounds_y, bounds_w, bounds_h); GE( cogl_wrap_glDisable (GL_STENCIL_TEST) );
}
GE( cogl_wrap_glDisable (GL_STENCIL_TEST) ); else
#else {
{ /* This is our edge list it stores intersections between our
/* This is our edge list it stores intersections between our curve and * curve and scanlines, it should probably be implemented with a
* scanlines, it should probably be implemented with a data structure * data structure that has smaller overhead for inserting the
* that has smaller overhead for inserting the curve/scanline intersections. * curve/scanline intersections.
*/ */
GSList *scanlines[bounds_h]; GSList *scanlines[bounds_h];
gint i; gint i;
gint prev_x; gint prev_x;
gint prev_y; gint prev_y;
gint first_x; gint first_x;
gint first_y; gint first_y;
gint lastdir=-2; /* last direction we vere moving */ gint lastdir=-2; /* last direction we vere moving */
gint lastline=-1; /* the previous scanline we added to */ gint lastline=-1; /* the previous scanline we added to */
/* clear scanline intersection lists */ /* clear scanline intersection lists */
for (i=0; i < bounds_h; i++) for (i=0; i < bounds_h; i++)
scanlines[i]=NULL; scanlines[i]=NULL;
first_x = prev_x = CLUTTER_FIXED_TO_INT (ctx->path_nodes[0].x); first_x = prev_x = CLUTTER_FIXED_TO_INT (ctx->path_nodes[0].x);
first_y = prev_y = CLUTTER_FIXED_TO_INT (ctx->path_nodes[0].y); first_y = prev_y = CLUTTER_FIXED_TO_INT (ctx->path_nodes[0].y);
/* create scanline intersection list */
for (i=1; i<ctx->path_nodes_size; i++)
{
gint dest_x = CLUTTER_FIXED_TO_INT (ctx->path_nodes[i].x);
gint dest_y = CLUTTER_FIXED_TO_INT (ctx->path_nodes[i].y);
gint ydir;
gint dx;
gint dy;
gint y;
fill_close:
dx = dest_x - prev_x;
dy = dest_y - prev_y;
if (dy < 0)
ydir = -1;
else if (dy > 0)
ydir = 1;
else
ydir = 0;
/* do linear interpolation between vertexes */
for (y=prev_y; y!= dest_y; y += ydir)
{
/* only add a point if the scanline has changed and we're
* within bounds.
*/
if (y-bounds_y >= 0 &&
y-bounds_y < bounds_h &&
lastline != y)
{
gint x = prev_x + (dx * (y-prev_y)) / dy;
scanlines[ y - bounds_y ]=
g_slist_insert_sorted (scanlines[ y - bounds_y],
GINT_TO_POINTER(x),
compare_ints);
if (ydir != lastdir && /* add a double entry when changing */
lastdir!=-2) /* vertical direction */
scanlines[ y - bounds_y ]=
g_slist_insert_sorted (scanlines[ y - bounds_y],
GINT_TO_POINTER(x),
compare_ints);
lastdir = ydir;
lastline = y;
}
}
prev_x = dest_x;
prev_y = dest_y;
/* if we're on the last knot, fake the first vertex being a
next one */
if (ctx->path_nodes_size == i+1)
{
dest_x = first_x;
dest_y = first_y;
i++; /* to make the loop finally end */
goto fill_close;
}
}
/* create scanline intersection list */
for (i=1; i<ctx->path_nodes_size; i++)
{ {
gint dest_x = CLUTTER_FIXED_TO_INT (ctx->path_nodes[i].x); gint spans = 0;
gint dest_y = CLUTTER_FIXED_TO_INT (ctx->path_nodes[i].y); gint span_no;
gint ydir; GLfixed *coords;
gint dx;
gint dy;
gint y;
fill_close: /* count number of spans */
dx = dest_x - prev_x; for (i=0; i < bounds_h; i++)
dy = dest_y - prev_y; {
GSList *iter = scanlines[i];
while (iter)
{
GSList *next = iter->next;
if (!next)
{
break;
}
/* draw the segments that should be visible */
spans ++;
iter = next->next;
}
}
coords = g_malloc0 (spans * sizeof (GLfixed) * 3 * 2 * 2);
if (dy < 0) span_no = 0;
ydir = -1; /* build list of triangles */
else if (dy > 0) for (i=0; i < bounds_h; i++)
ydir = 1; {
else GSList *iter = scanlines[i];
ydir = 0; while (iter)
{
GSList *next = iter->next;
GLfixed x0, x1;
GLfixed y0, y1;
if (!next)
break;
/* do linear interpolation between vertexes */ x0 = CLUTTER_INT_TO_FIXED (GPOINTER_TO_INT (iter->data));
for (y=prev_y; y!= dest_y; y += ydir) x1 = CLUTTER_INT_TO_FIXED (GPOINTER_TO_INT (next->data));
{ y0 = CLUTTER_INT_TO_FIXED (bounds_y + i);
y1 = CLUTTER_INT_TO_FIXED (bounds_y + i + 1) + 2048;
/* render scanlines 1.0625 high to avoid gaps when
transformed */
/* only add a point if the scanline has changed and we're coords[span_no * 12 + 0] = x0;
* within bounds. coords[span_no * 12 + 1] = y0;
*/ coords[span_no * 12 + 2] = x1;
if (y-bounds_y >= 0 && coords[span_no * 12 + 3] = y0;
y-bounds_y < bounds_h && coords[span_no * 12 + 4] = x1;
lastline != y) coords[span_no * 12 + 5] = y1;
{ coords[span_no * 12 + 6] = x0;
gint x = prev_x + (dx * (y-prev_y)) / dy; coords[span_no * 12 + 7] = y0;
coords[span_no * 12 + 8] = x0;
scanlines[ y - bounds_y ]= coords[span_no * 12 + 9] = y1;
g_slist_insert_sorted (scanlines[ y - bounds_y], coords[span_no * 12 + 10] = x1;
GINT_TO_POINTER(x), coords[span_no * 12 + 11] = y1;
compare_ints); span_no ++;
iter = next->next;
if (ydir != lastdir && /* add a double entry when changing */ }
lastdir!=-2) /* vertical direction */ }
scanlines[ y - bounds_y ]= for (i=0; i < bounds_h; i++)
g_slist_insert_sorted (scanlines[ y - bounds_y], {
GINT_TO_POINTER(x), g_slist_free (scanlines[i]);
compare_ints); }
lastdir = ydir;
lastline = y;
}
}
prev_x = dest_x;
prev_y = dest_y;
/* if we're on the last knot, fake the first vertex being a next one */
if (ctx->path_nodes_size == i+1)
{
dest_x = first_x;
dest_y = first_y;
i++; /* to make the loop finally end */
goto fill_close;
}
}
{
gint spans = 0;
gint span_no;
GLfixed *coords;
/* count number of spans */
for (i=0; i < bounds_h; i++)
{
GSList *iter = scanlines[i];
while (iter)
{
GSList *next = iter->next;
if (!next)
{
break;
}
/* draw the segments that should be visible */
spans ++;
iter = next->next;
}
}
coords = g_malloc0 (spans * sizeof (GLfixed) * 3 * 2 * 2);
span_no = 0;
/* build list of triangles */
for (i=0; i < bounds_h; i++)
{
GSList *iter = scanlines[i];
while (iter)
{
GSList *next = iter->next;
GLfixed x0, x1;
GLfixed y0, y1;
if (!next)
break;
x0 = CLUTTER_INT_TO_FIXED (GPOINTER_TO_INT (iter->data));
x1 = CLUTTER_INT_TO_FIXED (GPOINTER_TO_INT (next->data));
y0 = CLUTTER_INT_TO_FIXED (bounds_y + i);
y1 = CLUTTER_INT_TO_FIXED (bounds_y + i + 1) + 2048;
/* render scanlines 1.0625 high to avoid gaps when transformed */
coords[span_no * 12 + 0] = x0;
coords[span_no * 12 + 1] = y0;
coords[span_no * 12 + 2] = x1;
coords[span_no * 12 + 3] = y0;
coords[span_no * 12 + 4] = x1;
coords[span_no * 12 + 5] = y1;
coords[span_no * 12 + 6] = x0;
coords[span_no * 12 + 7] = y0;
coords[span_no * 12 + 8] = x0;
coords[span_no * 12 + 9] = y1;
coords[span_no * 12 + 10] = x1;
coords[span_no * 12 + 11] = y1;
span_no ++;
iter = next->next;
}
}
for (i=0; i < bounds_h; i++)
{
g_slist_free (scanlines[i]);
}
/* render triangles */ /* render triangles */
cogl_enable (COGL_ENABLE_VERTEX_ARRAY cogl_enable (COGL_ENABLE_VERTEX_ARRAY
| (ctx->color_alpha < 255 ? COGL_ENABLE_BLEND : 0)); | (ctx->color_alpha < 255 ? COGL_ENABLE_BLEND : 0));
GE ( cogl_wrap_glVertexPointer (2, GL_FIXED, 0, coords ) ); GE ( cogl_wrap_glVertexPointer (2, GL_FIXED, 0, coords ) );
GE ( cogl_wrap_glDrawArrays (GL_TRIANGLES, 0, spans * 2 * 3)); GE ( cogl_wrap_glDrawArrays (GL_TRIANGLES, 0, spans * 2 * 3));
g_free (coords); g_free (coords);
} }
} }
#endif
} }

View File

@ -381,7 +381,7 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888); bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888);
/* Viewport needs to have some size and be inside the window for this */ /* Viewport needs to have some size and be inside the window for this */
GE( glGetIntegerv (GL_VIEWPORT, viewport) ); GE( cogl_wrap_glGetIntegerv (GL_VIEWPORT, viewport) );
if (viewport[0] < 0 || viewport[1] < 0 || if (viewport[0] < 0 || viewport[1] < 0 ||
viewport[2] <= 0 || viewport[3] <= 0) viewport[2] <= 0 || viewport[3] <= 0)
@ -422,10 +422,10 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
still doesn't seem to have an alpha buffer. This might be just still doesn't seem to have an alpha buffer. This might be just
a PowerVR issue. a PowerVR issue.
GLint r_bits, g_bits, b_bits, a_bits; GLint r_bits, g_bits, b_bits, a_bits;
GE( glGetIntegerv (GL_ALPHA_BITS, &a_bits) ); GE( cogl_wrap_glGetIntegerv (GL_ALPHA_BITS, &a_bits) );
GE( glGetIntegerv (GL_RED_BITS, &r_bits) ); GE( cogl_wrap_glGetIntegerv (GL_RED_BITS, &r_bits) );
GE( glGetIntegerv (GL_GREEN_BITS, &g_bits) ); GE( cogl_wrap_glGetIntegerv (GL_GREEN_BITS, &g_bits) );
GE( glGetIntegerv (GL_BLUE_BITS, &b_bits) ); GE( cogl_wrap_glGetIntegerv (GL_BLUE_BITS, &b_bits) );
printf ("R bits: %d\n", r_bits); printf ("R bits: %d\n", r_bits);
printf ("G bits: %d\n", g_bits); printf ("G bits: %d\n", g_bits);
printf ("B bits: %d\n", b_bits); printf ("B bits: %d\n", b_bits);

View File

@ -482,11 +482,11 @@ _cogl_features_init ()
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
GE( glGetIntegerv (GL_STENCIL_BITS, &stencil_bits) ); GE( cogl_wrap_glGetIntegerv (GL_STENCIL_BITS, &stencil_bits) );
if (stencil_bits > 0) if (stencil_bits > 0)
flags |= COGL_FEATURE_STENCIL_BUFFER; flags |= COGL_FEATURE_STENCIL_BUFFER;
GE( glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) ); GE( cogl_wrap_glGetIntegerv (GL_MAX_CLIP_PLANES, &max_clip_planes) );
if (max_clip_planes >= 4) if (max_clip_planes >= 4)
flags |= COGL_FEATURE_FOUR_CLIP_PLANES; flags |= COGL_FEATURE_FOUR_CLIP_PLANES;
@ -538,13 +538,13 @@ void
cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha) cogl_get_bitmasks (gint *red, gint *green, gint *blue, gint *alpha)
{ {
if (red) if (red)
GE( glGetIntegerv(GL_RED_BITS, red) ); GE( cogl_wrap_glGetIntegerv(GL_RED_BITS, red) );
if (green) if (green)
GE( glGetIntegerv(GL_GREEN_BITS, green) ); GE( cogl_wrap_glGetIntegerv(GL_GREEN_BITS, green) );
if (blue) if (blue)
GE( glGetIntegerv(GL_BLUE_BITS, blue) ); GE( cogl_wrap_glGetIntegerv(GL_BLUE_BITS, blue) );
if (alpha) if (alpha)
GE( glGetIntegerv(GL_ALPHA_BITS, alpha ) ); GE( cogl_wrap_glGetIntegerv(GL_ALPHA_BITS, alpha ) );
} }
void void