From 5ea242d6b17e70f7d05898a89d112fdfa7222185 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 30 Mar 2013 16:57:46 +0100 Subject: Fix alpha blending. --- plugingui/pixelbuffer.cc | 59 ++++++++++++++++++++++++++++-------------------- plugingui/pixelbuffer.h | 4 ++++ 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/plugingui/pixelbuffer.cc b/plugingui/pixelbuffer.cc index c0dc2cc..a593f9e 100644 --- a/plugingui/pixelbuffer.cc +++ b/plugingui/pixelbuffer.cc @@ -42,6 +42,14 @@ void GUI::PixelBuffer::realloc(size_t width, size_t height) this->height = height; } +// http://en.wikipedia.org/wiki/Alpha_compositing +static void getAlpha(unsigned char _a, unsigned char _b, float &a, float &b) +{ + a = _a / 255.0; + b = _b / 255.0; + b *= (1-a); +} + #define PX(k) (x + y * width) * 3 + k void GUI::PixelBuffer::setPixel(size_t x, size_t y, unsigned char red, @@ -49,12 +57,17 @@ void GUI::PixelBuffer::setPixel(size_t x, size_t y, unsigned char blue, unsigned char alpha) { - //printf("%d %d %d\n", red, green, blue); if(x >= width || y >= height) return; - float a = alpha / 255.0; - buf[PX(0)] = (unsigned char)(red * a + buf[PX(0)] * (1-a)); - buf[PX(1)] = (unsigned char)(green * a + buf[PX(1)] * (1-a)); - buf[PX(2)] = (unsigned char)(blue * a + buf[PX(2)] * (1-a)); + + float a,b; + getAlpha(alpha, 255, a, b); + + buf[PX(0)] = (unsigned char)((float)red * a + (float)buf[PX(0)] * b); + buf[PX(0)] /= (a + b); + buf[PX(1)] = (unsigned char)((float)green * a + (float)buf[PX(1)] * b); + buf[PX(1)] /= (a + b); + buf[PX(2)] = (unsigned char)((float)blue * a + (float)buf[PX(2)] * b); + buf[PX(2)] /= (a + b); } static int idx = 0; @@ -82,15 +95,8 @@ void GUI::PixelBufferAlpha::setPixel(size_t x, size_t y, unsigned char blue, unsigned char alpha) { - // printf("%d %d %d %d\n", red, green, blue, alpha); if(x >= width || y >= height) return; - /* - float a = alpha / 255.0; - buf[PX(0)] = (unsigned char)(red * a + buf[PX(0)] * (1-a)); - buf[PX(1)] = (unsigned char)(green * a + buf[PX(1)] * (1-a)); - buf[PX(2)] = (unsigned char)(blue * a + buf[PX(2)] * (1-a)); - buf[PX(3)] = (unsigned char)(alpha * a + buf[PX(3)] * (1-a)); - */ + buf[PX(0)] = red; buf[PX(1)] = green; buf[PX(2)] = blue; @@ -103,22 +109,26 @@ void GUI::PixelBufferAlpha::addPixel(size_t x, size_t y, unsigned char blue, unsigned char alpha) { - // printf("%d %d %d %d\n", red, green, blue, alpha); if(x >= width || y >= height) return; if(alpha == 0) return; - float a = (float)alpha / (float)(alpha + buf[PX(3)]); - buf[PX(0)] = (unsigned char)(red * a + buf[PX(0)] * (1-a)); - buf[PX(1)] = (unsigned char)(green * a + buf[PX(1)] * (1-a)); - buf[PX(2)] = (unsigned char)(blue * a + buf[PX(2)] * (1-a)); + float a,b; + getAlpha(alpha, buf[PX(3)], a, b); - //buf[PX(3)] = (unsigned char)(alpha * a + buf[PX(3)] * (1-a)); - //buf[PX(3)] = alpha>buf[PX(3)]?alpha:buf[PX(3)]; + buf[PX(0)] = (unsigned char)((float)red * a + (float)buf[PX(0)] * b); + buf[PX(0)] /= (a + b); + buf[PX(1)] = (unsigned char)((float)green * a + (float)buf[PX(1)] * b); + buf[PX(1)] /= (a + b); + buf[PX(2)] = (unsigned char)((float)blue * a + (float)buf[PX(2)] * b); + buf[PX(2)] /= (a + b); - float a1 = (float)buf[PX(3)] / 255.0; - float a2 = (float)alpha / 255.0; - buf[PX(3)] = (a1 + ((1 - a1) * a2)) * 255.0; + buf[PX(3)] = (a + b) * 255; +} + +void GUI::PixelBufferAlpha::addPixel(size_t x, size_t y, GUI::Colour c) +{ + addPixel(x, y, c.red * 255, c.green * 255, c.blue * 255, c.alpha * 255); } void GUI::PixelBufferAlpha::pixel(size_t x, size_t y, @@ -127,8 +137,7 @@ void GUI::PixelBufferAlpha::pixel(size_t x, size_t y, unsigned char *blue, unsigned char *alpha) { - //printf("%d %d %d\n", red, green, blue); - if(x > width || y > height) return; + if(x >= width || y >= height) return; *red = buf[PX(0)]; *green = buf[PX(1)]; *blue = buf[PX(2)]; diff --git a/plugingui/pixelbuffer.h b/plugingui/pixelbuffer.h index 21a6ceb..2b73503 100644 --- a/plugingui/pixelbuffer.h +++ b/plugingui/pixelbuffer.h @@ -29,6 +29,8 @@ #include +#include "colour.h" + namespace GUI { class PixelBuffer { @@ -69,6 +71,8 @@ public: unsigned char blue, unsigned char alpha); + void addPixel(size_t x, size_t y, Colour c); + void pixel(size_t x, size_t y, unsigned char *red, unsigned char *green, -- cgit v1.2.3