buffer examples compile

This commit is contained in:
Michael Miller
2024-04-12 22:58:44 -07:00
parent 50bfc2f44e
commit c81721e595
13 changed files with 108 additions and 268 deletions

View File

@@ -14,7 +14,7 @@
#include <SPI.h> #include <SPI.h>
#include <SD.h> #include <SD.h>
const int chipSelect = D8; // make sure to set this to your SD carder reader CS const int chipSelect = 8; // make sure to set this to your SD carder reader CS
//typedef NeoGrbFeature MyPixelColorFeature; //typedef NeoGrbFeature MyPixelColorFeature;
typedef NeoGrbwFeature MyPixelColorFeature; typedef NeoGrbwFeature MyPixelColorFeature;
@@ -30,7 +30,7 @@ NeoPixelAnimator animations(AnimCount); // NeoPixel animation management object
// our NeoBitmapFile will use the same color feature as NeoPixelBus and // our NeoBitmapFile will use the same color feature as NeoPixelBus and
// we want it to use the SD File object // we want it to use the SD File object
NeoBitmapFile<MyPixelColorFeature, File> image; NeoBitmapFile<MyPixelColorFeature::ColorObject, File> image;
uint16_t animState; uint16_t animState;

View File

@@ -28,11 +28,11 @@ NeoPixelBus<MyPixelColorFeature, NeoWs2812xMethod> strip(PixelCount, PixelPin);
NeoPixelAnimator animations(AnimCount); // NeoPixel animation management object NeoPixelAnimator animations(AnimCount); // NeoPixel animation management object
// sprite sheet stored in progmem using the same pixel feature as the NeoPixelBus // sprite sheet stored in progmem using the same pixel feature as the NeoPixelBus
NeoVerticalSpriteSheet<NeoBufferProgmemMethod<MyPixelColorFeature>> spriteSheet( NeoVerticalSpriteSheet<NeoBufferProgmemMethod<MyPixelColorFeature::ColorObject>> spriteSheet(
myImageWidth, // image width and sprite width since its vertical sprite sheet myImageWidth, // image width and sprite width since its vertical sprite sheet
myImageHeight, // image height myImageHeight, // image height
1, // sprite is only one pixel high 1, // sprite is only one pixel high
myImage); myImage);
uint16_t indexSprite; uint16_t indexSprite;
@@ -71,4 +71,3 @@ void loop()
animations.UpdateAnimations(); animations.UpdateAnimations();
strip.Show(); strip.Show();
} }

View File

@@ -1,7 +1,7 @@
// NeoPixelBufferShader // NeoPixelBufferShader
// This example will provide a shader class to the NeoPixelBuffer that will dim and brighten // This example will provide a shader class to the NeoPixelBuffer that will dim and brighten
// the pixels that are in the buffer (a device dependent bitmap) // the pixels that are in the buffer (a device independant bitmap)
// // It is just a demonstration of using a custom shader
#include <NeoPixelBus.h> #include <NeoPixelBus.h>
@@ -14,7 +14,7 @@ NeoPixelBus<NeoGrbFeature, NeoWs2812xMethod> strip(PixelCount, PixelPin);
// the buffer object, // the buffer object,
// defined to use memory with the same feature as the strip // defined to use memory with the same feature as the strip
// initialized with the same number of pixels as our strip // initialized with the same number of pixels as our strip
NeoBuffer<NeoBufferMethod<NeoGrbFeature>> image(8,8,NULL); NeoBuffer<NeoBufferMethod<RgbColor>> image(8, 8, NULL);
const RgbColor BrightRed(255, 0, 0); const RgbColor BrightRed(255, 0, 0);
const RgbColor BrightGreen(0, 255, 0); const RgbColor BrightGreen(0, 255, 0);
@@ -36,53 +36,40 @@ const RgbColor White(255);
const RgbColor Black(0); const RgbColor Black(0);
// define a custom shader object that provides brightness support // define a custom shader object that provides brightness support
// based upon the NeoShaderBase class BrightnessShader
template<typename T_COLOR_FEATURE> class BrightnessShader : public NeoShaderBase
{ {
public: public:
BrightnessShader(): BrightnessShader() :
NeoShaderBase(), _brightness(255) // default to full bright
_brightness(255) // default to full bright {}
{}
// required for a shader object, it will be called for // required for a shader object, it will be called for
// every pixel // every pixel
void Apply(uint16_t index, uint8_t* pDest, const uint8_t* pSrc) RgbColor Apply(const RgbColor& color)
{
// we don't care what the index is so we ignore it
//
// to apply our brightness shader,
// use the source color, modify, and apply to the destination
// for every byte in the pixel,
// scale the source value by the brightness and
// store it in the destination byte
const uint8_t* pSrcEnd = pSrc + T_COLOR_FEATURE::PixelSize;
while (pSrc != pSrcEnd)
{ {
*pDest++ = (*pSrc++ * (uint16_t(_brightness) + 1)) >> 8; // to apply our brightness shader,
// use the source color, modify, and return it
return color.Dim(_brightness);
} }
}
// provide an accessor to set brightness // provide an accessor to set brightness
void setBrightness(uint8_t brightness) void setBrightness(uint8_t brightness)
{ {
_brightness = brightness; _brightness = brightness;
Dirty(); // must call dirty when a property changes }
}
// provide an accessor to get brightness // provide an accessor to get brightness
uint8_t getBrightness() uint8_t getBrightness()
{ {
return _brightness; return _brightness;
} }
private: private:
uint8_t _brightness; uint8_t _brightness;
}; };
// create an instance of our shader object with the same feature as our buffer // create an instance of our shader object
BrightnessShader<NeoGrbFeature> shader; BrightnessShader shader;
// some dimming tracking variables and settings // some dimming tracking variables and settings
int8_t delta; int8_t delta;
@@ -132,36 +119,32 @@ void setup()
void loop() void loop()
{ {
// we increment by delta every 30ms // we increment by delta every 30ms
delay(30); delay(30);
// update the brightness in shader // update the brightness in shader
// //
uint8_t brightness = shader.getBrightness(); uint8_t brightness = shader.getBrightness();
// check if we flip directions // check if we flip directions
if (brightness == 0) if (brightness == 0)
{ {
delta = 1; // increment delta = 1; // increment
} }
else if (brightness == 255) else if (brightness == 255)
{ {
delta = -1; // decrement delta = -1; // decrement
} }
// modify and apply // modify and apply
brightness += delta; brightness += delta;
shader.setBrightness(brightness); shader.setBrightness(brightness);
Serial.println(brightness); Serial.println(brightness);
// render the image using the shader and then call Show() // render the image using the shader and then call Show()
// these two should be called together in order // these two should be called together in order
// //
image.Render<BrightnessShader>(strip, shader);
// need to provide the type of color feature for the strip and strip.Show();
// the type of our custom shader
image.Render<BrightnessShader<NeoGrbFeature>>(strip, shader);
strip.Show();
} }

View File

@@ -1,158 +0,0 @@
// 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 <NeoPixelBus.h>
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<NeoGrbFeature, NeoWs2812xMethod> strip(PixelCount, PixelPin);
// the DIB object, using RgbColor and initialized with the same number of pixels as our strip
NeoDib<RgbColor> 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
// based upon the NeoShaderBase
class BrightnessShader : public NeoShaderBase
{
public:
BrightnessShader():
NeoShaderBase(),
_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;
Dirty(); // must call dirty when a property changes
}
// 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 and then call Show()
// these two should be called together in order
//
// need to provide the type of color feature for the strip and
// the type of our custom shader
image.Render<NeoGrbFeature, BrightnessShader>(strip, shader);
strip.Show();
}

View File

@@ -28,7 +28,7 @@ License along with NeoPixel. If not, see
#include "NeoPixelBus.h" #include "NeoPixelBus.h"
template<typename T_EXPOSED_COLOR_OBJECT, template <typename T_EXPOSED_COLOR_OBJECT,
typename T_FEATURE_COLOR_OBJECT, typename T_FEATURE_COLOR_OBJECT,
typename T_GAMMA> typename T_GAMMA>
class LuminanceShader class LuminanceShader

View File

@@ -70,7 +70,8 @@ enum BmpCompression
// T_COLOR_OBJECT - one of the color objects (RgbColor, RgbwColor) // T_COLOR_OBJECT - one of the color objects (RgbColor, RgbwColor)
// T_FILE_METHOD - any standard File object following Arduino File methods/members // T_FILE_METHOD - any standard File object following Arduino File methods/members
// //
template<typename T_COLOR_OBJECT, typename T_FILE_METHOD> class NeoBitmapFile template <typename T_COLOR_OBJECT, typename T_FILE_METHOD>
class NeoBitmapFile
{ {
public: public:
NeoBitmapFile() : NeoBitmapFile() :
@@ -213,7 +214,7 @@ public:
{ {
if (readPixel(&color)) if (readPixel(&color))
{ {
color = shader.Apply(indexPixel, color); color = shader.Apply(color);
xSrc++; xSrc++;
} }
} }

View File

@@ -29,7 +29,8 @@ License along with NeoPixel. If not, see
// NeoBufferMethod // NeoBufferMethod
// NeoBufferProgmemMethod // NeoBufferProgmemMethod
// //
template<typename T_BUFFER_METHOD> class NeoBuffer template <typename T_BUFFER_METHOD>
class NeoBuffer
{ {
public: public:
NeoBuffer(uint16_t width, NeoBuffer(uint16_t width,
@@ -155,13 +156,14 @@ public:
Blt(destBuffer, xDest, yDest, 0, 0, Width(), Height(), layoutMap); Blt(destBuffer, xDest, yDest, 0, 0, Width(), Height(), layoutMap);
} }
template <typename T_SHADER> void Render(NeoBufferContext<typename T_BUFFER_METHOD::ColorObject> destBuffer, T_SHADER& shader) template <typename T_SHADER>
void Render(NeoBufferContext<typename T_BUFFER_METHOD::ColorObject> destBuffer, T_SHADER& shader)
{ {
uint16_t destPixelCount = destBuffer.PixelCount(); uint16_t countPixels = destBuffer.PixelCount;
if (destPixelCount > _method.PixelCount()) if (countPixels > _method.PixelCount())
{ {
destPixelCount = _method.PixelCount(); countPixels = _method.PixelCount();
} }
for (uint16_t indexPixel = 0; indexPixel < countPixels; indexPixel++) for (uint16_t indexPixel = 0; indexPixel < countPixels; indexPixel++)

View File

@@ -28,17 +28,18 @@ License along with NeoPixel. If not, see
// This is used to allow a template classes that share common buffer concept to // This is used to allow a template classes that share common buffer concept to
// be able to pass that common information to functions // be able to pass that common information to functions
// The template classes just need to expose a conversion operator to this type // The template classes just need to expose a conversion operator to this type
template <typename T_COLOR_OBJECT> struct NeoBufferContext template <typename T_COLOR_OBJECT>
struct NeoBufferContext
{ {
NeoBufferContext(T_COLOR_OBJECT* pixels, NeoBufferContext(T_COLOR_OBJECT* pixels,
size_t pixelsCount) : size_t pixelCount) :
Pixels(pixels), Pixels(pixels),
PixelsCount(pixelsCount) PixelCount(pixelCount)
{ {
} }
typedef T_COLOR_OBJECT ColorObject; typedef T_COLOR_OBJECT ColorObject;
T_COLOR_OBJECT* Pixels; T_COLOR_OBJECT* Pixels;
const size_t PixelsCount; const size_t PixelCount;
; };

View File

@@ -26,7 +26,8 @@ License along with NeoPixel. If not, see
#pragma once #pragma once
template<typename T_COLOR_OBJECT> class NeoBufferMethod template <typename T_COLOR_OBJECT>
class NeoBufferMethod
{ {
public: public:
NeoBufferMethod(uint16_t width, uint16_t height, PGM_VOID_P pixels = nullptr) : NeoBufferMethod(uint16_t width, uint16_t height, PGM_VOID_P pixels = nullptr) :
@@ -37,10 +38,12 @@ public:
if (pixels) if (pixels)
{ {
const uint8_t* pixelsSrc = static_cast<const uint8_t*>(pixels);
// copy from progmem to initialize // copy from progmem to initialize
for (size_t index = 0; index < PixelCount(); index++) for (size_t index = 0; index < PixelCount(); index++)
{ {
_pixels[index] = T_COLOR_OBJECT::PgmRead(pixels + T_COLOR_OBJECT::Size * indexPixel); _pixels[index] = T_COLOR_OBJECT::PgmRead(pixelsSrc + T_COLOR_OBJECT::Size * index);
} }
} }
} }
@@ -53,7 +56,7 @@ public:
operator NeoBufferContext<T_COLOR_OBJECT>() operator NeoBufferContext<T_COLOR_OBJECT>()
{ {
return NeoBufferContext<T_COLOR_OBJECT>(Pixels(), PixelsCount()); return NeoBufferContext<T_COLOR_OBJECT>(Pixels(), PixelCount());
} }
uint8_t* Pixels() const uint8_t* Pixels() const
@@ -96,7 +99,8 @@ public:
void SetPixelColor(int16_t x, int16_t y, T_COLOR_OBJECT color) void SetPixelColor(int16_t x, int16_t y, T_COLOR_OBJECT color)
{ {
if (x < 0 || x >= _width || y < 0 || y >= _height) if (x < 0 || static_cast<uint16_t>(x) >= _width ||
y < 0 || static_cast<uint16_t>(y) >= _height)
{ {
return; return;
} }

View File

@@ -26,7 +26,8 @@ License along with NeoPixel. If not, see
#pragma once #pragma once
template<typename T_COLOR_OBJECT> class NeoBufferProgmemMethod template <typename T_COLOR_OBJECT>
class NeoBufferProgmemMethod
{ {
public: public:
NeoBufferProgmemMethod(uint16_t width, uint16_t height, PGM_VOID_P pixels) : NeoBufferProgmemMethod(uint16_t width, uint16_t height, PGM_VOID_P pixels) :
@@ -38,7 +39,7 @@ public:
operator NeoBufferContext<T_COLOR_OBJECT>() operator NeoBufferContext<T_COLOR_OBJECT>()
{ {
return NeoBufferContext<T_COLOR_OBJECT>(Pixels(), PixelsCount()); return NeoBufferContext<T_COLOR_OBJECT>(Pixels(), PixelCount());
} }
const uint8_t* Pixels() const const uint8_t* Pixels() const
@@ -80,7 +81,9 @@ public:
return 0; return 0;
} }
return T_COLOR_OBJECT::PgmRead(_pixels + T_COLOR_OBJECT::Size * indexPixel); const uint8_t* pixelsSrc = static_cast<const uint8_t*>(_pixels);
return T_COLOR_OBJECT::PgmRead(pixelsSrc + T_COLOR_OBJECT::Size * indexPixel);
}; };

View File

@@ -25,7 +25,7 @@ License along with NeoPixel. If not, see
-------------------------------------------------------------------------*/ -------------------------------------------------------------------------*/
#pragma once #pragma once
template<typename T_EXPOSED_COLOR_OBJECT, typename T_FEATURE_COLOR_OBJECT> template <typename T_EXPOSED_COLOR_OBJECT, typename T_FEATURE_COLOR_OBJECT>
class NeoShaderNop class NeoShaderNop
{ {
public: public:

View File

@@ -42,7 +42,7 @@ public:
{ {
} }
operator NeoBufferContext<typename T_BUFFER_METHOD::ColorFeature>() operator NeoBufferContext<typename T_BUFFER_METHOD::ColorObject>()
{ {
return _method; return _method;
} }
@@ -82,11 +82,11 @@ public:
_method.ClearTo(color); _method.ClearTo(color);
}; };
void Blt(NeoBufferContext<typename T_BUFFER_METHOD::ColorFeature> destBuffer, void Blt(NeoBufferContext<typename T_BUFFER_METHOD::ColorObject> destBuffer,
uint16_t destPixelIndex, uint16_t destPixelIndex,
uint16_t indexSprite) uint16_t indexSprite)
{ {
uint16_t destPixelCount = destBuffer.PixelCount(); uint16_t destPixelCount = destBuffer.PixelCount;
// validate destPixelIndex // validate destPixelIndex
if (destPixelIndex >= destPixelCount) if (destPixelIndex >= destPixelCount)
{ {
@@ -114,7 +114,7 @@ public:
} }
} }
void Blt(NeoBufferContext<typename T_BUFFER_METHOD::ColorFeature> destBuffer, void Blt(NeoBufferContext<typename T_BUFFER_METHOD::ColorObject> destBuffer,
int16_t x, int16_t x,
int16_t y, int16_t y,
uint16_t indexSprite, uint16_t indexSprite,
@@ -135,7 +135,7 @@ public:
if (indexDest < destPixelCount) if (indexDest < destPixelCount)
{ {
typename T_BUFFER_METHOD::ColorObject color = _method.GetPixelColor(pixelIndex(indexSprite, srcX, srcY)); typename T_BUFFER_METHOD::ColorObject color = _method.GetPixelColor(pixelIndex(indexSprite, srcX, srcY));
destBuffer.Pixels[destPixelIndex + indexDest] = color; destBuffer.Pixels[indexDest] = color;
} }
} }
} }

View File

@@ -70,26 +70,31 @@ protected:
template <typename T_COLOR> static T_COLOR template <typename T_COLOR> static T_COLOR
_PgmReadByBytes(PGM_VOID_P pPixelSrc) _PgmReadByBytes(PGM_VOID_P pPixelSrc)
{ {
T_COLOR result;
const uint8_t* pSrc = reinterpret_cast<const uint8_t*>(pPixelSrc); const uint8_t* pSrc = reinterpret_cast<const uint8_t*>(pPixelSrc);
const uint8_t* pEnd = pSrc + T_COLOR::Count; const uint8_t* pEnd = pSrc + T_COLOR::Count;
uint8_t index = 0; uint8_t index = 0;
while (pSrc < pEnd) while (pSrc < pEnd)
{ {
color[index++] = pgm_read_byte(pSrc++); result[index++] = pgm_read_byte(pSrc++);
} }
return result;
} }
template <typename T_COLOR> static T_COLOR template <typename T_COLOR> static T_COLOR
_PgmReadByWords(PGM_VOID_P pPixelSrc) _PgmReadByWords(PGM_VOID_P pPixelSrc)
{ {
T_COLOR result;
const uint16_t* pSrc = reinterpret_cast<const uint16_t*>(pPixelSrc); const uint16_t* pSrc = reinterpret_cast<const uint16_t*>(pPixelSrc);
const uint16_t* pEnd = pSrc + T_COLOR::Count; const uint16_t* pEnd = pSrc + T_COLOR::Count;
uint8_t index = 0; uint8_t index = 0;
while (pSrc < pEnd) while (pSrc < pEnd)
{ {
color[index++] = pgm_read_word(pSrc++); result[index++] = pgm_read_word(pSrc++);
} }
return result;
} }
}; };