From 65c584aedaaf45924c45beb548db76671abfee48 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Thu, 27 Apr 2023 17:31:55 +0200 Subject: [PATCH] 2D enhancement (internal) - move() wrapping - dual addPixelColorXY() --- wled00/FX.cpp | 13 ++++---- wled00/FX.h | 34 +++++++++---------- wled00/FX_2Dfcn.cpp | 81 +++++++++++++++++++++++++++------------------ wled00/FX_fcn.cpp | 18 ++++++++-- 4 files changed, 87 insertions(+), 59 deletions(-) diff --git a/wled00/FX.cpp b/wled00/FX.cpp index f189fb767..cb454af01 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -1247,10 +1247,10 @@ uint16_t mode_rain() { if (SEGENV.call && SEGENV.step > SPEED_FORMULA_L) { SEGENV.step = 1; if (strip.isMatrix) { - uint32_t ctemp[width]; - for (int i = 0; i> 8; noise3d[i*cols + j] = scale8(noise3d[i*cols + j], SEGMENT.intensity) + scale8(data, 255 - SEGMENT.intensity); SEGMENT.setPixelColorXY(i, j, ColorFromPalette(SEGPALETTE,~noise3d[i*cols + j]*3)); - SEGMENT.color_wheel(1); } } } @@ -7464,7 +7463,7 @@ uint16_t mode_2Dsoap() { CRGB PixelB = CRGB::Black; if ((zF >= 0) && (zF < cols)) PixelB = SEGMENT.getPixelColorXY(zF, y); else PixelB = ColorFromPalette(SEGPALETTE, ~noise3d[(abs(zF)%cols)*cols + y]*3); - ledsbuff[x] = (PixelA.nscale8(ease8InOutApprox(255 - fraction))) + (PixelB.nscale8(ease8InOutApprox(fraction))); // lerp8by8(PixelA, PixelB, fraction ); + ledsbuff[x] = (PixelA.nscale8(ease8InOutApprox(255 - fraction))) + (PixelB.nscale8(ease8InOutApprox(fraction))); } for (size_t x = 0; x < cols; x++) { SEGMENT.setPixelColorXY(x, y, ledsbuff[x]); @@ -7499,7 +7498,7 @@ uint16_t mode_2Dsoap() { return FRAMETIME; } -static const char _data_FX_MODE_2DSOAP[] PROGMEM = "Soap@!,Smoothness;;!;2;"; +static const char _data_FX_MODE_2DSOAP[] PROGMEM = "Soap@!,Smoothness;;!;2;pal=11"; #endif // WLED_DISABLE_2D diff --git a/wled00/FX.h b/wled00/FX.h index b824cfd41..b4ba2f21c 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -254,8 +254,8 @@ #define FX_MODE_2DBLOBS 121 //gap fill #define FX_MODE_2DSCROLLTEXT 122 //gap fill #define FX_MODE_2DDRIFTROSE 123 //gap fill -#define FX_MODE_2DDISTORTIONWAVES 124 -#define FX_MODE_2DSOAP 125 +#define FX_MODE_2DDISTORTIONWAVES 124 //gap fill +#define FX_MODE_2DSOAP 125 //gap fill // WLED-SR effects (SR compatible IDs !!!) #define FX_MODE_PIXELS 128 @@ -563,9 +563,9 @@ typedef struct Segment { void fadeToBlackBy(uint8_t fadeBy); void blendPixelColor(int n, uint32_t color, uint8_t blend); void blendPixelColor(int n, CRGB c, uint8_t blend) { blendPixelColor(n, RGBW32(c.r,c.g,c.b,0), blend); } - void addPixelColor(int n, uint32_t color); - void addPixelColor(int n, byte r, byte g, byte b, byte w = 0) { addPixelColor(n, RGBW32(r,g,b,w)); } // automatically inline - void addPixelColor(int n, CRGB c) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0)); } // automatically inline + void addPixelColor(int n, uint32_t color, bool fast = false); + void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(n, RGBW32(r,g,b,w), fast); } // automatically inline + void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); } // automatically inline void fadePixelColor(uint16_t n, uint8_t fade); uint8_t get_random_wheel_index(uint8_t pos); uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255); @@ -587,16 +587,16 @@ typedef struct Segment { // 2D support functions void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend); void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); } - void addPixelColorXY(int x, int y, uint32_t color); - void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { addPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline - void addPixelColorXY(int x, int y, CRGB c) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } + void addPixelColorXY(int x, int y, uint32_t color, bool fast = false); + void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColorXY(x, y, RGBW32(r,g,b,w), fast); } // automatically inline + void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), fast); } void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade); void box_blur(uint16_t i, bool vertical, fract8 blur_amount); // 1D box blur (with weight) void blurRow(uint16_t row, fract8 blur_amount); void blurCol(uint16_t col, fract8 blur_amount); - void moveX(int8_t delta); - void moveY(int8_t delta); - void move(uint8_t dir, uint8_t delta); + void moveX(int8_t delta, bool wrap = false); + void moveY(int8_t delta, bool wrap = false); + void move(uint8_t dir, uint8_t delta, bool wrap = false); void draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c); void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c); void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c); @@ -620,16 +620,16 @@ typedef struct Segment { uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); } void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); } void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); } - void addPixelColorXY(int x, int y, uint32_t color) { addPixelColor(x, color); } - void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { addPixelColor(x, RGBW32(r,g,b,w)); } - void addPixelColorXY(int x, int y, CRGB c) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0)); } + void addPixelColorXY(int x, int y, uint32_t color, bool fast = false) { addPixelColor(x, color, fast); } + void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(x, RGBW32(r,g,b,w), fast); } + void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), fast); } void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); } void box_blur(uint16_t i, bool vertical, fract8 blur_amount) {} void blurRow(uint16_t row, fract8 blur_amount) {} void blurCol(uint16_t col, fract8 blur_amount) {} - void moveX(int8_t delta) {} - void moveY(int8_t delta) {} - void move(uint8_t dir, uint8_t delta) {} + void moveX(int8_t delta, bool wrap = false) {} + void moveY(int8_t delta, bool wrap = false) {} + void move(uint8_t dir, uint8_t delta, bool wrap = false) {} void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c) {} void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) {} void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) {} diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 30e0fa19b..8b4c70ef0 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -304,8 +304,22 @@ void Segment::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t } // Adds the specified color with the existing pixel color perserving color balance. -void Segment::addPixelColorXY(int x, int y, uint32_t color) { - setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color)); +void Segment::addPixelColorXY(int x, int y, uint32_t color, bool fast) { + uint32_t col = getPixelColorXY(x,y); + uint8_t r = R(col); + uint8_t g = G(col); + uint8_t b = B(col); + uint8_t w = W(col); + if (fast) { + r = qadd8(r, R(color)); + g = qadd8(g, G(color)); + b = qadd8(b, B(color)); + w = qadd8(w, W(color)); + col = RGBW32(r,g,b,w); + } else { + col = color_add(col, color); + } + setPixelColorXY(x, y, col); } void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { @@ -416,54 +430,55 @@ void Segment::blur1d(fract8 blur_amount) { for (uint16_t y = 0; y < rows; y++) blurRow(y, blur_amount); } -void Segment::moveX(int8_t delta) { +void Segment::moveX(int8_t delta, bool wrap) { const uint16_t cols = virtualWidth(); const uint16_t rows = virtualHeight(); - if (!delta) return; - if (delta > 0) { - for (uint8_t y = 0; y < rows; y++) for (uint8_t x = 0; x < cols-1; x++) { - if (x + delta >= cols) break; - setPixelColorXY(x, y, getPixelColorXY((x + delta)%cols, y)); - } - } else { - for (uint8_t y = 0; y < rows; y++) for (int16_t x = cols-1; x >= 0; x--) { - if (x + delta < 0) break; - setPixelColorXY(x, y, getPixelColorXY(x + delta, y)); + if (!delta || abs(delta) >= cols) return; + uint32_t newPxCol[cols]; + for (int y = 0; y < rows; y++) { + if (delta > 0) { + for (int x = 0; x < cols-delta; x++) newPxCol[x] = getPixelColorXY((x + delta), y); + for (int x = cols-delta; x < cols; x++) newPxCol[x] = getPixelColorXY(wrap ? (x + delta) - cols : x, y); + } else { + for (int x = cols-1; x >= -delta; x--) newPxCol[x] = getPixelColorXY((x + delta), y); + for (int x = -delta-1; x >= 0; x--) newPxCol[x] = getPixelColorXY(wrap ? (x + delta) + cols : x, y); } + for (int x = 0; x < cols; x++) setPixelColorXY(x, y, newPxCol[x]); } } -void Segment::moveY(int8_t delta) { +void Segment::moveY(int8_t delta, bool wrap) { const uint16_t cols = virtualWidth(); const uint16_t rows = virtualHeight(); - if (!delta) return; - if (delta > 0) { - for (uint8_t x = 0; x < cols; x++) for (uint8_t y = 0; y < rows-1; y++) { - if (y + delta >= rows) break; - setPixelColorXY(x, y, getPixelColorXY(x, (y + delta))); - } - } else { - for (uint8_t x = 0; x < cols; x++) for (int16_t y = rows-1; y >= 0; y--) { - if (y + delta < 0) break; - setPixelColorXY(x, y, getPixelColorXY(x, y + delta)); + if (!delta || abs(delta) >= rows) return; + uint32_t newPxCol[rows]; + for (int x = 0; x < cols; x++) { + if (delta > 0) { + for (int y = 0; y < rows-delta; y++) newPxCol[y] = getPixelColorXY(x, (y + delta)); + for (int y = rows-delta; y < rows; y++) newPxCol[y] = getPixelColorXY(x, wrap ? (y + delta) - rows : y); + } else { + for (int y = rows-1; y >= -delta; y--) newPxCol[y] = getPixelColorXY(x, (y + delta)); + for (int y = -delta-1; y >= 0; y--) newPxCol[y] = getPixelColorXY(x, wrap ? (y + delta) + rows : y); } + for (int y = 0; y < rows; y++) setPixelColorXY(x, y, newPxCol[y]); } } // move() - move all pixels in desired direction delta number of pixels // @param dir direction: 0=left, 1=left-up, 2=up, 3=right-up, 4=right, 5=right-down, 6=down, 7=left-down // @param delta number of pixels to move -void Segment::move(uint8_t dir, uint8_t delta) { +// @param wrap around +void Segment::move(uint8_t dir, uint8_t delta, bool wrap) { if (delta==0) return; switch (dir) { - case 0: moveX( delta); break; - case 1: moveX( delta); moveY( delta); break; - case 2: moveY( delta); break; - case 3: moveX(-delta); moveY( delta); break; - case 4: moveX(-delta); break; - case 5: moveX(-delta); moveY(-delta); break; - case 6: moveY(-delta); break; - case 7: moveX( delta); moveY(-delta); break; + case 0: moveX( delta, wrap); break; + case 1: moveX( delta, wrap); moveY( delta, wrap); break; + case 2: moveY( delta, wrap); break; + case 3: moveX(-delta, wrap); moveY( delta, wrap); break; + case 4: moveX(-delta, wrap); break; + case 5: moveX(-delta, wrap); moveY(-delta, wrap); break; + case 6: moveY(-delta, wrap); break; + case 7: moveX( delta, wrap); moveY(-delta, wrap); break; } } diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index ee907125f..666a24ac3 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -821,8 +821,22 @@ void Segment::blendPixelColor(int n, uint32_t color, uint8_t blend) { } // Adds the specified color with the existing pixel color perserving color balance. -void Segment::addPixelColor(int n, uint32_t color) { - setPixelColor(n, color_add(getPixelColor(n), color)); +void Segment::addPixelColor(int n, uint32_t color, bool fast) { + uint32_t col = getPixelColor(n); + uint8_t r = R(col); + uint8_t g = G(col); + uint8_t b = B(col); + uint8_t w = W(col); + if (fast) { + r = qadd8(r, R(color)); + g = qadd8(g, G(color)); + b = qadd8(b, B(color)); + w = qadd8(w, W(color)); + col = RGBW32(r,g,b,w); + } else { + col = color_add(col, color); + } + setPixelColor(n, col); } void Segment::fadePixelColor(uint16_t n, uint8_t fade) {