From 7ba611f81f904e13c07ec7713ddf5296b8460348 Mon Sep 17 00:00:00 2001 From: mrfaptastic <12006953+mrfaptastic@users.noreply.github.com> Date: Thu, 23 Dec 2021 01:03:24 +0000 Subject: Implement FastLED pixel buffer example An extreme memory hog, but not too different to what is used with the Aurora demo's. https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/discussions/225 --- .../FastLED_Pixel_Buffer.cpp | 116 +++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 examples/ChainedPanelsScreenBuffer/FastLED_Pixel_Buffer.cpp (limited to 'examples/ChainedPanelsScreenBuffer/FastLED_Pixel_Buffer.cpp') diff --git a/examples/ChainedPanelsScreenBuffer/FastLED_Pixel_Buffer.cpp b/examples/ChainedPanelsScreenBuffer/FastLED_Pixel_Buffer.cpp new file mode 100644 index 0000000..79e19c9 --- /dev/null +++ b/examples/ChainedPanelsScreenBuffer/FastLED_Pixel_Buffer.cpp @@ -0,0 +1,116 @@ +/** + * Experimental layer class to do play with pixel in an off-screen buffer before painting to the DMA + * + * Requires FastLED + * + * Faptastic 2020-2021 + **/ + +#include "FastLED_Pixel_Buffer.h" + +/** + * The one for 256+ matrices + * otherwise this: + * for (uint8_t i = 0; i < MATRIX_WIDTH; i++) {} + * turns into an infinite loop + */ +inline uint16_t VirtualMatrixPanel_FastLED_Pixel_Buffer::XY16( uint16_t x, uint16_t y) { + + if (x >= virtualResX) return 0; + if (y >= virtualResY) return 0; + + return (y * virtualResX) + x + 1; // everything offset by one to compute out of bounds stuff - never displayed by ShowFrame() +} + +// For adafruit +void VirtualMatrixPanel_FastLED_Pixel_Buffer::drawPixel(int16_t x, int16_t y, uint16_t color) { + + //Serial.println("calling our drawpixel!"); + + // 565 color conversion + uint8_t r = ((((color >> 11) & 0x1F) * 527) + 23) >> 6; + uint8_t g = ((((color >> 5) & 0x3F) * 259) + 33) >> 6; + uint8_t b = (((color & 0x1F) * 527) + 23) >> 6; + + this->drawPixel(x, y, CRGB(r,g,b)); +} + +void VirtualMatrixPanel_FastLED_Pixel_Buffer::drawPixel(int16_t x, int16_t y, int r, int g, int b) { + this->drawPixel(x, y, CRGB(r,g,b)); +} + +// We actually just draw to ourselves... to our buffer +void VirtualMatrixPanel_FastLED_Pixel_Buffer::drawPixel(int16_t x, int16_t y, CRGB color) +{ + //Serial.printf("updated x y : %d %d", x, y); + buffer[XY16(x,y)] = color; +} + +CRGB VirtualMatrixPanel_FastLED_Pixel_Buffer::getPixel(int16_t x, int16_t y) +{ + return buffer[XY16(x,y)]; +} + +/** + * Dim all the pixels on the layer. + */ +void VirtualMatrixPanel_FastLED_Pixel_Buffer::dimAll(byte value) { + + //Serial.println("performing dimall"); + // nscale8 max value is 255, or it'll flip back to 0 + // (documentation is wrong when it says x/256), it's actually x/255 + /* + for (int y = 0; y < LAYER_HEIGHT; y++) { + for (int x = 0; x < LAYER_WIDTH; x++) { + pixels->data[y][x].nscale8(value); + }} + */ + dimRect(0,0, virtualResX, virtualResY, value); +} + +/** + * Dim all the pixels in a rectangular option of the layer the layer. + */ +void VirtualMatrixPanel_FastLED_Pixel_Buffer::dimRect(int16_t x, int16_t y, int16_t w, int16_t h, byte value) { + for (int16_t i = x; i < x + w; i++) + { + for (int16_t j = y; j < y + h; j++) + { + buffer[XY16(i,j)].nscale8(value); + } + } +} + +void VirtualMatrixPanel_FastLED_Pixel_Buffer::clear() { + memset(buffer, CRGB(0,0,0), (virtualResX * virtualResY) ); +} + +/** + * Actually Send the CRGB FastLED buffer to the DMA engine / Physical Panels! + * Do this via the underlying 'VirtualMatrixPanel' that does all the pixel-remapping for + * all sorts of chained panels, and panel scan types. + */ +void VirtualMatrixPanel_FastLED_Pixel_Buffer::show() { + + //Serial.println("Doing Show"); + + CRGB _pixel = 0; + for (int16_t y = 0; y < virtualResY; y++) { + for (int16_t x = 0; x < virtualResX; x++) + { + //VirtualMatrixPanel::getCoords(x, y); // call to base to update coords for chaining approach + _pixel = buffer[XY16(x,y)]; + drawPixelRGB888( x, y, _pixel.r, _pixel.g, _pixel.b); // call VirtualMatrixPanel::drawPixelRGB888(...) + //drawPixelRGB888( x, y, 0, 0, 128); // call VirtualMatrixPanel::drawPixelRGB888(...) + } // end loop to copy fast led to the dma matrix + } + +} // show + +/** + * Cleanup should we delete this buffer class. Unlikely during runtime. + */ +VirtualMatrixPanel_FastLED_Pixel_Buffer::~VirtualMatrixPanel_FastLED_Pixel_Buffer(void) +{ + delete(buffer); +} \ No newline at end of file -- cgit v1.3.1