correct render of sprite lines!!

This commit is contained in:
Emanuele Trabattoni
2021-05-30 13:03:02 +02:00
parent 539a95df61
commit 7116885f2d
4 changed files with 110 additions and 48 deletions

View File

@@ -5,10 +5,11 @@
namespace Render {
Mare::Mare(dim_t size) :
Mare::Mare(dim_t size, ScreenRotation rot) :
_screenSize(size),
_screenBufferBackground(nullptr),
_screenBufferForeground(nullptr)
_screenBufferForeground(nullptr),
_rotation(rot)
{
int rv;
_bufferDim = (_screenSize.x >> 3) * _screenSize.y;
@@ -48,17 +49,74 @@ namespace Render {
EPD_2IN9_V2_Display_Partial(_screenBufferBackground);
}
void Mare::setPixel(uint8_t* img, uint16_t x, uint16_t y, bool value){
if (x >= _screenSize.y) return;
if (y >= _screenSize.x) return;
img += (sizeof(uint8_t)*y*(_screenSize.x>>3) + sizeof(uint8_t)*(x>>3));
if (value) *img &= ~(0x80 >> (x%8));
else *img |= (0x80 >> (x%8));
}
void Mare::clearBuffer(uint8_t* buffer, uint16_t len, Color col){
assert(buffer != nullptr);
std::memset(buffer, col == Color::White ? 0xff : 0x00, len);
}
bool Mare::applyRotation(uint16_t* x, uint16_t* y) {
uint16_t ax,ay;
switch(_rotation){
case ScreenRotation::Rot0 :
{
if (*x >= _screenSize.x || *y >= _screenSize.y) return false;
break;
}
case ScreenRotation::Rot90 :
{
if (*x >= _screenSize.y || *y >= _screenSize.x) return false;
ax = *x; ay = *y;
*x = _screenSize.x - ay;
*y = ax;
break;
}
case ScreenRotation::Rot180 :
{
if (*x >= _screenSize.x || *y >= _screenSize.y) return false;
ax = *x; ay = *y;
*x = _screenSize.x - ax;
*y = _screenSize.y - ay;
break;
}
case ScreenRotation::Rot270 :
{
if (*x >= _screenSize.y || *y >= _screenSize.x) return false;
ax = *x; ay = *y;
*x = ay;
*y = _screenSize.y - ax;
break;
}
}
if (*x < 0 || *y < 0) return false;
return true;
}
// Public
const dim_t Mare::getCenter() {
dim_t rv;
if (_rotation == ScreenRotation::Rot0 || _rotation == ScreenRotation::Rot180){
rv.x = _screenSize.x >> 1;
rv.y = _screenSize.y >> 1;
} else {
rv.x = _screenSize.y >> 1;
rv.y = _screenSize.x >> 1;
}
return rv;
}
void Mare::setPixel(uint8_t* img, uint16_t x, uint16_t y, bool value) {
if (!applyRotation(&x,&y)) return;
// from here the coordinates are natural for the screen
img += (sizeof(uint8_t)*y*(_screenSize.x>>3) + sizeof(uint8_t)*(x>>3));
if (value) *img &= ~(0x80 >> (x%8));
else *img |= (0x80 >> (x%8));
}
void Mare::clearScreen() {
EPD_2IN9_V2_Clear();
clearBuffer(_screenBufferBackground, _bufferDim, Color::White);
EPD_2IN9_V2_Display(_screenBufferBackground);
}
}

View File

@@ -59,13 +59,14 @@ namespace Render{
friend class Page;
public:
Mare(dim_t size);
Mare(dim_t size, ScreenRotation rot);
~Mare();
// getters, setters
public:
void setSize(const dim_t size);
const dim_t getSize() {return _screenSize;};
const dim_t getCenter();
void setRotation(const ScreenRotation r);
const ScreenRotation getRotation() {return _rotation;};
void setCurrentPage(const uint8_t p);
@@ -91,16 +92,13 @@ namespace Render{
//render
private:
void clearBuffer(uint8_t* buffer, uint16_t len, Color col);
bool applyRotation(uint16_t* x, uint16_t* y);
void visitDrawables(Drawable* parent) {};
public:
void render();
void setPixel(uint8_t* img, uint16_t x, uint16_t y, bool value);
void clearScreen() {
EPD_2IN9_V2_Clear();
clearBuffer(_screenBufferBackground, _bufferDim, Color::White);
EPD_2IN9_V2_Display(_screenBufferBackground);
}
void clearScreen();
// members
private:

View File

@@ -66,13 +66,14 @@ namespace Render {
void DrawableLine::render(){
uint8_t* buf = getBuffer();
auto tt = _thickness;
auto dx = engine()->getSize().x;
auto dy = engine()->getSize().y;
auto e = engine();
auto square = [tt,dy,buf,e](uint16_t x, uint16_t y){ //sprite render
auto square = [buf,e,tt](uint16_t x, uint16_t y){
uint8_t c = tt > 1 ? tt>>1 : 0; //sprite render
x -= c;
y -= c;
for (auto xx(0); xx <= tt; ++xx)
for (auto yy(0); yy <= tt; ++yy){
e->setPixel(buf,dy-(yy+y),xx+x,true);
e->setPixel(buf,xx+x,yy+y,true);
}
};
@@ -80,24 +81,28 @@ namespace Render {
_rotation = fmod(_rotation, M_TWOPI);
float cx,sx;
sincosf(_rotation,&sx,&cx); // use optimized float instructions
uint16_t endX = round(cx*(float)_lenght);
uint16_t endY = round(sx*(float)_lenght);
if ((_rotation >= -M_PI_4 && _rotation <= M_PI_4) ||
(_rotation >= 3*M_PI_4 && _rotation <= 5*M_PI_4))
uint16_t endX = fabs(round(cx*(float)_lenght));
uint16_t endY = fabs(round(sx*(float)_lenght));
int8_t mult = (_rotation <= 3*M_PI_4 || _rotation >= 7*M_PI_4) ? 1 : -1;
if ((_rotation >= 7*M_PI_4 || _rotation <= M_PI_4) ||
(_rotation >= 3*M_PI_4 && _rotation <= 5*M_PI_4)) {
for(uint16_t xx(0); xx <= endX; ++xx){
float dydx = cx == 0.0f ? 0 : (sx/cx);
uint16_t y = getOrigin().y+xx*dydx;
uint16_t x = getOrigin().x+xx;
uint16_t y = getOrigin().y+xx*mult*dydx;
uint16_t x = getOrigin().x+xx*mult;
square(x,y);
}
else
} else {
for (uint16_t yy(0); yy <= endY; ++yy){
float dxdy = sx == 0.0f ? 0 : (cx/sx);
uint16_t y = getOrigin().y+yy;
uint16_t x = getOrigin().x+yy*dxdy;
uint16_t y = getOrigin().y+yy*mult;
uint16_t x = getOrigin().x+yy*mult*dxdy;
square(x,y);
}
}
resetDirty();
}
}