From 66c2df40c16d2affb9d5024fb9d88afb96f44122 Mon Sep 17 00:00:00 2001 From: Kevin Lange Date: Thu, 13 Sep 2012 23:22:38 -0700 Subject: [PATCH] Fix alpha blending for RGBA destinations. * Also enable PNG loading in `view` * Also enable RGBA PNG loading in general --- userspace/lib/graphics.c | 37 ++++++++++++++++++++++++++----------- userspace/lib/graphics.h | 1 + userspace/view.c | 12 +++++++++++- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/userspace/lib/graphics.c b/userspace/lib/graphics.c index c60a2914..a4736026 100644 --- a/userspace/lib/graphics.c +++ b/userspace/lib/graphics.c @@ -76,11 +76,12 @@ uint32_t alpha_blend(uint32_t bottom, uint32_t top, uint32_t mask) { uint32_t alpha_blend_rgba(uint32_t bottom, uint32_t top) { uint8_t a = _ALP(top); - uint8_t red = (_RED(bottom) * (255 - a) + _RED(top) * a) / 255; - uint8_t gre = (_GRE(bottom) * (255 - a) + _GRE(top) * a) / 255; - uint8_t blu = (_BLU(bottom) * (255 - a) + _BLU(top) * a) / 255; - uint8_t alp = a + _ALP(bottom) > 255 ? 255 : a + _ALP(bottom); - return rgba(red,gre,blu, alp); + uint8_t b = ((int)_ALP(bottom) * (255 - a)) / 255; + uint8_t alp = a + b; + uint8_t red = alp ? (int)(_RED(bottom) * (b) + _RED(top) * a) / (alp): 0; + uint8_t gre = alp ? (int)(_GRE(bottom) * (b) + _GRE(top) * a) / (alp): 0; + uint8_t blu = alp ? (int)(_BLU(bottom) * (b) + _BLU(top) * a) / (alp): 0; + return rgba(red,gre,blu,alp); } void load_sprite(sprite_t * sprite, char * filename) { @@ -182,13 +183,27 @@ int load_sprite_png(sprite_t * sprite, char * file) { sprite->alpha = 0; sprite->blank = 0; - printf(">> Notice, loaded with bit_depth = %d\n", bit_depth); - for (y = 0; y < height; ++y) { - png_byte* row = row_pointers[y]; - for (x = 0; x < width; ++x) { - png_byte * ptr = &(row[x*3]); - sprite->bitmap[(y) * width + x] = rgb(ptr[0], ptr[1], ptr[2]); + if (color_type == 2) { + sprite->alpha = ALPHA_OPAQUE; + for (y = 0; y < height; ++y) { + png_byte* row = row_pointers[y]; + for (x = 0; x < width; ++x) { + png_byte * ptr = &(row[x*3]); + sprite->bitmap[(y) * width + x] = rgb(ptr[0], ptr[1], ptr[2]); + } } + } else if (color_type == 6) { + sprite->alpha = ALPHA_EMBEDDED; + for (y = 0; y < height; ++y) { + png_byte* row = row_pointers[y]; + for (x = 0; x < width; ++x) { + png_byte * ptr = &(row[x*4]); + sprite->bitmap[(y) * width + x] = rgba(ptr[0], ptr[1], ptr[2], ptr[3]); + } + } + + } else { + printf("XXX: UNKNOWN COLOR TYPE: %d!\n", color_type); } for (y = 0; y < height; ++y) { diff --git a/userspace/lib/graphics.h b/userspace/lib/graphics.h index d7734f35..3e4bbaee 100644 --- a/userspace/lib/graphics.h +++ b/userspace/lib/graphics.h @@ -52,6 +52,7 @@ gfx_context_t * init_graphics_fullscreen_double_buffer(); #define ALPHA_INDEXED 3 uint32_t rgb(uint8_t r, uint8_t g, uint8_t b); +uint32_t rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a); uint32_t alpha_blend(uint32_t bottom, uint32_t top, uint32_t mask); uint32_t alpha_blend_rgba(uint32_t bottom, uint32_t top); diff --git a/userspace/view.c b/userspace/view.c index c196909f..c29b9e28 100644 --- a/userspace/view.c +++ b/userspace/view.c @@ -34,7 +34,12 @@ int main (int argc, char ** argv) { int left = 30; int top = 30; - init_sprite(0, argv[1], NULL); + if (strstr(argv[1], ".png")) { + sprites[0] = malloc(sizeof(sprite_t)); + load_sprite_png(sprites[0], argv[1]); + } else { + init_sprite(0, argv[1], NULL); + } int width = sprites[0]->width; int height = sprites[0]->height; @@ -46,6 +51,11 @@ int main (int argc, char ** argv) { ctx = init_graphics_window(wina); draw_fill(ctx, rgb(0,0,0)); + if (sprites[0]->alpha == ALPHA_EMBEDDED) { + draw_fill(ctx, rgba(0,0,0,0)); + window_enable_alpha(wina); + } + draw_sprite(ctx, sprites[0], 0, 0); while (1) {