* clutter/cogl/gles/cogl-texture.c:
(cogl_texture_download_from_gl:) Implemented a workaround for missing alpha framebuffer channel. There are still some issues with detecting whether alpha is present in the framebuffer. See comments in code. Test-cogl-tex-getset now successfully retrieves a RGBA texture image data.
This commit is contained in:
parent
006573ac61
commit
4cb0d58ceb
@ -238,63 +238,24 @@ _cogl_texture_upload_to_gl (CoglTexture *tex)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_texture_download_from_gl (CoglTexture *tex,
|
||||
static void
|
||||
_cogl_texture_draw_and_read (CoglTexture *tex,
|
||||
CoglBitmap *target_bmp,
|
||||
GLuint target_gl_format,
|
||||
GLuint target_gl_type)
|
||||
ClutterColor *back_color,
|
||||
GLint *viewport)
|
||||
{
|
||||
gint bpp;
|
||||
GLint viewport[4];
|
||||
CoglHandle handle;
|
||||
ClutterColor cback = {0x0, 0x0, 0x0, 0x0};
|
||||
ClutterColor cwhite = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||
CoglBitmap rect_bmp;
|
||||
ClutterFixed rx1, ry1;
|
||||
ClutterFixed rx2, ry2;
|
||||
ClutterFixed tx1, ty1;
|
||||
ClutterFixed tx2, ty2;
|
||||
int bw, bh;
|
||||
COGLenum old_src_factor;
|
||||
COGLenum old_dst_factor;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, FALSE);
|
||||
CoglBitmap rect_bmp;
|
||||
CoglHandle handle;
|
||||
|
||||
handle = _cogl_texture_handle_from_pointer (tex);
|
||||
bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888);
|
||||
|
||||
/* Viewport needs to have some size and be inside the window for this */
|
||||
GE( glGetIntegerv (GL_VIEWPORT, viewport) );
|
||||
|
||||
if (viewport[0] < 0 || viewport[1] < 0 ||
|
||||
viewport[2] <= 0 || viewport[3] <= 0)
|
||||
return FALSE;
|
||||
|
||||
/* Setup orthographic projection into current viewport
|
||||
(0,0 in bottom-left corner to draw the texture
|
||||
upside-down so we match the way glReadPixels works) */
|
||||
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
GE( glOrthox (0, CLUTTER_INT_TO_FIXED (viewport[2]),
|
||||
0, CLUTTER_INT_TO_FIXED (viewport[3]),
|
||||
CLUTTER_INT_TO_FIXED (0),
|
||||
CLUTTER_INT_TO_FIXED (100)) );
|
||||
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
/* Draw to all channels */
|
||||
cogl_draw_buffer (COGL_WINDOW_BUFFER | COGL_MASK_BUFFER, 0);
|
||||
|
||||
/* Store old blending factors and setup direct copy operation */
|
||||
old_src_factor = ctx->blend_src_factor;
|
||||
old_dst_factor = ctx->blend_dst_factor;
|
||||
cogl_blend_func (CGL_ONE, CGL_ZERO);
|
||||
|
||||
/* If whole image fits into the viewport and target buffer
|
||||
has got no special rowstride, we can do it in one pass */
|
||||
if (tex->bitmap.width < viewport[2] - viewport[0] &&
|
||||
@ -303,8 +264,7 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
|
||||
{
|
||||
/* Clear buffer with transparent black, draw with white
|
||||
for direct copy to framebuffer */
|
||||
cogl_paint_init (&cback);
|
||||
cogl_color (&cwhite);
|
||||
cogl_paint_init (back_color);
|
||||
|
||||
/* Draw the texture image */
|
||||
cogl_texture_rectangle (handle,
|
||||
@ -355,8 +315,7 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
|
||||
|
||||
/* Clear buffer with transparent black, draw with white
|
||||
for direct copy to framebuffer */
|
||||
cogl_paint_init (&cback);
|
||||
cogl_color (&cwhite);
|
||||
cogl_paint_init (back_color);
|
||||
|
||||
/* Draw a portion of texture */
|
||||
cogl_texture_rectangle (handle,
|
||||
@ -396,7 +355,116 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
|
||||
|
||||
#undef CFIX
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_cogl_texture_download_from_gl (CoglTexture *tex,
|
||||
CoglBitmap *target_bmp,
|
||||
GLuint target_gl_format,
|
||||
GLuint target_gl_type)
|
||||
{
|
||||
gint bpp;
|
||||
GLint viewport[4];
|
||||
ClutterColor cwhite = {0xFF, 0xFF, 0xFF, 0xFF};
|
||||
CoglBitmap alpha_bmp;
|
||||
COGLenum old_src_factor;
|
||||
COGLenum old_dst_factor;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, FALSE);
|
||||
|
||||
bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888);
|
||||
|
||||
/* Viewport needs to have some size and be inside the window for this */
|
||||
GE( glGetIntegerv (GL_VIEWPORT, viewport) );
|
||||
|
||||
if (viewport[0] < 0 || viewport[1] < 0 ||
|
||||
viewport[2] <= 0 || viewport[3] <= 0)
|
||||
return FALSE;
|
||||
|
||||
/* Setup orthographic projection into current viewport
|
||||
(0,0 in bottom-left corner to draw the texture
|
||||
upside-down so we match the way glReadPixels works) */
|
||||
|
||||
GE( glMatrixMode (GL_PROJECTION) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
GE( glOrthox (0, CLUTTER_INT_TO_FIXED (viewport[2]),
|
||||
0, CLUTTER_INT_TO_FIXED (viewport[3]),
|
||||
CLUTTER_INT_TO_FIXED (0),
|
||||
CLUTTER_INT_TO_FIXED (100)) );
|
||||
|
||||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glPushMatrix () );
|
||||
GE( glLoadIdentity () );
|
||||
|
||||
/* Draw to all channels */
|
||||
cogl_draw_buffer (COGL_WINDOW_BUFFER | COGL_MASK_BUFFER, 0);
|
||||
|
||||
/* Store old blending factors */
|
||||
old_src_factor = ctx->blend_src_factor;
|
||||
old_dst_factor = ctx->blend_dst_factor;
|
||||
|
||||
/* Direct copy operation */
|
||||
cogl_color (&cwhite);
|
||||
cogl_blend_func (CGL_ONE, CGL_ZERO);
|
||||
_cogl_texture_draw_and_read (tex, target_bmp,
|
||||
&cwhite, viewport);
|
||||
|
||||
/* Check whether texture has alpha and framebuffer not */
|
||||
/* FIXME: For some reason even if ALPHA_BITS is 8, the framebuffer
|
||||
still doesn't seem to have an alpha buffer. This might be just
|
||||
a PowerVR issue.
|
||||
GLint r_bits, g_bits, b_bits, a_bits;
|
||||
GE( glGetIntegerv (GL_ALPHA_BITS, &a_bits) );
|
||||
GE( glGetIntegerv (GL_RED_BITS, &r_bits) );
|
||||
GE( glGetIntegerv (GL_GREEN_BITS, &g_bits) );
|
||||
GE( glGetIntegerv (GL_BLUE_BITS, &b_bits) );
|
||||
printf ("R bits: %d\n", r_bits);
|
||||
printf ("G bits: %d\n", g_bits);
|
||||
printf ("B bits: %d\n", b_bits);
|
||||
printf ("A bits: %d\n", a_bits);
|
||||
if ((tex->bitmap.format & COGL_A_BIT) && a_bits == 0) */
|
||||
{
|
||||
guchar *srcdata;
|
||||
guchar *dstdata;
|
||||
guchar *srcpixel;
|
||||
guchar *dstpixel;
|
||||
gint x,y;
|
||||
|
||||
/* Create temp bitmap for alpha values */
|
||||
alpha_bmp.format = COGL_PIXEL_FORMAT_RGBA_8888;
|
||||
alpha_bmp.width = target_bmp->width;
|
||||
alpha_bmp.height = target_bmp->height;
|
||||
alpha_bmp.rowstride = bpp * alpha_bmp.width;
|
||||
alpha_bmp.data = (guchar*) g_malloc (alpha_bmp.rowstride *
|
||||
alpha_bmp.height);
|
||||
|
||||
/* Draw alpha values into RGB channels */
|
||||
cogl_blend_func (CGL_ZERO, CGL_SRC_ALPHA);
|
||||
_cogl_texture_draw_and_read (tex, &alpha_bmp,
|
||||
&cwhite, viewport);
|
||||
|
||||
/* Copy temp R to target A */
|
||||
srcdata = alpha_bmp.data;
|
||||
dstdata = target_bmp->data;
|
||||
|
||||
for (y=0; y<target_bmp->height; ++y)
|
||||
{
|
||||
for (x=0; x<target_bmp->width; ++x)
|
||||
{
|
||||
srcpixel = srcdata + x*bpp;
|
||||
dstpixel = dstdata + x*bpp;
|
||||
dstpixel[3] = srcpixel[0];
|
||||
}
|
||||
srcdata += alpha_bmp.rowstride;
|
||||
dstdata += target_bmp->rowstride;
|
||||
}
|
||||
|
||||
g_free (alpha_bmp.data);
|
||||
}
|
||||
|
||||
/* Restore old state */
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix ();
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
|
Loading…
Reference in New Issue
Block a user