77 lines
2.3 KiB
C++
77 lines
2.3 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");
|
|
uint8_t startX = min(start.x, end.x);
|
|
uint8_t startY = min(start.y, end.y);
|
|
uint8_t endX = max(start.x, end.x);
|
|
uint8_t endY = max(start.y, end.y);
|
|
const uint16_t width = endX - startX + 1;
|
|
const uint16_t height = endY - startY + 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 + startX, y + startY};
|
|
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, startX, startY, x, y, coords.x, coords.y); // 256 = 1.0
|
|
// 128 = 0.0
|
|
// 0 = 1.0
|
|
shader(m_display->pixelAt(coords), virtCoords, coords, surfaceCoords);
|
|
}
|
|
}
|
|
}
|