Rework color_from_palette()

- respect paletteBlend
- bugfix in ColorFromPaletteWLED()
This commit is contained in:
Blaž Kristan 2025-01-27 21:26:35 +01:00
parent 7b13771cfe
commit 9bfd34e6b2
3 changed files with 13 additions and 6 deletions

View File

@ -684,7 +684,7 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w,
case 60: bits = pgm_read_byte_near(&console_font_5x12[(chr * h) + i]); break; // 5x12 font
default: return;
}
uint32_t c = ColorFromPaletteWLED(grad, (i+1)*255/h, 255, NOBLEND);
uint32_t c = ColorFromPalette(grad, (i+1)*255/h, 255, LINEARBLEND_NOWRAP);
// pre-scale color for all pixels
c = color_fade(c, _segBri);
_colorScaled = true;

View File

@ -1314,12 +1314,12 @@ uint32_t Segment::color_wheel(uint8_t pos) const {
* Gets a single color from the currently selected palette.
* @param i Palette Index (if mapping is true, the full palette will be _virtualSegmentLength long, if false, 255). Will wrap around automatically.
* @param mapping if true, LED position in segment is considered for color
* @param wrap FastLED palettes will usually wrap back to the start smoothly. Set false to get a hard edge
* @param moving FastLED palettes will usually wrap back to the start smoothly. Set to true if effect has moving palette and you want wrap.
* @param mcol If the default palette 0 is selected, return the standard color 0, 1 or 2 instead. If >2, Party palette is used instead
* @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling)
* @returns Single color from palette
*/
uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) const {
uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool moving, uint8_t mcol, uint8_t pbri) const {
uint32_t color = getCurrentColor(mcol < NUM_COLORS ? mcol : 0);
// default palette or no RGB support on segment
if ((palette == 0 && mcol < NUM_COLORS) || !_isRGB) {
@ -1329,9 +1329,15 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_
const int vL = vLength();
unsigned paletteIndex = i;
if (mapping && vL > 1) paletteIndex = (i*255)/(vL -1);
// paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined)
if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
CRGBW palcol = ColorFromPaletteWLED(_currentPalette, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
// paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined/no interpolation of palette entries)
// ColorFromPalette interpolations are: NOBLEND, LINEARBLEND, LINEARBLEND_NOWRAP
TBlendType blend = NOBLEND;
switch (strip.paletteBlend) { // NOTE: paletteBlend should be global
case 0: blend = moving ? LINEARBLEND : LINEARBLEND_NOWRAP; break;
case 1: blend = LINEARBLEND; break;
case 2: blend = LINEARBLEND_NOWRAP; break;
}
CRGBW palcol = ColorFromPalette(_currentPalette, paletteIndex, pbri, blend);
palcol.w = W(color);
return palcol.color32;

View File

@ -108,6 +108,7 @@ uint32_t ColorFromPaletteWLED(const CRGBPalette16& pal, unsigned index, uint8_t
blue1 = (blue1 * f1 + (unsigned)entry->b * f2) >> 8;
}
if (brightness < 255) { // note: zero checking could be done to return black but that is hardly ever used so it is omitted
// actually color_fade(c1, brightness)
uint32_t scale = brightness + 1; // adjust for rounding (bitshift)
red1 = (red1 * scale) >> 8; // note: using color_fade() is 30% slower
green1 = (green1 * scale) >> 8;