Added subpixel-rendering as well as blurring methods to Window.

This commit is contained in:
Fabian Schlenz 2019-09-25 06:27:43 +02:00
parent fa5f1c8816
commit aa11f5ed8a
2 changed files with 136 additions and 3 deletions

View File

@ -19,6 +19,7 @@ public:
void clear(); void clear();
void clear(CRGB* color); void clear(CRGB* color);
void setPixel(uint8_t x, uint8_t y, CRGB* color); void setPixel(uint8_t x, uint8_t y, CRGB* color);
void setSubPixel(accum88 x, accum88 y, CRGB* color);
void setPixelByIndex(uint16_t index, CRGB* color); void setPixelByIndex(uint16_t index, CRGB* color);
void raisePixel(uint8_t x, uint8_t y, CRGB* color); void raisePixel(uint8_t x, uint8_t y, CRGB* color);
void line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, CRGB* color); void line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, CRGB* color);
@ -27,7 +28,19 @@ public:
void circle(uint8_t x, uint8_t y, uint8_t r, CRGB* color); void circle(uint8_t x, uint8_t y, uint8_t r, CRGB* color);
uint16_t coordsToGlobalIndex(uint8_t x, uint8_t y); uint16_t coordsToGlobalIndex(uint8_t x, uint8_t y);
uint16_t localToGlobalIndex(uint16_t); uint16_t localToGlobalIndex(uint16_t);
void drawChar(Font* f, uint8_t x, uint8_t y, const char c, CRGB* color, bool mask=false); void drawChar(Font* f, accum88 x, accum88 y, const char c, CRGB* color, bool mask=false);
void drawText(Font* f, uint16_t x, uint16_t y, String s, CRGB* color);
void drawSubText(Font* f, accum88 x, accum88 y, String s, CRGB* color);
void addPixelColor(uint16_t index, CRGB* color); void addPixelColor(uint16_t index, CRGB* color);
void addPixelColor(uint8_t x, uint8_t y, CRGB* color);
CRGB get_pixel(uint8_t x, uint8_t y);
void fadeToBlackBy(fract8 speed); void fadeToBlackBy(fract8 speed);
void shift_down();
void shift_down_and_blur();
void clear_row(uint8_t y);
void blur(fract8 intensity);
void blur_rows(fract8 intensity);
void blur_row(uint8_t y, fract8 intensity);
void blur_columns(fract8 intensity);
void blur_column(uint8_t x, fract8 intensity);
}; };

View File

@ -41,7 +41,19 @@ void Window::clear(CRGB* color) {
for(int x=0; x<this->width; x++) for(int y=0; y<this->height; y++) this->setPixel(x, y, color); for(int x=0; x<this->width; x++) for(int y=0; y<this->height; y++) this->setPixel(x, y, color);
} }
void Window::drawChar(Font* font, uint8_t xPos, uint8_t yPos, const char c, CRGB* color, bool mask) { void Window::drawText(Font* font, uint16_t x, uint16_t y, String text, CRGB* color) {
for (int i=0; i<text.length(); i++) {
drawChar(font, (x+(i*(font->width + 1))<<8), (y<<8), text[i], color);
}
}
void Window::drawSubText(Font* font, accum88 x, accum88 y, String text, CRGB* color) {
for (int i=0; i<text.length(); i++) {
drawChar(font, x+(i*((font->width + 1)<<8)), y, text[i], color);
}
}
void Window::drawChar(Font* font, accum88 xPos, accum88 yPos, const char c, CRGB* color, bool mask) {
if (!font->isCharAllowed(c)) return; if (!font->isCharAllowed(c)) return;
uint16_t position = font->getCharPosition(c); uint16_t position = font->getCharPosition(c);
uint8_t* data = new uint8_t[font->width]; uint8_t* data = new uint8_t[font->width];
@ -50,16 +62,87 @@ void Window::drawChar(Font* font, uint8_t xPos, uint8_t yPos, const char c, CRGB
for(uint8_t y=0; y<font->height; y++) for(uint8_t x=0; x<font->width; x++) { for(uint8_t y=0; y<font->height; y++) for(uint8_t x=0; x<font->width; x++) {
bool on = (data[x]>>(font->height - 1 - y) & 1) * 255; bool on = (data[x]>>(font->height - 1 - y) & 1) * 255;
if (mask) on = !on; if (mask) on = !on;
if (on) this->setPixel(x + xPos, y + yPos, color); if (on) this->setSubPixel(xPos + (x<<8), yPos + (y<<8), color);
} }
free(data); free(data);
} }
void Window::clear_row(uint8_t y) {
CRGB black(0x000000);
for (uint8_t x=0; x<this->width; x++) this->setPixel(x, y, &black);
}
void Window::shift_down() {
for (uint8_t y=this->height-1; y>=1; y--) {
for (uint8_t x=0; x<this->width; x++) {
leds[coordsToGlobalIndex(x, y)] = leds[coordsToGlobalIndex(x, y-1)];
}
}
clear_row(0);
}
void Window::shift_down_and_blur() {
shift_down();
for (uint8_t y=1; y<this->height; y++) {
blur_row(y, 128);
}
}
void Window::blur(fract8 intensity) {
blur_rows(intensity);
blur_columns(intensity);
}
void Window::blur_rows(fract8 intensity) {
for (uint8_t y=0; y<this->height; y++) {
blur_row(y, intensity);
}
}
void Window::blur_columns(fract8 intensity) {
for (uint8_t x=0; x<this->width; x++) {
blur_column(x, intensity);
}
}
void Window::blur_row(uint8_t y, fract8 intensity) {
uint16_t idx1 = coordsToGlobalIndex(0, y);
uint16_t idx2 = coordsToGlobalIndex(this->width - 1, y);
blur1d(&(leds[idx1 < idx2 ? idx1 : idx2]), this->width, intensity);
}
void Window::blur_column(uint8_t x, fract8 intensity) {
// Reimplementation from FastLEDs blurColumns
uint8_t keep = 255 - intensity;
uint8_t seep = intensity >> 1;
CRGB carryover = CRGB::Black;
for (uint8_t y=0; y<this->height; y++) {
CRGB cur = leds[coordsToGlobalIndex(x, y)];
CRGB part = cur;
part.nscale8(seep);
cur.nscale8(keep);
cur += carryover;
if (y>0) leds[coordsToGlobalIndex(x, y-1)] += part;
leds[coordsToGlobalIndex(x, y)] = cur;
carryover = part;
}
}
void Window::addPixelColor(uint16_t index, CRGB* color) { void Window::addPixelColor(uint16_t index, CRGB* color) {
leds[localToGlobalIndex(index)] += *color; leds[localToGlobalIndex(index)] += *color;
} }
void Window::addPixelColor(uint8_t x, uint8_t y, CRGB* color) {
leds[coordsToGlobalIndex(x, y)] += *color;
}
CRGB Window::get_pixel(uint8_t x, uint8_t y) {
return leds[coordsToGlobalIndex(x, y)];
}
void Window::fadeToBlackBy(fract8 speed) { void Window::fadeToBlackBy(fract8 speed) {
for (uint8_t x=0; x<this->width; x++) for(uint8_t y=0; y<this->height; y++) { for (uint8_t x=0; x<this->width; x++) for(uint8_t y=0; y<this->height; y++) {
leds[coordsToGlobalIndex(x, y)].nscale8(255 - speed); leds[coordsToGlobalIndex(x, y)].nscale8(255 - speed);
@ -135,3 +218,40 @@ void Window::lineWithAngle(uint8_t x, uint8_t y, uint8_t angle, uint8_t startdis
line(x1, y1, x2, y2, color); line(x1, y1, x2, y2, color);
} }
void Window::setSubPixel(accum88 x, accum88 y, CRGB* color) {
uint8_t px, py;
// px = Part of next pixel to fill
// x = "Origin pixel"
px = x & 0xFF;
py = y & 0xFF;
x = x >> 8;
y = y >> 8;
CRGB c;
c = CRGB(dim8_video( scale8( scale8( color->r, 255-py), 255-px)),
dim8_video( scale8( scale8( color->g, 255-py), 255-px)),
dim8_video( scale8( scale8( color->b, 255-py), 255-px)));
this->addPixelColor(x, y, &c);
if (px) {
c = CRGB(dim8_video( scale8( scale8( color->r, 255-py), px)),
dim8_video( scale8( scale8( color->g, 255-py), px)),
dim8_video( scale8( scale8( color->b, 255-py), px)));
this->addPixelColor(x+1, y, &c);
}
if (py) {
c = CRGB(dim8_video( scale8( scale8( color->r, py), 255-px)),
dim8_video( scale8( scale8( color->g, py), 255-px)),
dim8_video( scale8( scale8( color->b, py), 255-px)));
this->addPixelColor(x, y+1, &c);
}
if (px || py) {
c = CRGB(dim8_video( scale8( scale8( color->r, py), px)),
dim8_video( scale8( scale8( color->g, py), px)),
dim8_video( scale8( scale8( color->b, py), px)));
this->addPixelColor(x+1, y+1, &c);
}
}