diff --git a/cogl-material.h b/cogl-material.h index 510ce8238..44a837564 100644 --- a/cogl-material.h +++ b/cogl-material.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. * + * 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) * * Since 1.0 @@ -475,6 +480,11 @@ void cogl_material_set_alpha_test_function (CoglHandle material, * * * + * 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 * blending is supported by the underlying driver/hardware. If there * was an error, it returns FALSE. diff --git a/cogl.h.in b/cogl.h.in index a468cf717..64d57fc4f 100644 --- a/cogl.h.in +++ b/cogl.h.in @@ -455,8 +455,13 @@ void cogl_set_source (CoglHandle material); * cogl_set_source_color: * @color: a #CoglColor * - * Sets the source color using normalized values for each component. - * This color will be used for any subsequent drawing operation. + * This is a convenience function for creating a solid fill source material + * 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() * if you already have the color components. diff --git a/common/cogl-material.c b/common/cogl-material.c index 831fa30f1..7e3935bff 100644 --- a/common/cogl-material.c +++ b/common/cogl-material.c @@ -109,7 +109,7 @@ cogl_material_new (void) material->blend_constant[2] = 0; material->blend_constant[3] = 0; #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->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC; diff --git a/common/cogl.c b/common/cogl.c index 336303917..5857db2d3 100644 --- a/common/cogl.c +++ b/common/cogl.c @@ -250,12 +250,17 @@ cogl_get_backface_culling_enabled (void) void cogl_set_source_color (const CoglColor *color) { + CoglColor premultiplied; + _COGL_GET_CONTEXT (ctx, NO_RETVAL); /* In case cogl_set_source_texture was previously used... */ 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); } diff --git a/gl/cogl-texture.c b/gl/cogl-texture.c index 3af78f9a0..2ee50617c 100644 --- a/gl/cogl-texture.c +++ b/gl/cogl-texture.c @@ -1085,18 +1085,20 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format, GLenum glformat = 0; GLenum gltype = 0; - /* No premultiplied formats accepted by GL - * (FIXME: latest hardware?) */ - - if (format & COGL_PREMULT_BIT) - format = (format & COGL_UNPREMULT_MASK); - - /* Everything else accepted - * (FIXME: check YUV support) */ - required_format = format; + /* If PREMULT_BIT isn't specified, that means that we premultiply + * textures with alpha before uploading to GL; once we are in GL land, + * everything is premultiplied. + * + * Everything else accepted (FIXME: check YUV support) + */ + if ((format & COGL_A_BIT) != 0 && + format != COGL_PIXEL_FORMAT_A_8) + required_format = format | COGL_PREMULT_BIT; + else + required_format = format; /* Find GL equivalents */ - switch (format) + switch (format & COGL_UNPREMULT_MASK) { case COGL_PIXEL_FORMAT_A_8: glintformat = GL_ALPHA; diff --git a/gles/cogl-texture.c b/gles/cogl-texture.c index ae3e437b8..f9b6e0b78 100644 --- a/gles/cogl-texture.c +++ b/gles/cogl-texture.c @@ -1184,18 +1184,20 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format, GLenum glformat = 0; GLenum gltype = 0; - /* No premultiplied formats accepted by GL - * (FIXME: latest hardware?) */ - - if (format & COGL_PREMULT_BIT) - format = (format & COGL_UNPREMULT_MASK); - - /* Everything else accepted - * (FIXME: check YUV support) */ - required_format = format; + /* If PREMULT_BIT isn't specified, that means that we premultiply + * textures with alpha before uploading to GL; once we are in GL land, + * everything is premultiplied. + * + * Everything else accepted (FIXME: check YUV support) + */ + if ((format & COGL_A_BIT) != 0 && + format != COGL_PIXEL_FORMAT_A_8) + required_format = format | COGL_PREMULT_BIT; + else + required_format = format; /* Find GL equivalents */ - switch (format) + switch (format & COGL_UNPREMULT_MASK) { case COGL_PIXEL_FORMAT_A_8: glintformat = GL_ALPHA; @@ -1226,6 +1228,7 @@ _cogl_pixel_format_to_gl (CoglPixelFormat format, glformat = GL_RGBA; gltype = GL_UNSIGNED_BYTE; required_format = COGL_PIXEL_FORMAT_RGBA_8888; + required_format |= (format & COGL_PREMULT_BIT); break; /* The following three types of channel ordering