Implement alpha channel in graphics library

Alpha channel can be used to draw transparent objects.
replace/2b99394505f7f8ec895d9231befe1f1869691120
Niccolò Izzo 2020-12-19 15:00:33 +01:00
rodzic d56fafe1a2
commit 8d55a3e702
3 zmienionych plików z 35 dodań i 14 usunięć

Wyświetl plik

@ -77,6 +77,7 @@ typedef struct color_t
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t alpha;
} color_t;
typedef enum

Wyświetl plik

@ -162,12 +162,28 @@ inline void gfx_setPixel(point_t pos, color_t color)
return; // off the screen
#ifdef PIX_FMT_RGB565
buf[pos.x + pos.y*SCREEN_WIDTH] = _true2highColor(color);
// Blend old pixel value and new one
if (color.alpha < 255) {
uint8_t alpha = color.alpha;
rgb565_t new_pixel = _true2highColor(color);
uint16_t raw_pixel = __builtin_bswap16(
*((uint16_t *)buf + pos.x + pos.y*SCREEN_WIDTH));
rgb565_t old_pixel = *((rgb565_t*) &raw_pixel);
rgb565_t pixel = {((255-alpha)*old_pixel.b+alpha*new_pixel.b)/255,
((255-alpha)*old_pixel.g+alpha*new_pixel.g)/255,
((255-alpha)*old_pixel.r+alpha*new_pixel.r)/255};
buf[pos.x + pos.y*SCREEN_WIDTH] = pixel;
} else {
buf[pos.x + pos.y*SCREEN_WIDTH] = _true2highColor(color);
}
#elif defined PIX_FMT_BW
uint16_t cell = (pos.x + pos.y*SCREEN_WIDTH) / 8;
uint16_t elem = (pos.x + pos.y*SCREEN_WIDTH) % 8;
buf[cell] &= ~(1 << elem);
buf[cell] |= (_color2bw(color) << elem);
// Ignore more than half transparent pixels
if (color.alpha >= 128) {
uint16_t cell = (pos.x + pos.y*SCREEN_WIDTH) / 8;
uint16_t elem = (pos.x + pos.y*SCREEN_WIDTH) % 8;
buf[cell] &= ~(1 << elem);
buf[cell] |= (_color2bw(color) << elem);
}
#endif
}
@ -349,16 +365,16 @@ void gfx_print(point_t start, const char *text, fontSize_t size, textAlign_t ali
*
*/
void gfx_drawBattery(point_t start, uint16_t width, uint16_t height, float percentage) {
color_t white = {255, 255, 255};
color_t black = {0, 0, 0 };
color_t white = {255, 255, 255, 255};
color_t black = {0, 0, 0 , 255};
// Cap percentage to 1
percentage = (percentage > 1.0f) ? 1.0f : percentage;
#ifdef PIX_FMT_RGB565
color_t green = {0, 255, 0 };
color_t yellow = {250, 180, 19 };
color_t red = {255, 0, 0 };
color_t green = {0, 255, 0 , 255};
color_t yellow = {250, 180, 19 , 255};
color_t red = {255, 0, 0 , 255};
// Select color according to percentage
color_t bat_color = yellow;

Wyświetl plik

@ -105,9 +105,9 @@ typedef struct layout_t
fontSize_t bottom_font;
} layout_t;
const color_t color_white = {255, 255, 255};
const color_t color_grey = {60, 60, 60};
const color_t yellow_fab413 = {250, 180, 19};
const color_t color_white = {255, 255, 255, 255};
const color_t color_grey = {60, 60, 60, 255};
const color_t yellow_fab413 = {250, 180, 19, 255};
layout_t layout;
bool layout_ready = false;
@ -286,6 +286,11 @@ bool _ui_drawMainVFO(state_t* last_state)
{
gfx_clearScreen();
_ui_drawBackground();
point_t splash_origin = {0, SCREEN_HEIGHT / 2 - 6};
color_t yellow = yellow_fab413;
yellow.alpha = 0.1f * 255;
gfx_print(splash_origin, "O P N\nR T X", FONT_SIZE_12PT, TEXT_ALIGN_CENTER,
yellow);
_ui_drawTopBar(last_state);
_ui_drawMiddleVFO(last_state);
_ui_drawBottomBar();
@ -361,7 +366,6 @@ bool _ui_drawLowBatteryScreen()
gfx_drawBattery(bat_pos, bat_width, bat_height, 0.1f);
point_t text_pos_1 = {0, SCREEN_HEIGHT * 2 / 3};
point_t text_pos_2 = {0, SCREEN_HEIGHT * 2 / 3 + 16};
const color_t color_white = {255, 255, 255};
gfx_print(text_pos_1,
"For emergency use",