diff --git a/libs/mare/CMakeLists.txt b/libs/mare/CMakeLists.txt index 0c2dcc2..096dc06 100644 --- a/libs/mare/CMakeLists.txt +++ b/libs/mare/CMakeLists.txt @@ -4,9 +4,6 @@ # Save the name to DIR_Config_SRCS aux_source_directory(. DIR_Config_SRCS) -# Initialize the SDK -pico_sdk_init() - include_directories(../epaper/Config) include_directories(../epaper/e-Paper) include_directories(../epaper/Fonts) diff --git a/libs/mare/mare.cpp b/libs/mare/mare.cpp index a4e1c1f..f57dc3d 100644 --- a/libs/mare/mare.cpp +++ b/libs/mare/mare.cpp @@ -49,9 +49,9 @@ namespace Render { } void Mare::setPixel(uint8_t* img, uint16_t x, uint16_t y, bool value){ - assert(x <= _screenSize.x); - assert(y <= _screenSize.y); - img += (sizeof(uint8_t)*y*(_screenSize.x/8) + sizeof(uint8_t)*(x/8)); + if (x >= _screenSize.x) return; + if (y >= _screenSize.y) 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)); } diff --git a/libs/mare/mare.h b/libs/mare/mare.h index 7fdd754..9d838fc 100644 --- a/libs/mare/mare.h +++ b/libs/mare/mare.h @@ -4,6 +4,7 @@ #include #include +#include extern "C" { #include @@ -14,6 +15,7 @@ extern "C" { #include #include #include +#include namespace Render{ @@ -94,6 +96,11 @@ namespace Render{ 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_Base(_screenBufferBackground); + } // members private: @@ -123,12 +130,19 @@ namespace Render{ void setId(const size_t id) { _id = id; }; void setOrigin(const pos_t origin) { _origin = origin; }; void setDirty() {_dirty = true;}; + void resetDirty() {_dirty = false;}; void setBlendMode(const BlendMode mode) { _blendMode = BlendMode::Intersect; }; + const bool isDirty() {return _dirty;} const pos_t getOrigin() { return _origin; }; const bbox2d_t getBBox() { return _bbox; }; const BlendMode getBlendMode() { return _blendMode; }; + uint8_t* getBuffer() { + if (_parent == nullptr) return engine()->bBuffer(); + else return engine()->fBuffer(); + } + Mare* engine() { return _engine; }; Drawable* parent() { return _parent; }; @@ -162,26 +176,27 @@ namespace Render{ }; class DrawableLine: public Drawable { - - DrawableLine(); - ~DrawableLine(); + + public: + DrawableLine(const size_t id, Drawable* parent, Mare* engine); + ~DrawableLine(); public: - void setThickness(uint16_t thickness); - const uint16_t getThickness(); - void setRotation(float rotation); - const float getRotation(); - void setLength(uint16_t length); - const uint16_t getLength(); + 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;}; private: void render(); // difficult business // members private: - uint16_t _thickness; - uint16_t _lenght; - float _rotation; + uint16_t _thickness; + uint16_t _lenght; + float _rotation; }; class DrawableRectangle: public Drawable { diff --git a/libs/mare/mare_drawables.cpp b/libs/mare/mare_drawables.cpp index d84384b..f4cb757 100644 --- a/libs/mare/mare_drawables.cpp +++ b/libs/mare/mare_drawables.cpp @@ -5,7 +5,11 @@ namespace Render { Drawable::Drawable(const size_t id, Drawable* parent, Mare* engine): _id(id), _parent(parent), - _engine(engine) + _engine(engine), + _origin({0,0}), + _bbox({0,0,0,0}), + _blendMode(Render::BlendMode::Intersect), + _dirty(false) { } @@ -28,23 +32,58 @@ namespace Render { void DrawablePoint::render() { uint8_t *buf; - if (parent() == nullptr) - buf = engine()->bBuffer(); - else - buf = engine()->fBuffer(); - //TODO: implement screen rotation and margin check - auto dx = engine()->getSize().x; - for (uint16_t xx(0); xx< _size.x; xx++){ - for (uint16_t yy(0); yy < _size.y; yy++) - { - engine()->setPixel(buf,dx-(getOrigin().x+xx),getOrigin().y+yy,true); - } + if (isDirty()){ + buf = getBuffer(); + //TODO: implement screen rotation and margin check + auto dx = engine()->getSize().x; + auto dy = engine()->getSize().y; + for (uint16_t xx(0); xx< _size.x; xx++){ + for (uint16_t yy(0); yy < _size.y; yy++) + { + engine()->setPixel(buf,dx-(getOrigin().x+xx),getOrigin().y+yy,true); + } + } + resetDirty(); } } //--------+--------+--------+--------+--------+--------+--------+--------+--------+--------// //Line + DrawableLine::DrawableLine(const size_t id, Drawable* parent, Mare* engine): + Drawable(id, parent,engine), + _thickness(1), + _lenght(0), + _rotation(0.0f) + { + + } + + DrawableLine::~DrawableLine(){ + + } + + void DrawableLine::render(){ + uint8_t* buf; + if (isDirty()) { + buf = getBuffer(); + float cx,sx; + auto dx = engine()->getSize().x; + auto dy = engine()->getSize().y; + sincosf(_rotation,&sx,&cx); // use optimized float instructions + uint16_t endX = round(cx*(float)_lenght); + for(uint16_t yy(0); yy <= _thickness; ++yy){ + for(uint16_t xx(0); xx <= endX; ++xx){ + float dydx = cx == 0.0f ? 0 : (sx/cx); + float dxdy = sx == 0.0f ? 0 : (cx/sx); + uint16_t y = getOrigin().y+yy+xx*dydx; + uint16_t x = dx-(getOrigin().x+xx+yy); + engine()->setPixel(buf,x,y,true); + } + } + resetDirty(); + } + } //--------+--------+--------+--------+--------+--------+--------+--------+--------+--------// //Rectangle diff --git a/src/main.cpp b/src/main.cpp index 64924c1..4275bba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,22 +16,30 @@ int main(){ auto viewer = Render::Mare(ssize); - Render::dim_t ps; ps.x=0; ps.y=0; + Render::dim_t ps; ps.x=8; ps.y=8; - auto point = viewer.addDrawable(ps); - point->setSize({16,16}); - for (auto d(0); d < 128-16; ++d){ - ps.x=d; ps.y=d; - point->setOrigin(ps); - viewer.render(); + auto line = viewer.addDrawable(); + line->setThickness(4); + line->setOrigin(ps); + while (true){ + line->setRotation(0); + for (auto d(8); d < 128; d+=8){ + line->setLength(d); + line->setDirty(); + viewer.render(); + } + + for (float a(0.0f); a<=M_PI_2; a+=0.1){ + line->setRotation(a); + line->setDirty(); + viewer.render(); + } + viewer.clearScreen(); } - - while(true){ - printf("[%u] Hello, world!\n",i++); gpio_put(LED_PIN,s); s = s ? false : true; - + sleep_ms(500); } return 0;