From 2ba00f2bf01acfb824070631478259b7729f3606 Mon Sep 17 00:00:00 2001 From: Michael Miller Date: Tue, 24 Jan 2017 15:26:48 -0800 Subject: [PATCH] Dib and Shader support (#158) --- examples/NeoPixelDibTest/NeoPixelDibTest.ino | 152 +++++++++++++++++++ src/NeoPixelBus.h | 2 +- src/internal/NeoDib.h | 108 +++++++++++++ 3 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 examples/NeoPixelDibTest/NeoPixelDibTest.ino create mode 100644 src/internal/NeoDib.h diff --git a/examples/NeoPixelDibTest/NeoPixelDibTest.ino b/examples/NeoPixelDibTest/NeoPixelDibTest.ino new file mode 100644 index 0000000..83fbfdc --- /dev/null +++ b/examples/NeoPixelDibTest/NeoPixelDibTest.ino @@ -0,0 +1,152 @@ +// NeoPixelDibTest +// This example will provide a shader class to the NeoPixelDib that will dim and brighten +// the pixels that are in the Dib (Device Independant Bitmap) +// + +#include + +const uint16_t PixelCount = 64; // set this to the size of your strip +const uint8_t PixelPin = 2; // make sure to set this to the correct pin, ignored for Esp8266 + +// three element GRB pixels, change to your needs +NeoPixelBus strip(PixelCount, PixelPin); + +// the DIB object, using RgbColor and initialized with the same number of pixels as our strip +NeoDib image(PixelCount); + +const RgbColor BrightRed(255, 0, 0); +const RgbColor BrightGreen(0, 255, 0); +const RgbColor BrightBlue(0, 0, 255); + +const RgbColor BrightYellow(255, 255, 0); +const RgbColor BrightCyan(0, 255, 255); +const RgbColor BrightPurple(255, 0, 255); + +const RgbColor DarkRed(32, 0, 0); +const RgbColor DarkGreen(0, 32, 0); +const RgbColor DarkBlue(0, 0, 32); + +const RgbColor DarkYellow(32, 32, 0); +const RgbColor DarkCyan(0, 32, 32); +const RgbColor DarkPurple(32, 0, 32); + +const RgbColor White(255); +const RgbColor Black(0); + +// define a custom shader object that provides brightness support +class BrightnessShader +{ +public: + BrightnessShader(): + _brightness(255) // default to full bright + {} + + // required for a shader object, it will be called for + // every pixel + RgbColor Apply(uint16_t index, RgbColor original) + { + // we don't care what the index is so we ignore it + // + // to apply our brightness shader, modify the original color and return the color we want + // blend from black (_brightness == 0.0) to the original color (_brightness == 1.0) + + return RgbColor::LinearBlend(Black, original, (float)_brightness / 255.0f); + } + + // provide an accessor to set brightness + void setBrightness(uint8_t brightness) + { + _brightness = brightness; + } + + // provide an accessor to get brightness + uint8_t getBrightness() + { + return _brightness; + } + +private: + uint8_t _brightness; +}; + +// create an instance of our shader object +BrightnessShader shader; + +// some dimming tracking variables and settings +int8_t delta; + +void setup() +{ + Serial.begin(115200); + while (!Serial); // wait for serial attach + + Serial.println(); + Serial.println("Initializing..."); + Serial.flush(); + + // this resets all the neopixels to an off state + strip.Begin(); + strip.Show(); + + // dibs do not default to any color, + // so clear it to black if you aren't going to draw + // into every pixel + image.ClearTo(Black); + + // draw a pattern into the image + uint8_t index = 0; + image.SetPixelColor(index++, DarkRed); + image.SetPixelColor(index++, DarkYellow); + image.SetPixelColor(index++, DarkGreen); + image.SetPixelColor(index++, DarkCyan); + image.SetPixelColor(index++, DarkBlue); + image.SetPixelColor(index++, DarkPurple); + + image.SetPixelColor(index++, Black); + image.SetPixelColor(index++, Black); + + image.SetPixelColor(index++, BrightRed); + image.SetPixelColor(index++, BrightYellow); + image.SetPixelColor(index++, BrightGreen); + image.SetPixelColor(index++, BrightCyan); + image.SetPixelColor(index++, BrightBlue); + image.SetPixelColor(index++, BrightPurple); + + Serial.println(); + Serial.println("Running..."); + + delta = -1; // start by dimming downward +} + +void loop() +{ + // we increment by delta every 30ms + delay(30); + + // update the brightness in shader + // + uint8_t brightness = shader.getBrightness(); + // check if we flip directions + if (brightness == 0) + { + delta = 1; // increment + } + else if (brightness == 255) + { + delta = -1; // decrement + } + // modify and apply + brightness += delta; + shader.setBrightness(brightness); + + Serial.println(brightness); + + // render the image using the shader + // need to provide the type of color feature for the strip and + // the type of our custom shader + image.Render(strip, shader); + + // and just show the strip + strip.Show(); +} + diff --git a/src/NeoPixelBus.h b/src/NeoPixelBus.h index fb2566d..c886b73 100644 --- a/src/NeoPixelBus.h +++ b/src/NeoPixelBus.h @@ -49,7 +49,7 @@ License along with NeoPixel. If not, see #include "internal/NeoBuffer.h" #include "internal/NeoSpriteSheet.h" #include "internal/NeoBitmapFile.h" - +#include "internal/NeoDib.h" #include "internal/NeoEase.h" #include "internal/NeoGamma.h" diff --git a/src/internal/NeoDib.h b/src/internal/NeoDib.h new file mode 100644 index 0000000..ddbd140 --- /dev/null +++ b/src/internal/NeoDib.h @@ -0,0 +1,108 @@ +/*------------------------------------------------------------------------- +NeoPixel library + +Written by Michael C. Miller. + +I invest time and resources providing this open source code, +please support me by dontating (see https://github.com/Makuna/NeoPixelBus) + +------------------------------------------------------------------------- +This file is part of the Makuna/NeoPixelBus library. + +NeoPixelBus is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as +published by the Free Software Foundation, either version 3 of +the License, or (at your option) any later version. + +NeoPixelBus is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with NeoPixel. If not, see +. +-------------------------------------------------------------------------*/ +#pragma once + +template class NeoDib +{ +public: + NeoDib(uint16_t countPixels) : + _countPixels(countPixels) + { + _pixels = (T_COLOR_OBJECT*)malloc(PixelsSize()); + } + + ~NeoDib() + { + free((uint8_t*)_pixels); + } + + T_COLOR_OBJECT* Pixels() const + { + return _pixels; + }; + + uint16_t PixelCount() const + { + return _countPixels; + }; + + size_t PixelsSize() const + { + return _countPixels * PixelSize(); + }; + + size_t PixelSize() const + { + return sizeof(T_COLOR_OBJECT); + }; + + void SetPixelColor( + uint16_t indexPixel, + T_COLOR_OBJECT color) + { + if (indexPixel < PixelCount()) + { + _pixels[indexPixel] = color; + } + }; + + T_COLOR_OBJECT GetPixelColor( + uint16_t indexPixel) const + { + if (indexPixel >= PixelCount()) + { + return 0; + } + return _pixels[indexPixel]; + }; + + void ClearTo(T_COLOR_OBJECT color) + { + for (uint16_t pixel = 0; pixel < PixelCount(); pixel++) + { + _pixels[pixel] = color; + } + }; + + template void Render(NeoBufferContext destBuffer, T_SHADER shader) + { + uint16_t countPixels = destBuffer.PixelCount(); + if (countPixels > _countPixels) + { + countPixels = _countPixels; + } + + for (uint16_t indexPixel = 0; indexPixel < countPixels; indexPixel++) + { + T_COLOR_OBJECT color = shader.Apply(indexPixel, _pixels[indexPixel]); + T_COLOR_FEATURE::applyPixelColor(destBuffer.Pixels, indexPixel, color); + } + } + +private: + const uint16_t _countPixels; // Number of RGB LEDs in strip + T_COLOR_OBJECT* _pixels; +}; \ No newline at end of file