Skip to content

Commit

Permalink
Blending refactored
Browse files Browse the repository at this point in the history
LedEffects
- remove blend parameters

LedFixture.projectAndMap:
- bugfix: clear mappingTable

LedLeds
- bugfix: clear mappingTable
- sPC: remove blendAmount
- sPC: remove pixelsToBlend = true
- fTB, fS, fR: remove blendAmount and noBlend

LedModEffects.loop:
- if multiple led effects: reset pixelsToBlend and set after each led frame
  • Loading branch information
ewoudwijma committed Jul 27, 2024
1 parent dc5ce3b commit f52544d
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 73 deletions.
88 changes: 43 additions & 45 deletions src/App/LedEffects.h
Original file line number Diff line number Diff line change
Expand Up @@ -896,7 +896,7 @@ class DJLight: public Effect {
const char * tags() {return "♫💡";}

void setup(Leds &leds) {
leds.fill_solid(CRGB::Black, true); //no blend
leds.fill_solid(CRGB::Black);
}

void loop(Leds &leds) {
Expand Down Expand Up @@ -1461,7 +1461,7 @@ class GameOfLife: public Effect {
int nx = x + pattern[i][0];
int ny = y + pattern[i][1];
setBitValue(futureCells, leds.XYZUnprojected({nx, ny, z}), true);
leds.setPixelColor({nx, ny, z}, colorByAge ? CRGB::Green : color, 0);
leds.setPixelColor({nx, ny, z}, colorByAge ? CRGB::Green : color); //ewowi check blend
}
return;
}
Expand Down Expand Up @@ -1514,7 +1514,7 @@ class GameOfLife: public Effect {
if (leds.projectionDimension == _3D && !leds.isMapped(leds.XYZUnprojected({x,y,z}))) continue;
if (random8(100) < lifeChance) {
setBitValue(cells, leds.XYZUnprojected({x,y,z}), true);
leds.setPixelColor({x,y,z}, bgColor, 0); // Color set in redraw loop
leds.setPixelColor({x,y,z}, bgColor); // Color set in redraw loop
}
}
memcpy(futureCells, cells, dataSize);
Expand All @@ -1528,7 +1528,7 @@ class GameOfLife: public Effect {
return;
}

byte blur = leds.fixture->globalBlend;
byte blur = leds.fixture->globalBlend; //ewowi: should be managed in sPC
int fadedBackground = 0;
if (blur > 220 && !colorByAge) { // Keep faded background if blur > 220
fadedBackground = bgColor.r + bgColor.g + bgColor.b + 20 + (blur-220);
Expand All @@ -1548,12 +1548,12 @@ class GameOfLife: public Effect {
CRGB cellColor = leds.getPixelColor(cLoc);
bool recolor = (paletteChanged || (alive && *generation == 1 && cellColor == bgColor && !random(16))); // Palette change or Initial Color
// Redraw alive if palette changed, spawn initial colors randomly, age alive cells while paused
if (alive && recolor) leds.setPixelColor(cLoc, colorByAge ? CRGB::Green : ColorFromPalette(leds.palette, random8()), 0);
else if (alive && colorByAge && !*generation) leds.setPixelColor(cLoc, CRGB::Red, 248); // Age alive cells while paused
if (alive && recolor) leds.setPixelColor(cLoc, colorByAge ? CRGB::Green : ColorFromPalette(leds.palette, random8())); //ewowi: check blend
else if (alive && colorByAge && !*generation) leds.setPixelColor(cLoc, CRGB::Red); // Age alive cells while paused ewowi: check blend (was 248)
// Redraw dead if palette changed, blur paused game, fade on newgame
if (!alive && (paletteChanged || disablePause)) leds.setPixelColor(cLoc, bgColor, 0); // Remove blended dead cells
else if (!alive && blurDead) leds.setPixelColor(cLoc, bgColor, blur); // Blend dead cells while paused
else if (!alive && *generation == 1) leds.setPixelColor(cLoc, bgColor, 248); // Fade dead on new game
if (!alive && (paletteChanged || disablePause)) leds.setPixelColor(cLoc, bgColor); // Remove blended dead cells ewowi: check blend
else if (!alive && blurDead) leds.setPixelColor(cLoc, bgColor); // Blend dead cells while paused ewowi: check blend (was blur)
else if (!alive && *generation == 1) leds.setPixelColor(cLoc, bgColor); // Fade dead on new game ewowi: check blend (was 248)
}
}

Expand Down Expand Up @@ -1624,27 +1624,27 @@ class GameOfLife: public Effect {
if (cellValue && !surviveNumbers[neighbors]) {
// Loneliness or Overpopulation
setBitValue(futureCells, cIndex, false);
leds.setPixelColor(cPos, bgColor, blur);
leds.setPixelColor(cPos, bgColor); //ewowi: check blend (was blur)
}
else if (!cellValue && birthNumbers[neighbors]){
// Reproduction
setBitValue(futureCells, cIndex, true);
CRGB randomParentColor = color; // Last seen color, overwrite if colors are found
if (colorCount) randomParentColor = nColors[random8(colorCount)];
if (random8(100) < mutation) randomParentColor = ColorFromPalette(leds.palette, random8());
leds.setPixelColor(cPos, colorByAge ? CRGB::Green : randomParentColor, 0);
leds.setPixelColor(cPos, colorByAge ? CRGB::Green : randomParentColor); //ewowi: check blend

}
else {
// Blending, fade dead cells further causing blurring effect to moving cells
if (!cellValue) {
if (fadedBackground) {
CRGB val = leds.getPixelColor(cPos);
if (fadedBackground < val.r + val.g + val.b) leds.setPixelColor(cPos, bgColor, blur);
if (fadedBackground < val.r + val.g + val.b) leds.setPixelColor(cPos, bgColor); //ewowi: check blend (was blur)
}
else leds.setPixelColor(cPos, bgColor, blur);
else leds.setPixelColor(cPos, bgColor); //ewowi: check blend (was blur)
}
if (cellValue && colorByAge) leds.setPixelColor(cPos, CRGB::Red, 248);
if (cellValue && colorByAge) leds.setPixelColor(cPos, CRGB::Red); //ewowi: check blend (was 248)
}
}

Expand Down Expand Up @@ -1879,12 +1879,12 @@ class RubiksCube: public Effect {
int distZ = min(z, sizeZ - z);
int dist = min(distX, min(distY, distZ));

if (dist == distZ && z < halfZ) leds.setPixelColor(led, COLOR_MAP[front[normalizedY][normalizedX]], blendVal);
else if (dist == distX && x < halfX) leds.setPixelColor(led, COLOR_MAP[left[normalizedY][SIZE - 1 - normalizedZ]], blendVal);
else if (dist == distY && y < halfY) leds.setPixelColor(led, COLOR_MAP[top[SIZE - 1 - normalizedZ][normalizedX]], blendVal);
else if (dist == distZ && z >= halfZ) leds.setPixelColor(led, COLOR_MAP[back[normalizedY][SIZE - 1 - normalizedX]], blendVal);
else if (dist == distX && x >= halfX) leds.setPixelColor(led, COLOR_MAP[right[normalizedY][normalizedZ]], blendVal);
else if (dist == distY && y >= halfY) leds.setPixelColor(led, COLOR_MAP[bottom[normalizedZ][normalizedX]], blendVal);
if (dist == distZ && z < halfZ) leds.setPixelColor(led, COLOR_MAP[front[normalizedY][normalizedX]]); //ewowi: check no blend (was blendVal)
else if (dist == distX && x < halfX) leds.setPixelColor(led, COLOR_MAP[left[normalizedY][SIZE - 1 - normalizedZ]]); //ewowi: check blend (was blendVal
else if (dist == distY && y < halfY) leds.setPixelColor(led, COLOR_MAP[top[SIZE - 1 - normalizedZ][normalizedX]]); //ewowi: check blend (was blendVal
else if (dist == distZ && z >= halfZ) leds.setPixelColor(led, COLOR_MAP[back[normalizedY][SIZE - 1 - normalizedX]]); //ewowi: check blend (was blendVal
else if (dist == distX && x >= halfX) leds.setPixelColor(led, COLOR_MAP[right[normalizedY][normalizedZ]]); //ewowi: check blend (was blendVal
else if (dist == distY && y >= halfY) leds.setPixelColor(led, COLOR_MAP[bottom[normalizedZ][normalizedX]]); //ewowi: check blend (was blendVal
}
}
};
Expand Down Expand Up @@ -2031,11 +2031,11 @@ class ParticleTest: public Effect {

if (newPos == prevPos) return; // Skip if no change in position

leds.setPixelColor(prevPos, CRGB::Black, 0); // Clear previous position
leds.setPixelColor(prevPos, CRGB::Black); // Clear previous position ewowi: check blend

if (leds.isMapped(leds.XYZUnprojected(newPos)) && !newPos.isOutofBounds(leds.size) && leds.getPixelColor(newPos) == CRGB::Black) {
if (debugPrint) ppf(" New Pos was mapped and particle placed\n");
leds.setPixelColor(newPos, color, 0); // Set new position
leds.setPixelColor(newPos, color); // Set new position ewowi: check blend
return;
}

Expand Down Expand Up @@ -2097,7 +2097,7 @@ class ParticleTest: public Effect {
if (debugPrint) ppf(" New Pos: %f, %f, %f Velo: %f, %f, %f\n", x, y, z, vx, vy, vz);
}

leds.setPixelColor(toCoord3DRounded(), color, 0); // Set new position
leds.setPixelColor(toCoord3DRounded(), color); // Set new position ewowi: check blend
}
};

Expand Down Expand Up @@ -2126,14 +2126,14 @@ class ParticleTest: public Effect {
if (*setup) {
ppf("Setting Up Particles\n");
*setup = false;
leds.fill_solid(CRGB::Black, true);
leds.fill_solid(CRGB::Black);

if (barriers) {
// create a 2 pixel thick barrier around middle y value with gaps
for (int x = 0; x < leds.size.x; x++) for (int z = 0; z < leds.size.z; z++) {
if (!random8(5)) continue;
leds.setPixelColor({x, leds.size.y/2, z}, CRGB::White, 0);
leds.setPixelColor({x, leds.size.y/2 - 1, z}, CRGB::White, 0);
leds.setPixelColor({x, leds.size.y/2, z}, CRGB::White); //ewowi: check blend
leds.setPixelColor({x, leds.size.y/2 - 1, z}, CRGB::White);//ewowi: check blend
}
}

Expand All @@ -2156,7 +2156,7 @@ class ParticleTest: public Effect {

particles[index].color = ColorFromPalette(leds.palette, random8());
Coord3D initPos = particles[index].toCoord3DRounded();
leds.setPixelColor(initPos, particles[index].color, 0);
leds.setPixelColor(initPos, particles[index].color); //ewowi: check blend
}
ppf("Particles Set Up\n");
*step = sys->now;
Expand Down Expand Up @@ -2544,7 +2544,7 @@ class FunkyPlank: public Effect {
const char * tags() {return "♫💡💫";}

void setup(Leds &leds) {
leds.fill_solid(CRGB::Black, true); //no blend
leds.fill_solid(CRGB::Black);
}

void loop(Leds &leds) {
Expand Down Expand Up @@ -2705,10 +2705,10 @@ class Byte2TestEffect: public Effect {
unsigned long *step = leds.effectData.readWrite<unsigned long>();

if (*setup) {
// leds.fill_solid(CRGB::Black, 0);
// leds.fill_solid(CRGB::Black); //ewowi: this should work now...
for (int x = 0; x < leds.size.x; x++) {
for (int y = 0; y < leds.size.y; y++) {
leds.setPixelColor(leds.XY(x, y), CRGB::Black, 0);
leds.setPixelColor(leds.XY(x, y), CRGB::Black); //ewowi check blend
}
}
*setup = false;
Expand All @@ -2720,9 +2720,10 @@ class Byte2TestEffect: public Effect {
for (int y = leds.size.y - 1; y > 0; y--) {
for (int x = 0; x < leds.size.x; x++) {
// Blend test
CRGB color = blend(leds.getPixelColor(leds.XY(x, y - 1)), leds.getPixelColor(leds.XY(x, y)), leds.fixture->globalBlend);
leds.setPixelColor(leds.XY(x, y), color, 0);
// leds.setPixelColor(leds.XY(x, y), leds.getPixelColor(leds.XY(x, y - 1)));
// ewowi: haha didn't realize globalBlend was hardcoded here!
// CRGB color = blend(leds.getPixelColor(leds.XY(x, y - 1)), leds.getPixelColor(leds.XY(x, y)), leds.fixture->globalBlend);
// leds.setPixelColor(leds.XY(x, y), color, 0);
leds.setPixelColor(leds.XY(x, y), leds.getPixelColor(leds.XY(x, y - 1)));
}
}

Expand All @@ -2731,10 +2732,10 @@ class Byte2TestEffect: public Effect {
byte g = random8();
byte b = random8();
for (int x = 0; x < leds.size.x; x++) {
if (drawMethod == 0) leds.setPixelColor(leds.XY(x, 0), ColorFromPalette(leds.palette, r), 0);
else if (drawMethod == 1) leds.setPixelColorPal(leds.XY(x, 0), r, 255, 0);
else if (drawMethod == 2) leds.setPixelColor(leds.XY(x, 0), CRGB(r, g, b), 0);
else if (drawMethod == 3) leds.setPixelColor(leds.XY(x, 0), CRGB(color.x, color.y, color.z), 0);
if (drawMethod == 0) leds.setPixelColor(leds.XY(x, 0), ColorFromPalette(leds.palette, r)); //ewowi check blend
else if (drawMethod == 1) leds.setPixelColorPal(leds.XY(x, 0), r, 255); //ewowi check blend
else if (drawMethod == 2) leds.setPixelColor(leds.XY(x, 0), CRGB(r, g, b)); //ewowi check blend
else if (drawMethod == 3) leds.setPixelColor(leds.XY(x, 0), CRGB(color.x, color.y, color.z)); //ewowi check blend
}

if (debugPrint) {
Expand All @@ -2755,10 +2756,7 @@ class Byte2TestEffect: public Effect {
ppf("Average Error: %3f %3f %3f\n", (float)diffR / leds.size.y, (float)diffG / leds.size.y, (float)diffB / leds.size.y);
}



*step = sys->now;

*step = sys->now;
}

void controls(Leds &leds, JsonObject parentVar) {
Expand Down Expand Up @@ -2799,10 +2797,10 @@ class Byte2TestEffect2: public Effect {
unsigned long *step = leds.effectData.readWrite<unsigned long>();

if (*setup) {
// leds.fill_solid(CRGB::Black, 0);
// leds.fill_solid(CRGB::Black); //ewowi: this should work now...
for (int x = 0; x < leds.size.x; x++) {
for (int y = 0; y < leds.size.y; y++) {
leds.setPixelColor(leds.XY(x, y), CRGB::Black, 0);
leds.setPixelColor(leds.XY(x, y), CRGB::Black); //ewowi check blend
}
}
*setup = false;
Expand Down Expand Up @@ -2872,8 +2870,8 @@ class Byte2TestEffect2: public Effect {
int half = leds.size.x/2;
for (int x = 0; x < half; x++) {
for (int y = 0; y < leds.size.y; y++) {
leds.setPixelColor(leds.XY(x, y), color, 0);
leds.setPixelColor(leds.XY(x+half, y), rColor, 0);
leds.setPixelColor(leds.XY(x, y), color); //ewowi check blend
leds.setPixelColor(leds.XY(x+half, y), rColor); //ewowi check blend
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/App/LedFixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ void Fixture::projectAndMap() {
stackUnsigned8 rowNr = 0;
for (Leds *leds: listOfLeds) {
if (leds->doMap) {
leds->fill_solid(CRGB::Black, true); //no blend
leds->fill_solid(CRGB::Black);

ppf("projectAndMap clear leds[%d] fx:%d pro:%d\n", rowNr, leds->fx, leds->projectionNr);
leds->size = Coord3D{0,0,0};
//vectors really gone now?
for (PhysMap &map:leds->mappingTable) {
leds->mappingTableIndexes.clear();
for (std::vector<uint16_t> mappingTableIndex: leds->mappingTableIndexes) {
mappingTableIndex.clear();
}
leds->mappingTableIndexes.clear();
leds->mappingTable.clear();
// leds->effectData.reset(); //do not reset as want to save settings.
}
Expand Down
26 changes: 11 additions & 15 deletions src/App/LedLeds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ unsigned16 Leds::XYZ(Coord3D pixel) {
}

// maps the virtual led to the physical led(s) and assign a color to it
void Leds::setPixelColor(unsigned16 indexV, CRGB color, unsigned8 blendAmount) {
void Leds::setPixelColor(unsigned16 indexV, CRGB color) {
if (indexV < mappingTable.size()) {
if (mappingTable[indexV].mapType == m_colorPal) mappingTable[indexV].mapType = m_color;
switch (mappingTable[indexV].mapType) {
Expand All @@ -60,14 +60,12 @@ void Leds::setPixelColor(unsigned16 indexV, CRGB color, unsigned8 blendAmount) {
}
case m_onePixel: {
uint16_t indexP = mappingTable[indexV].indexP;
fixture->ledsP[indexP] = fixture->pixelsToBlend[indexP]?blend(color, fixture->ledsP[indexP], blendAmount==UINT8_MAX?fixture->globalBlend:blendAmount):color;
fixture->pixelsToBlend[indexP] = true; //overlapping effects will blend
fixture->ledsP[indexP] = fixture->pixelsToBlend[indexP]?blend(color, fixture->ledsP[indexP], fixture->globalBlend):color;
break; }
case m_morePixels:
if (mappingTable[indexV].indexes < mappingTableIndexes.size())
for (forUnsigned16 indexP: mappingTableIndexes[mappingTable[indexV].indexes]) {
fixture->ledsP[indexP] = fixture->pixelsToBlend[indexP]?blend(color, fixture->ledsP[indexP], blendAmount==UINT8_MAX?fixture->globalBlend:blendAmount): color;
fixture->pixelsToBlend[indexP] = true; //overlapping effects will blend
fixture->ledsP[indexP] = fixture->pixelsToBlend[indexP]?blend(color, fixture->ledsP[indexP], fixture->globalBlend): color;
}
// else
// ppf("dev setPixelColor2 i:%d m:%d s:%d\n", indexV, mappingTable[indexV].indexes, mappingTableIndexes.size());
Expand All @@ -76,14 +74,13 @@ void Leds::setPixelColor(unsigned16 indexV, CRGB color, unsigned8 blendAmount) {
}
else if (indexV < NUM_LEDS_Max) { //no projection
uint16_t indexP = (projectionNr == p_Random)?random(fixture->nrOfLeds):indexV;
fixture->ledsP[indexP] = fixture->pixelsToBlend[indexP]?blend(color, fixture->ledsP[indexP], blendAmount==UINT8_MAX?fixture->globalBlend:blendAmount): color;
fixture->pixelsToBlend[indexP] = true; //overlapping effects will blend
fixture->ledsP[indexP] = fixture->pixelsToBlend[indexP]?blend(color, fixture->ledsP[indexP], fixture->globalBlend): color;
}
else if (indexV != UINT16_MAX) //assuming UINT16_MAX is set explicitly (e.g. in XYZ)
ppf(" dev sPC V:%d >= %d", indexV, NUM_LEDS_Max);
}

void Leds::setPixelColorPal(unsigned16 indexV, uint8_t palIndex, uint8_t palBri, unsigned8 blendAmount) {
void Leds::setPixelColorPal(unsigned16 indexV, uint8_t palIndex, uint8_t palBri) {
if (indexV < mappingTable.size()) {
if (mappingTable[indexV].mapType == m_color) mappingTable[indexV].mapType = m_colorPal;
switch (mappingTable[indexV].mapType) {
Expand All @@ -92,14 +89,13 @@ void Leds::setPixelColorPal(unsigned16 indexV, uint8_t palIndex, uint8_t palBri,
mappingTable[indexV].palBri = palBri >> 2; // 8 bits to 6 bits
break;
default:
setPixelColor(indexV, ColorFromPalette(palette, palIndex, palBri), blendAmount);
setPixelColor(indexV, ColorFromPalette(palette, palIndex, palBri));
break;
}
}
else if (indexV < NUM_LEDS_Max) {//no projection
uint16_t indexP = (projectionNr == p_Random)?random(fixture->nrOfLeds):indexV;
fixture->ledsP[indexP] = fixture->pixelsToBlend[indexP]?blend(ColorFromPalette(palette, palIndex, palBri), fixture->ledsP[indexP], blendAmount==UINT8_MAX?fixture->globalBlend:blendAmount): ColorFromPalette(palette, palIndex, palBri);
fixture->pixelsToBlend[indexP] = true; //overlapping effects will blend
fixture->ledsP[indexP] = fixture->pixelsToBlend[indexP]?blend(ColorFromPalette(palette, palIndex, palBri), fixture->ledsP[indexP], fixture->globalBlend): ColorFromPalette(palette, palIndex, palBri);
}
else if (indexV != UINT16_MAX) //assuming UINT16_MAX is set explicitly (e.g. in XYZ)
ppf(" dev sPC V:%d >= %d", indexV, NUM_LEDS_Max);
Expand Down Expand Up @@ -137,17 +133,17 @@ void Leds::fadeToBlackBy(unsigned8 fadeBy) {
for (uint16_t index = 0; index < mappingTable.size(); index++) {
CRGB color = getPixelColor(index);
color.nscale8(255-fadeBy);
setPixelColor(index, color, fixture->globalBlend);
setPixelColor(index, color);
}
}
}

void Leds::fill_solid(const struct CRGB& color, bool noBlend) {
void Leds::fill_solid(const struct CRGB& color) {
if (projectionNr == p_None || projectionNr == p_Random || (fixture->listOfLeds.size() == 1)) {
fastled_fill_solid(fixture->ledsP, fixture->nrOfLeds, color);
} else {
for (uint16_t index = 0; index < mappingTable.size(); index++)
setPixelColor(index, color, noBlend?0:fixture->globalBlend); //noBlend: no blending of old color
setPixelColor(index, color);
}
}

Expand All @@ -161,7 +157,7 @@ void Leds::fill_rainbow(unsigned8 initialhue, unsigned8 deltahue) {
hsv.sat = 240;

for (uint16_t index = 0; index < mappingTable.size(); index++) {
setPixelColor(index, hsv, fixture->globalBlend); //noBlend: no blending of old color
setPixelColor(index, hsv);
hsv.hue += deltahue;
}
}
Expand Down
Loading

0 comments on commit f52544d

Please sign in to comment.