renderbug/lib/Figments/Surface.cpp

74 lines
2.2 KiB
C++

#include "./Surface.h"
#include "./Display.h"
#include <ArduinoLog.h>
#include "Perfcounter.h"
Surface::Surface(Display* dpy, const VirtualCoordinates& start, const VirtualCoordinates& end)
: start(dpy->coordinateMapping()->virtualToPhysicalCoords(start)),
end(dpy->coordinateMapping()->virtualToPhysicalCoords(end)),
virtStart(start),
virtEnd(end),
m_display(dpy)
{
//assert(start.x <= end.x);
//assert(start.y <= end.y);
}
Surface::Surface(Display* dpy, const VirtualCoordinates& start, const VirtualCoordinates& end, uint8_t rotation)
: start(dpy->coordinateMapping()->virtualToPhysicalCoords(start)),
end(dpy->coordinateMapping()->virtualToPhysicalCoords(end)),
virtStart(start),
virtEnd(end),
m_display(dpy),
m_rotation(rotation)
{
//assert(start.x <= end.x);
//assert(start.y <= end.y);
}
Surface&
Surface::operator=(const CRGB& color)
{
paintWith([&](CRGB& pixel) {
pixel = color;
});
return *this;
}
Surface&
Surface::operator+=(const CRGB& color)
{
paintWith([&](CRGB& pixel) {
pixel += color;
});
return *this;
}
void
Surface::paintWith(std::function<void(CRGB&)> func)
{
paintShader([=](CRGB& pixel, const VirtualCoordinates&, const PhysicalCoordinates&, const VirtualCoordinates&){ func(pixel); });
}
void
Surface::paintShader(Surface::Shader shader)
{
PerfCounter _("paintShader");
const uint16_t width = end.x - start.x + 1;
const uint16_t height = end.y - start.y + 1;
const uint8_t xMod = 255 / width;
const uint8_t yMod = 255 / height;
for(auto x = 0; x < width; x++) {
for(auto y = 0; y < height; y++) {
PhysicalCoordinates coords{x + start.x, y + start.y};
VirtualCoordinates virtCoords{m_display->coordinateMapping()->physicalToVirtualCoords(coords)};
VirtualCoordinates surfaceCoords{xMod * x, yMod * y};
//Log.notice("width=%d height=%d vx=%d vy=%d sx=%d sy=%d x=%d y=%d px=%d py=%d", width, height, start.x, start.y, x, y, coords.x, coords.y);
// 256 = 1.0
// 128 = 0.0
// 0 = 1.0
shader(m_display->pixelAt(coords), virtCoords, coords, surfaceCoords);
}
}
}