From 7116885f2d64a6bce390e30fa028b5ed432092ee Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sun, 30 May 2021 13:03:02 +0200 Subject: [PATCH] correct render of sprite lines!! --- libs/mare/mare.cpp | 78 +++++++++++++++++++++++++++++++----- libs/mare/mare.h | 10 ++--- libs/mare/mare_drawables.cpp | 33 ++++++++------- src/main.cpp | 37 ++++++++--------- 4 files changed, 110 insertions(+), 48 deletions(-) diff --git a/libs/mare/mare.cpp b/libs/mare/mare.cpp index c4bd5e0..fb96c41 100644 --- a/libs/mare/mare.cpp +++ b/libs/mare/mare.cpp @@ -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); + } + } \ No newline at end of file diff --git a/libs/mare/mare.h b/libs/mare/mare.h index 1b547f7..3889121 100644 --- a/libs/mare/mare.h +++ b/libs/mare/mare.h @@ -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: diff --git a/libs/mare/mare_drawables.cpp b/libs/mare/mare_drawables.cpp index 5a42aa1..b2b2e8d 100644 --- a/libs/mare/mare_drawables.cpp +++ b/libs/mare/mare_drawables.cpp @@ -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(); } } diff --git a/src/main.cpp b/src/main.cpp index 754eab0..be21ac9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,34 +14,35 @@ int main(){ ssize.x = EPD_2IN9_V2_WIDTH; ssize.y = EPD_2IN9_V2_HEIGHT; - auto viewer = Render::Mare(ssize); + auto viewer = Render::Mare(ssize, + Render::ScreenRotation::Rot90); Render::dim_t ps; ps.x=0; ps.y=0; - Render::dim_t cx; cx.x=ssize.x/2; cx.y=ssize.y/2; - //auto line = viewer.addDrawable(); - //auto line2 = viewer.addDrawable(); + auto line = viewer.addDrawable(); + auto line2 = viewer.addDrawable(); auto line3 = viewer.addDrawable(); - //line->setOrigin(ps); - //line->setLength(256); - //line2->setLength(256); - line3->setLength(32); - line3->setOrigin(cx); + line->setOrigin(ps); + line->setLength(256); + line2->setLength(256); + line3->setLength(64); + line3->setOrigin(viewer.getCenter()); while (true){ - //ps.x = ssize.y-i; - //line2->setOrigin(ps); - //line->setThickness(i); - //line2->setThickness(i); + ps.x = ssize.y-i; + line2->setOrigin(ps); + line->setThickness(i); + line2->setThickness(i); line3->setThickness(i++); - for (float a(0.0f); a<=M_TWOPI; a+=(M_TWOPI/180.0f)){ - //line->setRotation(a); - //line2->setRotation(M_PI-a); + for (float a(0); a<=M_TWOPI; a+=(M_TWOPI/90.0f)){ + line->setRotation(a); + line2->setRotation(M_PI-a); line3->setRotation(a); - //line->setDirty(); - //line2->setDirty(); + line->setDirty(); + line2->setDirty(); line3->setDirty(); viewer.render(); + printf("Angle: %4.3f\n", a/M_PI*180.0f); } viewer.clearScreen(); }