Skip to content

Instantly share code, notes, and snippets.

@kkristof
Created November 16, 2012 14:23
Show Gist options
  • Save kkristof/4087709 to your computer and use it in GitHub Desktop.
Save kkristof/4087709 to your computer and use it in GitHub Desktop.
static void
_cairo_gl_set_operator (cairo_gl_context_t *ctx,
cairo_operator_t op,
cairo_bool_t component_alpha)
{
struct {
GLenum src;
GLenum dst;
} blend_factors[] = {
{ GL_ZERO, GL_ZERO }, /* Clear */
{ GL_ONE, GL_ZERO }, /* Source */
{ GL_ONE, GL_ONE_MINUS_SRC_ALPHA }, /* Over */
{ GL_DST_ALPHA, GL_ZERO }, /* In */
{ GL_ONE_MINUS_DST_ALPHA, GL_ZERO }, /* Out */
{ GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Atop */
{ GL_ZERO, GL_ONE }, /* Dest */
{ GL_ONE_MINUS_DST_ALPHA, GL_ONE }, /* DestOver */
{ GL_ZERO, GL_SRC_ALPHA }, /* DestIn */
{ GL_ZERO, GL_ONE_MINUS_SRC_ALPHA }, /* DestOut */
{ GL_ONE_MINUS_DST_ALPHA, GL_SRC_ALPHA }, /* DestAtop */
{ GL_ONE_MINUS_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA }, /* Xor */
{ GL_ONE, GL_ONE }, /* Add */
};
GLenum src_factor, dst_factor;
assert (op < ARRAY_LENGTH (blend_factors));
/* different dst and component_alpha changes cause flushes elsewhere */
if (ctx->current_operator != op)
_cairo_gl_composite_flush (ctx);
ctx->current_operator = op;
src_factor = blend_factors[op].src;
dst_factor = blend_factors[op].dst;
/* Even when the user requests CAIRO_CONTENT_COLOR, we use GL_RGBA
* due to texture filtering of GL_CLAMP_TO_BORDER. So fix those
* bits in that case.
*/
if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) {
if (src_factor == GL_ONE_MINUS_DST_ALPHA)
src_factor = GL_ZERO;
if (src_factor == GL_DST_ALPHA)
src_factor = GL_ONE;
}
if (component_alpha) {
if (dst_factor == GL_ONE_MINUS_SRC_ALPHA)
dst_factor = GL_ONE_MINUS_SRC_COLOR;
if (dst_factor == GL_SRC_ALPHA)
dst_factor = GL_SRC_COLOR;
}
if (ctx->current_target->base.content == CAIRO_CONTENT_ALPHA) {
glBlendFuncSeparate (GL_ZERO, GL_ZERO, src_factor, dst_factor);
} else if (ctx->current_target->base.content == CAIRO_CONTENT_COLOR) {
glBlendFuncSeparate (src_factor, dst_factor, GL_ONE, GL_ONE);
} else {
glBlendFunc (src_factor, dst_factor);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment