Remove layer

This commit is contained in:
mrfaptastic 2020-12-07 21:50:48 +00:00
parent 5108c945cd
commit 7683b1d8f3
2 changed files with 0 additions and 442 deletions

338
Layer.cpp
View file

@ -1,338 +0,0 @@
/**
* Experimental layer class to do play with pixel in an off-screen buffer before painting to the DMA
*
* Requires FastLED
*
* Faptastic 2020
**/
#include "Layer.h"
// For adafruit
void Layer::drawPixel(int16_t x, int16_t y, uint16_t color) {
// 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;
drawPixel(x, y, CRGB(r,g,b));
}
void Layer::drawPixel(int16_t x, int16_t y, int r, int g, int b) {
drawPixel(x, y, CRGB(r,g,b));
}
void Layer::drawPixel(int16_t x, int16_t y, CRGB color) {
if( x >= LAYER_WIDTH || x < 0) return; // 0;
if( y >= LAYER_HEIGHT || y < 0) return; // 0;
pixels->data[y][x] = color;
//pixel[XY(x,y)] = color;
}
void Layer::dim(byte value) {
// 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);
}}
// for (int i = 0; i < NUM_PIXELS; i++) pixel[i].nscale8(value);
}
void Layer::clear() {
memset(pixels, BLACK_BACKGROUND_PIXEL_COLOUR, sizeof(layerPixels) );
}
void Layer::display() {
CRGB _pixel = 0 ;
for (int y = 0; y < LAYER_HEIGHT; y++) {
for (int x = 0; x < LAYER_WIDTH; x++)
{
//_pixel = pixel[XY(x, y)];
_pixel = pixels->data[y][x];
matrix->drawPixelRGB888( x, y, _pixel.r, _pixel.g, _pixel.b);
/*
if ( !transparency_enabled ){
matrix->drawPixelRGB888( x, y, _pixel.r, _pixel.g, _pixel.b);
} else {
if (_pixel != transparency_colour) {
matrix->drawPixelRGB888( x, y, _pixel.r, _pixel.g, _pixel.b);
}
}
*/
} // end loop to copy fast led to the dma matrix
}
} // display
void Layer::overridePixelColor(int r, int g, int b) {
CRGB _pixel = 0 ;
for (int y = 0; y < LAYER_HEIGHT; y++) {
for (int x = 0; x < LAYER_WIDTH; x++)
{
//_pixel = pixel[XY(x, y)];
_pixel = pixels->data[y][x];
if (_pixel != transparency_colour) {
matrix->drawPixelRGB888( x, y, _pixel.r, _pixel.g, _pixel.b);
}
} // end loop to copy fast led to the dma matrix
}
}
// default value is in definition
void Layer::drawCentreText(const char *buf, textPosition textPos, const GFXfont *f, CRGB color, int yadjust)
{
int16_t x1, y1;
uint16_t w, h;
setTextWrap(false);
if (f) { // Font struct pointer passed in?
setFont((GFXfont *)f);
} else { // NULL passed. Current font struct defined?
setFont(); // use default
}
// getTextBounds isn't correct for variable width fonts
getTextBounds(buf, 0, 0, &x1, &y1, &w, &h); //calc width of new string
//Serial.printf("The width of the text is %d pixels, the height is %d pixels.\n", w,h);
/*
From: https://learn.adafruit.com/adafruit-gfx-graphics-library/using-fonts
For example, whereas the cursor position when printing with the classic font identified
the top-left corner of the character cell, with new fonts the cursor position indicates the baseline
the bottom-most row of subsequent text. Characters may vary in size and width, and dont
necessarily begin at the exact cursor column (as in below, this character starts one pixel
left of the cursor, but others may be on or to the right of it).
*/
if (!f) {
if (textPos == TOP) {
setCursor((LAYER_WIDTH - w) / 2, 0); // top
} else if (textPos == BOTTOM) {
setCursor((LAYER_WIDTH - w) / 2, LAYER_HEIGHT - h);
} else { // middle
setCursor((LAYER_WIDTH - w) / 2, (LAYER_HEIGHT - h) / 2); // top
}
}
else // custom font
/* As we can't reliable know what is the actual FIRST and last 'lit' pixel, we need to check what was printed to the layer.*/
{
int wstart = 0;
if (w > 42) wstart = (LAYER_WIDTH - w) / 2;
else wstart = (LAYER_WIDTH - w) / 2;
if (textPos == TOP) {
setCursor(wstart, h+yadjust); // top
} else if (textPos == BOTTOM) {
setCursor(wstart+1, (LAYER_HEIGHT-1)+yadjust);
} else { // middle
setCursor( wstart, ((LAYER_HEIGHT/2) + (h/2)) + yadjust);
}
//Serial.printf("Layer: x1: %d, y1: %d, w: %d, h: %d.\n", x1, y1, w, h);
}
// setCursor(0,16);
setTextColor(this->color565(color.r, color.g, color.b)); // Need to confirm from FastLed CRGB to adafruit 565
print(buf);
} // end drawCentreText
// Move the contents of the screen left (-ve) or right (+ve)
void Layer::moveX(int offset)
{
if(offset > 0) { // move right
// Sprintln("Moving right");
for(int x = LAYER_WIDTH - 1; x >= 0; x--){ // 63 to 0
for(int y = 0; y < LAYER_HEIGHT; y++){ // 0 to 31
if (x - offset >= 0)
{
// Serial.printf("setting y %d x %d to y %d x %d\n", y, x, y, x-offset);
pixels->data[y][x] = pixels->data[y][x-offset];
}
else {
pixels->data[y][x] = BLACK_BACKGROUND_PIXEL_COLOUR;
}
}
}
} else { // move left
// Sprintln("Moving Left");
for(int x = 0; x <=LAYER_WIDTH - 1; x++){
for(int y = 0; y < LAYER_HEIGHT; y++){
if ( x > (LAYER_WIDTH-1)+offset )
{
pixels->data[y][x] = BLACK_BACKGROUND_PIXEL_COLOUR;
//Serial.println("eh?");
}
else
{
pixels->data[y][x] = pixels->data[y][x-offset];
// Serial.println("eh?");
}
}
}
}
}
// Find the leftmost and rightmost pixels across all rows. Centre the contents of the layer.
void Layer::autoCenterX()
{
int leftmost_x = 0, rightmost_x = 0, adjusted_leftmost_x = 0;
// Find leftmost
for(int x = 0; x < LAYER_WIDTH; x++) {
for(int y = 0; y < LAYER_HEIGHT; y++) {
if (pixels->data[y][x] != BLACK_BACKGROUND_PIXEL_COLOUR)
{
leftmost_x = x;
//Serial.printf("Left most x pixel is %d\n", leftmost_x);
goto rightmost;
}
}
}
rightmost:
for(int x = LAYER_WIDTH-1; x >= 0; x--) {
for(int y = 0; y < LAYER_HEIGHT; y++) {
if (pixels->data[y][x] != BLACK_BACKGROUND_PIXEL_COLOUR)
{
rightmost_x = x+1;
//Serial.printf("Right most x pixel is %d\n", rightmost_x);
goto centreit;
}
}
}
centreit:
adjusted_leftmost_x = ( LAYER_WIDTH - (rightmost_x - leftmost_x))/2;
//Serial.printf("Adjusted: %d, Moving x coords by %d pixels.\n", adjusted_leftmost_x, adjusted_leftmost_x-leftmost_x);
moveX(adjusted_leftmost_x-leftmost_x);
} // end autoCentreX
void Layer::moveY(int delta)
{
}
Layer::~Layer(void)
{
free(pixels);
}
/* Merge FastLED layers into a super layer and display. Definition */
namespace LayerCompositor
{
/*
* Display the foreground pixels if they're not the background/transparent color.
* If not, then fill with whatever is in the background.
*
* writeToBg = write the result back to the _bgLayer, and not directly to the output device!
* -> no need to do a subsequent bgLayer.display() otherwise.
*/
void Stack(RGB64x32MatrixPanel_I2S_DMA &disp, const Layer &_bgLayer, const Layer &_fgLayer, bool writeBackToBg)
{
for (int y = 0; y < LAYER_HEIGHT; y++) {
for (int x = 0; x < LAYER_WIDTH; x++)
{
//https://www.educative.io/edpresso/how-to-resolve-the-expression-must-have-class-type-error-in-cpp
if (_fgLayer.pixels->data[y][x] == _fgLayer.transparency_colour) // foreground is transparent, show the _bgLayer colors
{
if (writeBackToBg) // write the foreground to the background layer... perhaps so we can do stuff later with the _fgLayer.
_bgLayer.pixels->data[y][x] = _bgLayer.pixels->data[y][x];
else
disp.drawPixelRGB888(x,y, _bgLayer.pixels->data[y][x].r, _bgLayer.pixels->data[y][x].g, _bgLayer.pixels->data[y][x].b );
} // if the foreground is NOT transparent, then print whatever is the bg
else
{
if (writeBackToBg) // write the foreground to the background layer... perhaps so we can do stuff later with the _fgLayer.
_bgLayer.pixels->data[y][x] = _fgLayer.pixels->data[y][x];
else
disp.drawPixelRGB888(x,y, _fgLayer.pixels->data[y][x].r, _fgLayer.pixels->data[y][x].g, _fgLayer.pixels->data[y][x].b );
}
} // end x loop
} // end y loop
} // end stack
/*
* Where the foreground pixels are not the background/transparent color, populate with
* whatever is in the background.
*/
void Siloette(RGB64x32MatrixPanel_I2S_DMA &disp, const Layer &_bgLayer, const Layer &_fgLayer)
{
//const Layer *bg = &_bgLayer;
//const Layer *fg = &_fgLayer;
for (int y = 0; y < LAYER_HEIGHT; y++) {
for (int x = 0; x < LAYER_WIDTH; x++)
{
//https://www.educative.io/edpresso/how-to-resolve-the-expression-must-have-class-type-error-in-cpp
if (_fgLayer.pixels->data[y][x] != _fgLayer.transparency_colour)
{
disp.drawPixelRGB888(x,y, _bgLayer.pixels->data[y][x].r, _bgLayer.pixels->data[y][x].g, _bgLayer.pixels->data[y][x].b );
} // if the foreground is transparent, then print whatever is the bg
else
{
disp.drawPixelRGB888(x,y, 0,0,0);
}
} // end x loop
} // end y loop
} // end stack
void Blend(RGB64x32MatrixPanel_I2S_DMA &disp, const Layer &_bgLayer, const Layer &_fgLayer, uint8_t ratio)
{
CRGB _pixel = 0 ;
for (int y = 0; y < LAYER_HEIGHT; y++)
{
for (int x = 0; x < LAYER_WIDTH; x++)
{
/*
// set the blend ratio for the video cross fade
// (set ratio to 127 for a constant 50% / 50% blend)
uint8_t ratio = beatsin8(5);
*/
_pixel = blend(_bgLayer.pixels->data[y][x], _fgLayer.pixels->data[y][x], ratio);
// https://gist.github.com/StefanPetrick/0c0d54d0f35ea9cca983
disp.drawPixelRGB888(x,y, _pixel.r, _pixel.g, _pixel.b );
} // end x loop
} // end y loop
} // end blend
}

104
Layer.h
View file

@ -1,104 +0,0 @@
/**
* Experimental layer class to do play with pixel in an off-screen buffer before painting to the DMA
*
* Requires FastLED
*
* Faptastic 2020
**/
#ifndef DISPLAY_MATRIX_LAYER
#define DISPLAY_MATRIX_LAYER
#include <GFX.h>
#include <FastLed.h>
#include <ESP32-RGB64x32MatrixPanel-I2S-DMA.h>
#define HALF_WHITE_COLOUR 0x8410
#define BLACK_BACKGROUND_PIXEL_COLOUR CRGB(0,0,0)
#define LAYER_WIDTH 64
#define LAYER_HEIGHT 32
enum textPosition { TOP, MIDDLE, BOTTOM };
/* To help with direct pixel referencing by width and height */
struct layerPixels {
CRGB data[LAYER_HEIGHT][LAYER_WIDTH];
};
class Layer : public GFX // use GFX Root for now
{
public:
// Static allocation of memory for layer
//CRGB pixels[LAYER_WIDTH][LAYER_HEIGHT] = {{0}};
Layer(RGB64x32MatrixPanel_I2S_DMA &disp) : GFX (LAYER_WIDTH, LAYER_HEIGHT) {
matrix = &disp;
}
inline void init()
{
// https://stackoverflow.com/questions/5914422/proper-way-to-initialize-c-structs
pixels = new layerPixels();
//pixels = (layerPixels *) malloc(sizeof(layerPixels));
// pixel = (CRGB *) &pixels[0];
//Serial.printf("Allocated %d bytes of memory for standard CRGB (24bit) layer.\r\n", NUM_PIXELS*sizeof(CRGB));
Serial.printf("Allocated %d bytes of memory for layerPixels.\r\n", sizeof(layerPixels));
} // end Layer
void drawPixel(int16_t x, int16_t y, uint16_t color); // overwrite adafruit implementation
void drawPixel(int16_t x, int16_t y, int r, int g, int b); // Layer implementation
void drawPixel(int16_t x, int16_t y, CRGB color); // Layer implementation
// Font Stuff
//https://forum.arduino.cc/index.php?topic=642749.0
void drawCentreText(const char *buf, textPosition textPos = BOTTOM, const GFXfont *f = NULL, CRGB color = 0x8410, int yadjust = 0); // 128,128,128 RGB @ bottom row by default
void dim(byte value);
void clear();
void display(); // flush to display / LED matrix
// override the color of all pixels that aren't the transparent color
void overridePixelColor(int r, int g, int b);
inline uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}
inline void setTransparency(bool t) { transparency_enabled = t; }
// Effects
void moveX(int delta);
void autoCenterX();
void moveY(int delta);
// For layer composition - accessed publically
CRGB transparency_colour = BLACK_BACKGROUND_PIXEL_COLOUR;
bool transparency_enabled = true;
layerPixels *pixels;
//CRGB *pixel;
// Release Memory
~Layer(void);
private:
RGB64x32MatrixPanel_I2S_DMA *matrix = NULL;
};
/* Merge FastLED layers into a super layer and display. */
namespace LayerCompositor
{
void Stack(RGB64x32MatrixPanel_I2S_DMA &disp, const Layer &_bgLayer, const Layer &_fgLayer, bool writeToBgLayer = false);
void Siloette(RGB64x32MatrixPanel_I2S_DMA &disp, const Layer &_bgLayer, const Layer &_fgLayer);
void Blend(RGB64x32MatrixPanel_I2S_DMA &disp, const Layer &_bgLayer, const Layer &_fgLayer, uint8_t ratio);
}
#endif