renderbug/lib/Figments/Surface.h
2023-03-03 19:43:51 +01:00

76 lines
2.2 KiB
C++

#pragma once
#include <FastLED.h>
#include "./Geometry.h"
#include <functional>
class Display;
/**
* A high performance and hardware-independent rendering surface which
* represents a full 2d display ranging from (0,0) to (255, 255), that may be
* rotated.
*
* Simple brushes and complex shaders may be applied to a Surface using
* @paintWith and @paintShader. The Surface will only execute each shader or
* brush once for each physical pixel in the display, allowing you to design
* display-independent graphics.
*/
class Surface {
public:
Surface(Display* dpy, const VirtualCoordinates& start, const VirtualCoordinates& end);
Surface(Display* dpy, const VirtualCoordinates& start, const VirtualCoordinates& end, uint8_t rotation);
/**
* Sets the entire surface to one solid color
*/
Surface& operator=(const CRGB& color);
/**
* Adds the given color to every pixel on the surface
*/
Surface& operator+=(const CRGB& color);
/**
* OR operation that applies the given color to every pixel on the surface
*/
template<typename T>
Surface& operator|=(const T& val) {
paintWith([&](CRGB& pixel) {
pixel |= val;
});
return *this;
}
/**
* A lambda function that maps coordinates to colors.
*/
using Shader = std::function<void(CRGB&, const VirtualCoordinates& virtPos, const PhysicalCoordinates& realPos, const VirtualCoordinates& surfacePos)>;
/**
* A simple lambda that is called for every pixel in a surface. Commonly
* used for solid fills; if you want to map pixel coordinates to colors or
* textures, you probably want to use a Shader instead.
*/
using BrushFunc = std::function<void(CRGB&)>;
/**
* Applies the given BrushFunc to every physical pixel in the surface
*/
void paintWith(BrushFunc func);
/**
* Applies the given Shader to every physical pixel in the surface
*/
void paintShader(Shader shader);
const PhysicalCoordinates start;
const PhysicalCoordinates end;
const VirtualCoordinates virtStart;
const VirtualCoordinates virtEnd;
private:
Display* m_display;
uint8_t m_rotation = 0;
};