mirror of
https://github.com/brl/mutter.git
synced 2025-02-17 05:44:08 +00:00
Bug 1406 - Handling of premultiplication in clutter
Merge branch 'premultiplication' [cogl-texture docs] Improves the documentation of the internal_format args [test-premult] Adds a unit test for texture upload premultiplication semantics [fog] Document that fogging only works with opaque or unmultipled colors [test-blend-strings] Explicitly request RGBA_888 tex format for test textures [premultiplication] Be more conservative with what data gets premultiplied [bitmap] Fixes _cogl_bitmap_fallback_unpremult [cogl-bitmap] Fix minor copy and paste error in _cogl_bitmap_fallback_premult Avoid unnecesary unpremultiplication when saving to local data Don't unpremultiply Cairo data Default to a blend function that expects premultiplied colors Implement premultiplication for CoglBitmap Use correct texture format for pixmap textures and FBO's Add cogl_color_premultiply()
This commit is contained in:
commit
c52eda6715
12
cogl-color.h
12
cogl-color.h
@ -228,6 +228,18 @@ float cogl_color_get_blue (const CoglColor *color);
|
|||||||
*/
|
*/
|
||||||
float cogl_color_get_alpha (const CoglColor *color);
|
float cogl_color_get_alpha (const CoglColor *color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_color_premultiply:
|
||||||
|
* @color: the color to premultiply
|
||||||
|
*
|
||||||
|
* Converts a non-premultiplied color to a pre-multiplied color. For
|
||||||
|
* example, semi-transparent red is (1.0, 0, 0, 0.5) when non-premultiplied
|
||||||
|
* and (0.5, 0, 0, 0.5) when premultiplied.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
void cogl_color_premultiply (CoglColor *color);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __COGL_COLOR_H__ */
|
#endif /* __COGL_COLOR_H__ */
|
||||||
|
@ -138,6 +138,11 @@ gboolean cogl_is_material (CoglHandle handle);
|
|||||||
*
|
*
|
||||||
* This is the basic color of the material, used when no lighting is enabled.
|
* This is the basic color of the material, used when no lighting is enabled.
|
||||||
*
|
*
|
||||||
|
* Note that if you don't add any layers to the material then the color
|
||||||
|
* will be blended unmodified with the destination; the default blend
|
||||||
|
* expects premultiplied colors: for example, use (0.5, 0.0, 0.0, 0.5) for
|
||||||
|
* semi-transparent red. See cogl_color_premultiply().
|
||||||
|
*
|
||||||
* The default value is (1.0, 1.0, 1.0, 1.0)
|
* The default value is (1.0, 1.0, 1.0, 1.0)
|
||||||
*
|
*
|
||||||
* Since 1.0
|
* Since 1.0
|
||||||
@ -475,6 +480,11 @@ void cogl_material_set_alpha_test_function (CoglHandle material,
|
|||||||
* </programlisting>
|
* </programlisting>
|
||||||
* </section>
|
* </section>
|
||||||
*
|
*
|
||||||
|
* The default blend string is:
|
||||||
|
* "RGBA = ADD (SRC_COLOR, DST_COLOR*(1-SRC_COLOR[A]))"
|
||||||
|
* That gives normal alpha-blending when the calculated color for the material
|
||||||
|
* is in premultiplied form.
|
||||||
|
*
|
||||||
* Returns: TRUE if the blend string was successfully parsed, and the described
|
* Returns: TRUE if the blend string was successfully parsed, and the described
|
||||||
* blending is supported by the underlying driver/hardware. If there
|
* blending is supported by the underlying driver/hardware. If there
|
||||||
* was an error, it returns FALSE.
|
* was an error, it returns FALSE.
|
||||||
|
@ -68,7 +68,13 @@ CoglHandle cogl_texture_new_with_size (guint width,
|
|||||||
* @filename: the file to load
|
* @filename: the file to load
|
||||||
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
|
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
|
||||||
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the
|
* @internal_format: the #CoglPixelFormat to use for the GPU storage of the
|
||||||
* texture
|
* texture. If COGL_PIXEL_FORMAT_ANY is given then a premultiplied
|
||||||
|
* format similar to the format of the source data will be used. The
|
||||||
|
* default blending equations of Cogl expect premultiplied color data;
|
||||||
|
* the main use of passing a non-premultiplied format here is if you
|
||||||
|
* have non-premultiplied source data and are going to adjust the blend
|
||||||
|
* mode (see cogl_material_set_blend()) or use the data for something
|
||||||
|
* other than straight blending.
|
||||||
* @error: return location for a #GError or %NULL
|
* @error: return location for a #GError or %NULL
|
||||||
*
|
*
|
||||||
* Creates a COGL texture from an image file.
|
* Creates a COGL texture from an image file.
|
||||||
@ -90,7 +96,13 @@ CoglHandle cogl_texture_new_from_file (const gchar *filename,
|
|||||||
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
|
* @flags: Optional flags for the texture, or %COGL_TEXTURE_NONE
|
||||||
* @format: the #CoglPixelFormat the buffer is stored in in RAM
|
* @format: the #CoglPixelFormat the buffer is stored in in RAM
|
||||||
* @internal_format: the #CoglPixelFormat that will be used for storing
|
* @internal_format: the #CoglPixelFormat that will be used for storing
|
||||||
* the buffer on the GPU
|
* the buffer on the GPU. If COGL_PIXEL_FORMAT_ANY is given then a
|
||||||
|
* premultiplied format similar to the format of the source data will
|
||||||
|
* be used. The default blending equations of Cogl expect premultiplied
|
||||||
|
* color data; the main use of passing a non-premultiplied format here
|
||||||
|
* is if you have non-premultiplied source data and are going to adjust
|
||||||
|
* the blend mode (see cogl_material_set_blend()) or use the data for
|
||||||
|
* something other than straight blending.
|
||||||
* @rowstride: the memory offset in bytes between the starts of
|
* @rowstride: the memory offset in bytes between the starts of
|
||||||
* scanlines in @data
|
* scanlines in @data
|
||||||
* @data: pointer the memory region where the source buffer resides
|
* @data: pointer the memory region where the source buffer resides
|
||||||
|
32
cogl.h.in
32
cogl.h.in
@ -386,13 +386,22 @@ gboolean cogl_get_backface_culling_enabled (void);
|
|||||||
* @z_near: Position along z-axis where no fogging should be applied
|
* @z_near: Position along z-axis where no fogging should be applied
|
||||||
* @z_far: Position along z-axes where full fogging should be applied
|
* @z_far: Position along z-axes where full fogging should be applied
|
||||||
*
|
*
|
||||||
* Enables fogging. Fogging causes vertices that are further away from
|
* Enables fogging. Fogging causes vertices that are further away from the eye
|
||||||
* the eye to be rendered with a different color. The color is determined
|
* to be rendered with a different color. The color is determined according to
|
||||||
* according to the chosen fog mode; at it's simplest the color is
|
* the chosen fog mode; at it's simplest the color is linearly interpolated so
|
||||||
* linearly interpolated so that vertices at @z_near are drawn fully
|
* that vertices at @z_near are drawn fully with their original color and
|
||||||
* with their original color and vertices at @z_far are drawn fully
|
* vertices at @z_far are drawn fully with @fog_color. Fogging will remain
|
||||||
* with @fog_color. Fogging will remain enabled until you call
|
* enabled until you call cogl_disable_fog().
|
||||||
* cogl_disable_fog().
|
*
|
||||||
|
* Note: The fogging functions only work correctly when primitives use
|
||||||
|
* unmultiplied alpha colors. By default Cogl will premultiply textures
|
||||||
|
* and cogl_set_source_color will premultiply colors, so unless you
|
||||||
|
* explicitly load your textures requesting an unmultiplied
|
||||||
|
* internal_format and use cogl_material_set_color you can only use
|
||||||
|
* fogging with fully opaque primitives.
|
||||||
|
*
|
||||||
|
* We can look to improve this in the future when we can depend on
|
||||||
|
* fragment shaders.
|
||||||
*/
|
*/
|
||||||
void cogl_set_fog (const CoglColor *fog_color,
|
void cogl_set_fog (const CoglColor *fog_color,
|
||||||
CoglFogMode mode,
|
CoglFogMode mode,
|
||||||
@ -455,8 +464,13 @@ void cogl_set_source (CoglHandle material);
|
|||||||
* cogl_set_source_color:
|
* cogl_set_source_color:
|
||||||
* @color: a #CoglColor
|
* @color: a #CoglColor
|
||||||
*
|
*
|
||||||
* Sets the source color using normalized values for each component.
|
* This is a convenience function for creating a solid fill source material
|
||||||
* This color will be used for any subsequent drawing operation.
|
* from the given color. This color will be used for any subsequent drawing
|
||||||
|
* operation.
|
||||||
|
*
|
||||||
|
* The color will be premultiplied by Cogl, so the color should be
|
||||||
|
* non-premultiplied. For example: use (1.0, 0.0, 0.0, 0.5) for
|
||||||
|
* semi-transparent red.
|
||||||
*
|
*
|
||||||
* See also cogl_set_source_color4ub() and cogl_set_source_color4f()
|
* See also cogl_set_source_color4ub() and cogl_set_source_color4f()
|
||||||
* if you already have the color components.
|
* if you already have the color components.
|
||||||
|
@ -163,9 +163,9 @@ _cogl_unpremult_alpha_last (const guchar *src, guchar *dst)
|
|||||||
{
|
{
|
||||||
guchar alpha = src[3];
|
guchar alpha = src[3];
|
||||||
|
|
||||||
dst[0] = ((((gulong) src[0] >> 16) & 0xff) * 255 ) / alpha;
|
dst[0] = (src[0] * 255) / alpha;
|
||||||
dst[1] = ((((gulong) src[1] >> 8) & 0xff) * 255 ) / alpha;
|
dst[1] = (src[1] * 255) / alpha;
|
||||||
dst[2] = ((((gulong) src[2] >> 0) & 0xff) * 255 ) / alpha;
|
dst[2] = (src[2] * 255) / alpha;
|
||||||
dst[3] = alpha;
|
dst[3] = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,11 +175,46 @@ _cogl_unpremult_alpha_first (const guchar *src, guchar *dst)
|
|||||||
guchar alpha = src[0];
|
guchar alpha = src[0];
|
||||||
|
|
||||||
dst[0] = alpha;
|
dst[0] = alpha;
|
||||||
dst[1] = ((((gulong) src[1] >> 16) & 0xff) * 255 ) / alpha;
|
dst[1] = (src[1] * 255) / alpha;
|
||||||
dst[2] = ((((gulong) src[2] >> 8) & 0xff) * 255 ) / alpha;
|
dst[2] = (src[2] * 255) / alpha;
|
||||||
dst[3] = ((((gulong) src[3] >> 0) & 0xff) * 255 ) / alpha;
|
dst[3] = (src[3] * 255) / alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No division form of floor((c*a + 128)/255) (I first encountered
|
||||||
|
* this in the RENDER implementation in the X server.) Being exact
|
||||||
|
* is important for a == 255 - we want to get exactly c.
|
||||||
|
*/
|
||||||
|
#define MULT(d,c,a,t) G_STMT_START { t = c * a + 128; d = ((t >> 8) + t) >> 8; } G_STMT_END
|
||||||
|
|
||||||
|
inline static void
|
||||||
|
_cogl_premult_alpha_last (const guchar *src, guchar *dst)
|
||||||
|
{
|
||||||
|
guchar alpha = src[3];
|
||||||
|
/* Using a separate temporary per component has given slightly better
|
||||||
|
* code generation with GCC in the past; it shouldn't do any worse in
|
||||||
|
* any case.
|
||||||
|
*/
|
||||||
|
guint t1, t2, t3;
|
||||||
|
MULT(dst[0], src[0], alpha, t1);
|
||||||
|
MULT(dst[1], src[1], alpha, t2);
|
||||||
|
MULT(dst[2], src[2], alpha, t3);
|
||||||
|
dst[3] = alpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void
|
||||||
|
_cogl_premult_alpha_first (const guchar *src, guchar *dst)
|
||||||
|
{
|
||||||
|
guchar alpha = src[0];
|
||||||
|
guint t1, t2, t3;
|
||||||
|
|
||||||
|
dst[0] = alpha;
|
||||||
|
MULT(dst[1], src[1], alpha, t1);
|
||||||
|
MULT(dst[2], src[2], alpha, t2);
|
||||||
|
MULT(dst[3], src[3], alpha, t3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef MULT
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_bitmap_fallback_can_convert (CoglPixelFormat src, CoglPixelFormat dst)
|
_cogl_bitmap_fallback_can_convert (CoglPixelFormat src, CoglPixelFormat dst)
|
||||||
{
|
{
|
||||||
@ -211,6 +246,12 @@ _cogl_bitmap_fallback_can_unpremult (CoglPixelFormat format)
|
|||||||
return ((format & COGL_UNORDERED_MASK) == COGL_PIXEL_FORMAT_32);
|
return ((format & COGL_UNORDERED_MASK) == COGL_PIXEL_FORMAT_32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_bitmap_fallback_can_premult (CoglPixelFormat format)
|
||||||
|
{
|
||||||
|
return ((format & COGL_UNORDERED_MASK) == COGL_PIXEL_FORMAT_32);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_bitmap_fallback_convert (const CoglBitmap *bmp,
|
_cogl_bitmap_fallback_convert (const CoglBitmap *bmp,
|
||||||
CoglBitmap *dst_bmp,
|
CoglBitmap *dst_bmp,
|
||||||
@ -324,34 +365,86 @@ _cogl_bitmap_fallback_unpremult (const CoglBitmap *bmp,
|
|||||||
* dst_bmp->height
|
* dst_bmp->height
|
||||||
* dst_bmp->rowstride);
|
* dst_bmp->rowstride);
|
||||||
|
|
||||||
/* FIXME: Optimize */
|
|
||||||
for (y = 0; y < bmp->height; y++)
|
for (y = 0; y < bmp->height; y++)
|
||||||
{
|
{
|
||||||
src = (guchar*)bmp->data + y * bmp->rowstride;
|
src = (guchar*)bmp->data + y * bmp->rowstride;
|
||||||
dst = (guchar*)dst_bmp->data + y * dst_bmp->rowstride;
|
dst = (guchar*)dst_bmp->data + y * dst_bmp->rowstride;
|
||||||
|
|
||||||
for (x = 0; x < bmp->width; x++)
|
if (bmp->format & COGL_AFIRST_BIT)
|
||||||
{
|
{
|
||||||
/* FIXME: Would be nice to at least remove this inner
|
for (x = 0; x < bmp->width; x++)
|
||||||
* branching, but not sure it can be done without
|
{
|
||||||
* rewriting of the whole loop */
|
if (src[0] == 0)
|
||||||
if (bmp->format & COGL_AFIRST_BIT)
|
_cogl_unpremult_alpha_0 (src, dst);
|
||||||
{
|
else
|
||||||
if (src[0] == 0)
|
_cogl_unpremult_alpha_first (src, dst);
|
||||||
_cogl_unpremult_alpha_0 (src, dst);
|
src += bpp;
|
||||||
else
|
dst += bpp;
|
||||||
_cogl_unpremult_alpha_first (src, dst);
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (src[3] == 0)
|
for (x = 0; x < bmp->width; x++)
|
||||||
_cogl_unpremult_alpha_0 (src, dst);
|
{
|
||||||
else
|
if (src[0] == 0)
|
||||||
_cogl_unpremult_alpha_last (src, dst);
|
_cogl_unpremult_alpha_0 (src, dst);
|
||||||
}
|
else
|
||||||
|
_cogl_unpremult_alpha_last (src, dst);
|
||||||
|
src += bpp;
|
||||||
|
dst += bpp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
src += bpp;
|
return TRUE;
|
||||||
dst += bpp;
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_bitmap_fallback_premult (const CoglBitmap *bmp,
|
||||||
|
CoglBitmap *dst_bmp)
|
||||||
|
{
|
||||||
|
guchar *src;
|
||||||
|
guchar *dst;
|
||||||
|
gint bpp;
|
||||||
|
gint x,y;
|
||||||
|
|
||||||
|
/* Make sure format supported for un-premultiplication */
|
||||||
|
if (!_cogl_bitmap_fallback_can_premult (bmp->format))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
bpp = _cogl_get_format_bpp (bmp->format);
|
||||||
|
|
||||||
|
/* Initialize destination bitmap */
|
||||||
|
*dst_bmp = *bmp;
|
||||||
|
dst_bmp->format |= COGL_PREMULT_BIT;
|
||||||
|
|
||||||
|
/* Allocate a new buffer to hold converted data */
|
||||||
|
dst_bmp->data = g_malloc (sizeof(guchar)
|
||||||
|
* dst_bmp->height
|
||||||
|
* dst_bmp->rowstride);
|
||||||
|
|
||||||
|
for (y = 0; y < bmp->height; y++)
|
||||||
|
{
|
||||||
|
src = (guchar*)bmp->data + y * bmp->rowstride;
|
||||||
|
dst = (guchar*)dst_bmp->data + y * dst_bmp->rowstride;
|
||||||
|
|
||||||
|
if (bmp->format & COGL_AFIRST_BIT)
|
||||||
|
{
|
||||||
|
for (x = 0; x < bmp->width; x++)
|
||||||
|
{
|
||||||
|
_cogl_premult_alpha_first (src, dst);
|
||||||
|
src += bpp;
|
||||||
|
dst += bpp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (x = 0; x < bmp->width; x++)
|
||||||
|
{
|
||||||
|
_cogl_premult_alpha_last (src, dst);
|
||||||
|
src += bpp;
|
||||||
|
dst += bpp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,12 @@ _cogl_bitmap_can_unpremult (CoglPixelFormat format)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_bitmap_can_premult (CoglPixelFormat format)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_bitmap_convert (const CoglBitmap *bmp,
|
_cogl_bitmap_convert (const CoglBitmap *bmp,
|
||||||
CoglBitmap *dst_bmp,
|
CoglBitmap *dst_bmp,
|
||||||
@ -64,6 +70,13 @@ _cogl_bitmap_unpremult (const CoglBitmap *bmp,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_bitmap_premult (const CoglBitmap *bmp,
|
||||||
|
CoglBitmap *dst_bmp)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_QUARTZ
|
#ifdef USE_QUARTZ
|
||||||
|
|
||||||
/* lacking GdkPixbuf and other useful GError domains, define one of our own */
|
/* lacking GdkPixbuf and other useful GError domains, define one of our own */
|
||||||
|
@ -52,6 +52,12 @@ _cogl_bitmap_can_unpremult (CoglPixelFormat format);
|
|||||||
gboolean
|
gboolean
|
||||||
_cogl_bitmap_fallback_can_unpremult (CoglPixelFormat format);
|
_cogl_bitmap_fallback_can_unpremult (CoglPixelFormat format);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_bitmap_can_premult (CoglPixelFormat format);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_bitmap_fallback_can_premult (CoglPixelFormat format);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_bitmap_convert (const CoglBitmap *bmp,
|
_cogl_bitmap_convert (const CoglBitmap *bmp,
|
||||||
CoglBitmap *dst_bmp,
|
CoglBitmap *dst_bmp,
|
||||||
@ -69,6 +75,14 @@ gboolean
|
|||||||
_cogl_bitmap_fallback_unpremult (const CoglBitmap *bmp,
|
_cogl_bitmap_fallback_unpremult (const CoglBitmap *bmp,
|
||||||
CoglBitmap *dst_bmp);
|
CoglBitmap *dst_bmp);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_bitmap_premult (const CoglBitmap *bmp,
|
||||||
|
CoglBitmap *dst_bmp);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
_cogl_bitmap_fallback_premult (const CoglBitmap *bmp,
|
||||||
|
CoglBitmap *dst_bmp);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_cogl_bitmap_from_file (CoglBitmap *bmp,
|
_cogl_bitmap_from_file (CoglBitmap *bmp,
|
||||||
const gchar *filename,
|
const gchar *filename,
|
||||||
|
@ -87,8 +87,8 @@ _cogl_bitmap_convert_and_premult (const CoglBitmap *bmp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do we need to unpremultiply */
|
/* Do we need to unpremultiply */
|
||||||
if ((bmp->format & COGL_PREMULT_BIT) == 0 &&
|
if ((bmp->format & COGL_PREMULT_BIT) > 0 &&
|
||||||
(dst_format & COGL_PREMULT_BIT) > 0)
|
(dst_format & COGL_PREMULT_BIT) == 0)
|
||||||
{
|
{
|
||||||
/* Try unpremultiplying using imaging library */
|
/* Try unpremultiplying using imaging library */
|
||||||
if (!_cogl_bitmap_unpremult (&new_bmp, &tmp_bmp))
|
if (!_cogl_bitmap_unpremult (&new_bmp, &tmp_bmp))
|
||||||
@ -112,14 +112,28 @@ _cogl_bitmap_convert_and_premult (const CoglBitmap *bmp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do we need to premultiply */
|
/* Do we need to premultiply */
|
||||||
if ((bmp->format & COGL_PREMULT_BIT) > 0 &&
|
if ((bmp->format & COGL_PREMULT_BIT) == 0 &&
|
||||||
(dst_format & COGL_PREMULT_BIT) == 0)
|
(dst_format & COGL_PREMULT_BIT) > 0)
|
||||||
{
|
{
|
||||||
/* FIXME: implement premultiplication */
|
/* Try premultiplying using imaging library */
|
||||||
|
if (!_cogl_bitmap_premult (&new_bmp, &tmp_bmp))
|
||||||
|
{
|
||||||
|
/* ... or try fallback */
|
||||||
|
if (!_cogl_bitmap_fallback_premult (&new_bmp, &tmp_bmp))
|
||||||
|
{
|
||||||
|
if (new_bmp_owner)
|
||||||
|
g_free (new_bmp.data);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update bitmap with new data */
|
||||||
if (new_bmp_owner)
|
if (new_bmp_owner)
|
||||||
g_free (new_bmp.data);
|
g_free (new_bmp.data);
|
||||||
|
|
||||||
return FALSE;
|
new_bmp = tmp_bmp;
|
||||||
|
new_bmp_owner = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output new bitmap info */
|
/* Output new bitmap info */
|
||||||
|
@ -153,6 +153,14 @@ cogl_color_get_alpha (const CoglColor *color)
|
|||||||
return ((float) color->alpha / 255.0);
|
return ((float) color->alpha / 255.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_color_premultiply (CoglColor *color)
|
||||||
|
{
|
||||||
|
color->red = (color->red * color->alpha + 128) / 255;
|
||||||
|
color->green = (color->green * color->alpha + 128) / 255;
|
||||||
|
color->blue = (color->blue * color->alpha + 128) / 255;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_set_source_color4ub (guint8 red,
|
cogl_set_source_color4ub (guint8 red,
|
||||||
guint8 green,
|
guint8 green,
|
||||||
|
@ -109,7 +109,7 @@ cogl_material_new (void)
|
|||||||
material->blend_constant[2] = 0;
|
material->blend_constant[2] = 0;
|
||||||
material->blend_constant[3] = 0;
|
material->blend_constant[3] = 0;
|
||||||
#endif
|
#endif
|
||||||
material->blend_src_factor_rgb = GL_SRC_ALPHA;
|
material->blend_src_factor_rgb = GL_ONE;
|
||||||
material->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA;
|
material->blend_dst_factor_rgb = GL_ONE_MINUS_SRC_ALPHA;
|
||||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
|
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
|
||||||
|
|
||||||
|
@ -250,12 +250,17 @@ cogl_get_backface_culling_enabled (void)
|
|||||||
void
|
void
|
||||||
cogl_set_source_color (const CoglColor *color)
|
cogl_set_source_color (const CoglColor *color)
|
||||||
{
|
{
|
||||||
|
CoglColor premultiplied;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
/* In case cogl_set_source_texture was previously used... */
|
/* In case cogl_set_source_texture was previously used... */
|
||||||
cogl_material_remove_layer (ctx->default_material, 0);
|
cogl_material_remove_layer (ctx->default_material, 0);
|
||||||
|
|
||||||
cogl_material_set_color (ctx->default_material, color);
|
premultiplied = *color;
|
||||||
|
cogl_color_premultiply (&premultiplied);
|
||||||
|
cogl_material_set_color (ctx->default_material, &premultiplied);
|
||||||
|
|
||||||
cogl_set_source (ctx->default_material);
|
cogl_set_source (ctx->default_material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1085,18 +1085,12 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format,
|
|||||||
GLenum glformat = 0;
|
GLenum glformat = 0;
|
||||||
GLenum gltype = 0;
|
GLenum gltype = 0;
|
||||||
|
|
||||||
/* No premultiplied formats accepted by GL
|
/* FIXME: check YUV support */
|
||||||
* (FIXME: latest hardware?) */
|
|
||||||
|
|
||||||
if (format & COGL_PREMULT_BIT)
|
|
||||||
format = (format & COGL_UNPREMULT_MASK);
|
|
||||||
|
|
||||||
/* Everything else accepted
|
|
||||||
* (FIXME: check YUV support) */
|
|
||||||
required_format = format;
|
required_format = format;
|
||||||
|
|
||||||
/* Find GL equivalents */
|
/* Find GL equivalents */
|
||||||
switch (format)
|
switch (format & COGL_UNPREMULT_MASK)
|
||||||
{
|
{
|
||||||
case COGL_PIXEL_FORMAT_A_8:
|
case COGL_PIXEL_FORMAT_A_8:
|
||||||
glintformat = GL_ALPHA;
|
glintformat = GL_ALPHA;
|
||||||
@ -1195,9 +1189,15 @@ _cogl_texture_bitmap_prepare (CoglTexture *tex,
|
|||||||
CoglPixelFormat new_data_format;
|
CoglPixelFormat new_data_format;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
/* Was there any internal conversion requested? */
|
/* Was there any internal conversion requested?
|
||||||
|
* By default Cogl will use a premultiplied internal format. Later we will
|
||||||
|
* add control over this. */
|
||||||
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
||||||
internal_format = tex->bitmap.format;
|
{
|
||||||
|
if ((tex->bitmap.format & COGL_A_BIT) &&
|
||||||
|
tex->bitmap.format != COGL_PIXEL_FORMAT_A_8)
|
||||||
|
internal_format = tex->bitmap.format | COGL_PREMULT_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find closest format accepted by GL */
|
/* Find closest format accepted by GL */
|
||||||
new_data_format = _cogl_pixel_format_to_gl (internal_format,
|
new_data_format = _cogl_pixel_format_to_gl (internal_format,
|
||||||
|
@ -1184,18 +1184,12 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format,
|
|||||||
GLenum glformat = 0;
|
GLenum glformat = 0;
|
||||||
GLenum gltype = 0;
|
GLenum gltype = 0;
|
||||||
|
|
||||||
/* No premultiplied formats accepted by GL
|
/* FIXME: check YUV support */
|
||||||
* (FIXME: latest hardware?) */
|
|
||||||
|
|
||||||
if (format & COGL_PREMULT_BIT)
|
|
||||||
format = (format & COGL_UNPREMULT_MASK);
|
|
||||||
|
|
||||||
/* Everything else accepted
|
|
||||||
* (FIXME: check YUV support) */
|
|
||||||
required_format = format;
|
required_format = format;
|
||||||
|
|
||||||
/* Find GL equivalents */
|
/* Find GL equivalents */
|
||||||
switch (format)
|
switch (format & COGL_UNPREMULT_MASK)
|
||||||
{
|
{
|
||||||
case COGL_PIXEL_FORMAT_A_8:
|
case COGL_PIXEL_FORMAT_A_8:
|
||||||
glintformat = GL_ALPHA;
|
glintformat = GL_ALPHA;
|
||||||
@ -1226,6 +1220,7 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format,
|
|||||||
glformat = GL_RGBA;
|
glformat = GL_RGBA;
|
||||||
gltype = GL_UNSIGNED_BYTE;
|
gltype = GL_UNSIGNED_BYTE;
|
||||||
required_format = COGL_PIXEL_FORMAT_RGBA_8888;
|
required_format = COGL_PIXEL_FORMAT_RGBA_8888;
|
||||||
|
required_format |= (format & COGL_PREMULT_BIT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* The following three types of channel ordering
|
/* The following three types of channel ordering
|
||||||
@ -1270,9 +1265,15 @@ _cogl_texture_bitmap_prepare (CoglTexture *tex,
|
|||||||
CoglPixelFormat new_data_format;
|
CoglPixelFormat new_data_format;
|
||||||
gboolean success;
|
gboolean success;
|
||||||
|
|
||||||
/* Was there any internal conversion requested? */
|
/* Was there any internal conversion requested?
|
||||||
|
* By default Cogl will use a premultiplied internal format. Later we will
|
||||||
|
* add control over this. */
|
||||||
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
if (internal_format == COGL_PIXEL_FORMAT_ANY)
|
||||||
internal_format = tex->bitmap.format;
|
{
|
||||||
|
if ((tex->bitmap.format & COGL_A_BIT) &&
|
||||||
|
tex->bitmap.format != COGL_PIXEL_FORMAT_A_8)
|
||||||
|
internal_format = tex->bitmap.format | COGL_PREMULT_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find closest format accepted by GL */
|
/* Find closest format accepted by GL */
|
||||||
new_data_format = _cogl_pixel_format_to_gl (internal_format,
|
new_data_format = _cogl_pixel_format_to_gl (internal_format,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user