From 54fabc151da387d291370243bd4f954ab967bb78 Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Sun, 6 Jun 2021 13:22:03 +0200 Subject: [PATCH] rectagle outline drawing --- libs/mare/mare.cpp | 4 +- libs/mare/mare.h | 55 ++++++++------ libs/mare/mare_drawables.cpp | 136 ++++++++++++++++++++++------------- src/main.cpp | 19 +++-- 4 files changed, 136 insertions(+), 78 deletions(-) diff --git a/libs/mare/mare.cpp b/libs/mare/mare.cpp index 4201ea1..5dac9c9 100644 --- a/libs/mare/mare.cpp +++ b/libs/mare/mare.cpp @@ -113,9 +113,9 @@ namespace Render { else if (bm == BlendMode::Intersect) *img = ~*img ^ ~(0x80 >> (x%8)); } - spos_t Mare::rotateXY(int16_t x, int16_t y, float rot){ + pos_t Mare::rotateXY(int16_t x, int16_t y, float rot){ // apply rotation matrix xy - spos_t rv; + pos_t rv; float cx,sx; sincosf(rot, &sx, &cx); rv.x = x*cx - y*sx; diff --git a/libs/mare/mare.h b/libs/mare/mare.h index 268d6cc..353acfa 100644 --- a/libs/mare/mare.h +++ b/libs/mare/mare.h @@ -21,14 +21,11 @@ extern "C" { namespace Render{ - struct pos_t { - uint16_t x; - uint16_t y; - }; + typedef int32_t p_t; - struct spos_t { - int16_t x; - int16_t y; + struct pos_t { + p_t x; + p_t y; }; struct bbox2d_t { @@ -56,6 +53,8 @@ namespace Render{ class Page; class Drawable; class DrawablePoint; + class DrawableLine; + class DrawableRectangle; typedef pos_t dim_t; typedef std::vector> Pages; @@ -105,7 +104,7 @@ namespace Render{ public: void render(); void setPixel(uint8_t* img, uint16_t x, uint16_t y, BlendMode bm); - spos_t rotateXY(int16_t x, int16_t y, float rot); + pos_t rotateXY(int16_t x, int16_t y, float rot); void clearScreen(); // members @@ -182,6 +181,7 @@ namespace Render{ }; class DrawableLine: public Drawable { + friend class DrawableRectangle; public: DrawableLine(const size_t id, Drawable* parent, Mare* engine); @@ -190,12 +190,10 @@ namespace Render{ public: void setThickness(uint16_t thickness) {_thickness = thickness;}; const uint16_t getThickness() {return _thickness;}; - void setRotation(float rotation) {_rotation = rotation;}; - const float getRotation() {return _rotation;}; - void setLength(uint16_t length) {_lenght = length;}; - const uint16_t getLength() {return _lenght;}; - void setOutline(bool outline) {_outline = outline;}; - const bool getOutline() {return _outline;}; + void setRotation(uint16_t rotation) {_rotation = rotation;}; + const uint16_t getRotation() {return _rotation;}; + void setLength(uint16_t length) {_length = length;}; + const uint16_t getLength() {return _length;}; private: void render(); // difficult business @@ -203,23 +201,40 @@ namespace Render{ // members private: uint16_t _thickness; - uint16_t _lenght; - float _rotation; - bool _outline; + uint16_t _length; + uint16_t _rotation; }; class DrawableRectangle: public Drawable { - DrawableRectangle(); - ~DrawableRectangle(); + public: + DrawableRectangle(const size_t id, Drawable* parent, Mare* engine); + ~DrawableRectangle(); public: + void setThickness(uint16_t thickness) {_thickness = thickness;}; + const uint16_t getThickness() {return _thickness;}; + void setRotation(uint16_t rotation) {_rotation = rotation;}; + const uint16_t getRotation() {return _rotation;}; + void setDimension(dim_t dim) {_dim = dim;}; + const dim_t getDimension() {return _dim;}; + void setOutline(bool outline) {_outline = outline;}; + const bool getOutline() {return _outline;}; private: - void render() {}; + void createOutline(); + void render(); // members private: + DrawableLine* l1 = nullptr; + DrawableLine* l2 = nullptr; + DrawableLine* l3 = nullptr; + DrawableLine* l4 = nullptr; + uint16_t _thickness; + uint16_t _rotation; + dim_t _dim; + bool _outline; }; class DrawableCircle: public Drawable { diff --git a/libs/mare/mare_drawables.cpp b/libs/mare/mare_drawables.cpp index 83fd7e4..00d27cf 100644 --- a/libs/mare/mare_drawables.cpp +++ b/libs/mare/mare_drawables.cpp @@ -54,14 +54,14 @@ namespace Render { DrawableLine::DrawableLine(const size_t id, Drawable* parent, Mare* engine): Drawable(id, parent,engine), _thickness(1), - _lenght(0), - _rotation(0.0f), - _outline(false) + _length(0), + _rotation(0) { } - DrawableLine::~DrawableLine(){ + DrawableLine::~DrawableLine() + { } @@ -69,55 +69,23 @@ namespace Render { uint8_t* buf = getBuffer(); auto tt = _thickness; auto e = engine(); - // 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,xx+x,yy+y,getBlendMode()); - // } - // }; - - // if (isDirty() && false) { - // _rotation = fmod(_rotation, M_TWOPI); - // float cx,sx; - // sincosf(_rotation,&sx,&cx); // use optimized float instructions - // 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*mult*dydx; - // uint16_t x = getOrigin().x+xx*mult; - // square(x,y); - // } - // } else { - // for (uint16_t yy(0); yy <= endY; ++yy){ - // float dxdy = sx == 0.0f ? 0 : (cx/sx); - // uint16_t y = getOrigin().y+yy*mult; - // uint16_t x = getOrigin().x+yy*mult*dxdy; - // square(x,y); - // } - // } - // resetDirty(); - // } - - if (isDirty() && true) { - _rotation = fmod(_rotation, M_TWOPI); + if (isDirty()) { + _rotation = _rotation % 360; pos_t o = getOrigin(); - static spos_t res = {0,0}; + pos_t res = {0,0}; for (uint16_t t(0); t < _thickness; ++t) { - for (uint16_t xx(0); xx < _lenght; ++xx) { - if (!_outline || (_outline && (xx == 0 || xx == _lenght - 1 || t == 0 || t == _thickness - 1))) { - res = e->rotateXY(xx,t-(_thickness>>1),_rotation); - e->setPixel(buf,res.x+o.x,res.y+o.y,getBlendMode()); + for (uint16_t xx(0); xx < _length; ++xx) { + if (_rotation == 0 || _rotation == 180){ + res.x = _rotation == 0 ? xx : (_length-xx); + res.y = t-(_thickness>>1); + } else if (_rotation == 90 || _rotation == 270){ + res.x = t-(_thickness>>1); + res.y = _rotation == 90 ? xx : _length-xx; + } else { + res = e->rotateXY(xx,t-(_thickness>>1),_rotation/180.0f*M_PI); } + e->setPixel(buf,res.x+o.x,res.y+o.y,getBlendMode()); + } } resetDirty(); @@ -127,6 +95,74 @@ namespace Render { //--------+--------+--------+--------+--------+--------+--------+--------+--------+--------// //Rectangle + DrawableRectangle::DrawableRectangle(const size_t id, Drawable* parent, Mare* engine): + Drawable(id, parent,engine), + _thickness(1), + _rotation(0), + _dim({8,8}), + _outline(false) + { + + } + + DrawableRectangle::~DrawableRectangle() + { + + } + + void DrawableRectangle::createOutline(){ + auto e = engine(); + pos_t o = getOrigin(); + float cx,sx; + if (l1 == nullptr) l1 = e->addDrawable(); + if (l2 == nullptr) l2 = e->addDrawable(); + if (l3 == nullptr) l3 = e->addDrawable(); + if (l4 == nullptr) l4 = e->addDrawable(); + + _rotation %= 360; + sincosf(_rotation/180.0f*M_PI, &sx, &cx); + + l1->setRotation(_rotation); + l1->setLength(_dim.x); + l1->setThickness(_thickness); + l2->setRotation(_rotation+90); + l2->setLength(_dim.y); + l2->setThickness(_thickness); + l3->setRotation(_rotation); + l3->setLength(_dim.x); + l3->setThickness(_thickness); + l4->setRotation(_rotation+90); + l4->setLength(_dim.y); + l4->setThickness(_thickness); + + l1->setOrigin(o); + l2->setOrigin({(p_t)(o.x+(_dim.x-_thickness+1)*cx), (p_t)(o.y+(_dim.x-_thickness+1)*sx)}); + l3->setOrigin({(p_t)(o.x-(_dim.y-_thickness+1)*sx), (p_t)(o.y+(_dim.y-_thickness+1)*cx)}); + l4->setOrigin(o); + + l1->setDirty(); + l2->setDirty(); + l3->setDirty(); + l4->setDirty(); + } + + void DrawableRectangle::render() + { + uint8_t* buf = getBuffer(); + auto tt = _thickness; + auto e = engine(); + if (isDirty()) { + if (_outline) { + createOutline(); + l1->render(); + l2->render(); + l3->render(); + l4->render(); + } + resetDirty(); + } + } + //--------+--------+--------+--------+--------+--------+--------+--------+--------+--------// //Circle diff --git a/src/main.cpp b/src/main.cpp index aed056d..2a62671 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,30 +20,37 @@ int main(){ auto c1 = viewer.addDrawable(); auto c2 = viewer.addDrawable(); auto line3 = viewer.addDrawable(); + auto rect = viewer.addDrawable(); c1->setOrigin({0,63}); c1->setLength(296); - c1->setThickness(2); + c1->setThickness(3); c1->setBlendMode(Render::BlendMode::Add); c2->setOrigin({296/2-1, 1}); c2->setLength(128); - c2->setRotation(M_PI_2); - c2->setThickness(2); + c2->setRotation(90); + c2->setThickness(3); c1->setBlendMode(Render::BlendMode::Add); line3->setLength(64); line3->setOrigin(viewer.getCenter()); line3->setBlendMode(Render::BlendMode::Add); - line3->setOutline(false); + + rect->setDimension({48,32}); + rect->setOrigin({8,8}); + rect->setOutline(true); + rect->setThickness(3); while (true){ - line3->setThickness(i++); - for (float a(0); a<=M_TWOPI; a+=(M_TWOPI/36.0f)){ + line3->setThickness(2); + for (uint16_t a(0); a<=360; a+=360/32){ line3->setRotation(a); + //rect->setRotation(a); line3->setDirty(); c1->setDirty(); c2->setDirty(); + rect->setDirty(); viewer.render(); } viewer.clearScreen();