Last active
February 28, 2017 11:10
-
-
Save frkd-dev/bde1d87eaaf15c43d95f30f43ea0c12e to your computer and use it in GitHub Desktop.
DirectFB blitting and alpha blending documentation by generic code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://www.mail-archive.com/[email protected]/msg05080.html | |
//.------------------------------------------. | |
//| DirectFB - Hardware accelerated graphics | | |
//| http://www.directfb.org/ | | |
//"------------------------------------------" | |
#include "config.h" | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <directfb.h> | |
#include <core/state.h> | |
#include <gfx/convert.h> | |
#define MODULATE(a,b) do { (a) = (((int)(a) * ((int)(b) + 1)) >> 8); } while (0) | |
static DFBColor | |
blit_pixel( CardState *state, DFBColor src, DFBColor dst ) | |
{ | |
DFBColor x; | |
if (!state->blittingflags) | |
return src; | |
if (state->blittingflags & DSBLIT_DST_COLORKEY) { | |
if (PIXEL_RGB32(dst.r,dst.g,dst.b) != state->dst_colorkey) { | |
return dst; | |
} | |
} | |
if (state->blittingflags & DSBLIT_SRC_COLORKEY) { | |
if (PIXEL_RGB32(src.r,src.g,src.b) == state->src_colorkey) { | |
return dst; | |
} | |
} | |
if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) { | |
if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) | |
MODULATE( src.a, state->color.a ); | |
else | |
src.a = state->color.a; | |
} | |
if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { | |
MODULATE( src.r, src.a ); | |
MODULATE( src.g, src.a ); | |
MODULATE( src.b, src.a ); | |
} | |
if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) { | |
MODULATE( src.r, state->color.a ); | |
MODULATE( src.g, state->color.a ); | |
MODULATE( src.b, state->color.a ); | |
} | |
if (state->blittingflags & DSBLIT_COLORIZE) { | |
MODULATE( src.r, state->color.r ); | |
MODULATE( src.g, state->color.g ); | |
MODULATE( src.b, state->color.b ); | |
} | |
if (state->blittingflags & DSBLIT_DST_PREMULTIPLY) { | |
MODULATE( dst.r, dst.a ); | |
MODULATE( dst.g, dst.a ); | |
MODULATE( dst.b, dst.a ); | |
} | |
if (state->blittingflags & DSBLIT_XOR) { | |
src.a ^= dst.a; | |
src.r ^= dst.r; | |
src.g ^= dst.g; | |
src.b ^= dst.b; | |
} | |
x = src; | |
if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) { | |
switch (state->src_blend) { | |
case DSBF_ZERO: | |
x.a = x.r = x.g = x.b = 0; | |
break; | |
case DSBF_ONE: | |
break; | |
case DSBF_SRCCOLOR: | |
MODULATE( x.a, src.a ); | |
MODULATE( x.r, src.r ); | |
MODULATE( x.g, src.g ); | |
MODULATE( x.b, src.b ); | |
break; | |
case DSBF_INVSRCCOLOR: | |
MODULATE( x.a, src.a ^ 0xff ); | |
MODULATE( x.r, src.r ^ 0xff ); | |
MODULATE( x.g, src.g ^ 0xff ); | |
MODULATE( x.b, src.b ^ 0xff ); | |
break; | |
case DSBF_SRCALPHA: | |
MODULATE( x.a, src.a ); | |
MODULATE( x.r, src.a ); | |
MODULATE( x.g, src.a ); | |
MODULATE( x.b, src.a ); | |
break; | |
case DSBF_INVSRCALPHA: | |
MODULATE( x.a, src.a ^ 0xff ); | |
MODULATE( x.r, src.a ^ 0xff ); | |
MODULATE( x.g, src.a ^ 0xff ); | |
MODULATE( x.b, src.a ^ 0xff ); | |
break; | |
case DSBF_DESTALPHA: | |
MODULATE( x.a, dst.a ); | |
MODULATE( x.r, dst.a ); | |
MODULATE( x.g, dst.a ); | |
MODULATE( x.b, dst.a ); | |
break; | |
case DSBF_INVDESTALPHA: | |
MODULATE( x.a, dst.a ^ 0xff ); | |
MODULATE( x.r, dst.a ^ 0xff ); | |
MODULATE( x.g, dst.a ^ 0xff ); | |
MODULATE( x.b, dst.a ^ 0xff ); | |
break; | |
case DSBF_DESTCOLOR: | |
MODULATE( x.a, dst.a ); | |
MODULATE( x.r, dst.r ); | |
MODULATE( x.g, dst.g ); | |
MODULATE( x.b, dst.b ); | |
break; | |
case DSBF_INVDESTCOLOR: | |
MODULATE( x.a, dst.a ^ 0xff ); | |
MODULATE( x.r, dst.r ^ 0xff ); | |
MODULATE( x.g, dst.g ^ 0xff ); | |
MODULATE( x.b, dst.b ^ 0xff ); | |
break; | |
case DSBF_SRCALPHASAT: | |
D_UNIMPLEMENTED(); | |
break; | |
default: | |
D_BUG( "unknown blend function %d", state->src_blend ); | |
} | |
switch (state->dst_blend) { | |
case DSBF_ZERO: | |
dst.a = dst.r = dst.g = dst.b = 0; | |
break; | |
case DSBF_ONE: | |
break; | |
case DSBF_SRCCOLOR: | |
MODULATE( dst.a, src.a ); | |
MODULATE( dst.r, src.r ); | |
MODULATE( dst.g, src.g ); | |
MODULATE( dst.b, src.b ); | |
break; | |
case DSBF_INVSRCCOLOR: | |
MODULATE( dst.a, src.a ^ 0xff ); | |
MODULATE( dst.r, src.r ^ 0xff ); | |
MODULATE( dst.g, src.g ^ 0xff ); | |
MODULATE( dst.b, src.b ^ 0xff ); | |
break; | |
case DSBF_SRCALPHA: | |
MODULATE( dst.a, src.a ); | |
MODULATE( dst.r, src.a ); | |
MODULATE( dst.g, src.a ); | |
MODULATE( dst.b, src.a ); | |
break; | |
case DSBF_INVSRCALPHA: | |
MODULATE( dst.a, src.a ^ 0xff ); | |
MODULATE( dst.r, src.a ^ 0xff ); | |
MODULATE( dst.g, src.a ^ 0xff ); | |
MODULATE( dst.b, src.a ^ 0xff ); | |
break; | |
case DSBF_DESTALPHA: | |
MODULATE( dst.r, dst.a ); | |
MODULATE( dst.g, dst.a ); | |
MODULATE( dst.b, dst.a ); | |
MODULATE( dst.a, dst.a ); // | |
break; | |
case DSBF_INVDESTALPHA: | |
MODULATE( dst.r, dst.a ^ 0xff ); | |
MODULATE( dst.g, dst.a ^ 0xff ); | |
MODULATE( dst.b, dst.a ^ 0xff ); | |
MODULATE( dst.a, dst.a ^ 0xff ); // | |
break; | |
case DSBF_DESTCOLOR: | |
MODULATE( dst.r, dst.r ); | |
MODULATE( dst.g, dst.g ); | |
MODULATE( dst.b, dst.b ); | |
MODULATE( dst.a, dst.a ); // | |
break; | |
case DSBF_INVDESTCOLOR: | |
MODULATE( dst.r, dst.r ^ 0xff ); | |
MODULATE( dst.g, dst.g ^ 0xff ); | |
MODULATE( dst.b, dst.b ^ 0xff ); | |
MODULATE( dst.a, dst.a ^ 0xff ); // | |
break; | |
case DSBF_SRCALPHASAT: | |
D_UNIMPLEMENTED(); | |
break; | |
default: | |
D_BUG( "unknown blend function %d", state->dst_blend ); | |
} | |
x.a += dst.a; | |
x.r += dst.r; | |
x.g += dst.g; | |
x.b += dst.b; | |
} | |
if (state->blittingflags & DSBLIT_DEMULTIPLY) { | |
x.r = ((int)x.r << 8) / ((int)x.a + 1); | |
x.g = ((int)x.g << 8) / ((int)x.a + 1); | |
x.b = ((int)x.b << 8) / ((int)x.a + 1); | |
} | |
return x; | |
} | |
int main() | |
{ | |
DFBColor src = { 0xc0, 0x80, 0x20, 0xff }; | |
DFBColor dst = { 0xd0, 0x20, 0x20, 0x00 }; | |
CardState state; | |
DFBColor result; | |
state.blittingflags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_SRC_PREMULTIPLY; | |
state.src_blend = DSBF_ONE; | |
state.dst_blend = DSBF_INVSRCALPHA; | |
result = blit_pixel( &state, src, dst ); | |
printf( "src: %02x %02x %02x %02x\n", src.a, src.r, src.g, src.b ); | |
printf( "dst: %02x %02x %02x %02x\n", dst.a, dst.r, dst.g, dst.b ); | |
printf( "result: %02x %02x %02x %02x\n", result.a, result.r, result.g, result.b ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment