correct render of sprite lines!!
This commit is contained in:
@@ -5,10 +5,11 @@
|
|||||||
|
|
||||||
namespace Render {
|
namespace Render {
|
||||||
|
|
||||||
Mare::Mare(dim_t size) :
|
Mare::Mare(dim_t size, ScreenRotation rot) :
|
||||||
_screenSize(size),
|
_screenSize(size),
|
||||||
_screenBufferBackground(nullptr),
|
_screenBufferBackground(nullptr),
|
||||||
_screenBufferForeground(nullptr)
|
_screenBufferForeground(nullptr),
|
||||||
|
_rotation(rot)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
_bufferDim = (_screenSize.x >> 3) * _screenSize.y;
|
_bufferDim = (_screenSize.x >> 3) * _screenSize.y;
|
||||||
@@ -48,17 +49,74 @@ namespace Render {
|
|||||||
EPD_2IN9_V2_Display_Partial(_screenBufferBackground);
|
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){
|
void Mare::clearBuffer(uint8_t* buffer, uint16_t len, Color col){
|
||||||
assert(buffer != nullptr);
|
assert(buffer != nullptr);
|
||||||
std::memset(buffer, col == Color::White ? 0xff : 0x00, len);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -59,13 +59,14 @@ namespace Render{
|
|||||||
friend class Page;
|
friend class Page;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Mare(dim_t size);
|
Mare(dim_t size, ScreenRotation rot);
|
||||||
~Mare();
|
~Mare();
|
||||||
|
|
||||||
// getters, setters
|
// getters, setters
|
||||||
public:
|
public:
|
||||||
void setSize(const dim_t size);
|
void setSize(const dim_t size);
|
||||||
const dim_t getSize() {return _screenSize;};
|
const dim_t getSize() {return _screenSize;};
|
||||||
|
const dim_t getCenter();
|
||||||
void setRotation(const ScreenRotation r);
|
void setRotation(const ScreenRotation r);
|
||||||
const ScreenRotation getRotation() {return _rotation;};
|
const ScreenRotation getRotation() {return _rotation;};
|
||||||
void setCurrentPage(const uint8_t p);
|
void setCurrentPage(const uint8_t p);
|
||||||
@@ -91,16 +92,13 @@ namespace Render{
|
|||||||
//render
|
//render
|
||||||
private:
|
private:
|
||||||
void clearBuffer(uint8_t* buffer, uint16_t len, Color col);
|
void clearBuffer(uint8_t* buffer, uint16_t len, Color col);
|
||||||
|
bool applyRotation(uint16_t* x, uint16_t* y);
|
||||||
void visitDrawables(Drawable* parent) {};
|
void visitDrawables(Drawable* parent) {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void render();
|
void render();
|
||||||
void setPixel(uint8_t* img, uint16_t x, uint16_t y, bool value);
|
void setPixel(uint8_t* img, uint16_t x, uint16_t y, bool value);
|
||||||
void clearScreen() {
|
void clearScreen();
|
||||||
EPD_2IN9_V2_Clear();
|
|
||||||
clearBuffer(_screenBufferBackground, _bufferDim, Color::White);
|
|
||||||
EPD_2IN9_V2_Display(_screenBufferBackground);
|
|
||||||
}
|
|
||||||
|
|
||||||
// members
|
// members
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -66,13 +66,14 @@ namespace Render {
|
|||||||
void DrawableLine::render(){
|
void DrawableLine::render(){
|
||||||
uint8_t* buf = getBuffer();
|
uint8_t* buf = getBuffer();
|
||||||
auto tt = _thickness;
|
auto tt = _thickness;
|
||||||
auto dx = engine()->getSize().x;
|
|
||||||
auto dy = engine()->getSize().y;
|
|
||||||
auto e = engine();
|
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 xx(0); xx <= tt; ++xx)
|
||||||
for (auto yy(0); yy <= tt; ++yy){
|
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);
|
_rotation = fmod(_rotation, M_TWOPI);
|
||||||
float cx,sx;
|
float cx,sx;
|
||||||
sincosf(_rotation,&sx,&cx); // use optimized float instructions
|
sincosf(_rotation,&sx,&cx); // use optimized float instructions
|
||||||
uint16_t endX = round(cx*(float)_lenght);
|
uint16_t endX = fabs(round(cx*(float)_lenght));
|
||||||
uint16_t endY = round(sx*(float)_lenght);
|
uint16_t endY = fabs(round(sx*(float)_lenght));
|
||||||
if ((_rotation >= -M_PI_4 && _rotation <= M_PI_4) ||
|
|
||||||
(_rotation >= 3*M_PI_4 && _rotation <= 5*M_PI_4))
|
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){
|
for(uint16_t xx(0); xx <= endX; ++xx){
|
||||||
float dydx = cx == 0.0f ? 0 : (sx/cx);
|
float dydx = cx == 0.0f ? 0 : (sx/cx);
|
||||||
uint16_t y = getOrigin().y+xx*dydx;
|
uint16_t y = getOrigin().y+xx*mult*dydx;
|
||||||
uint16_t x = getOrigin().x+xx;
|
uint16_t x = getOrigin().x+xx*mult;
|
||||||
square(x,y);
|
square(x,y);
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
for (uint16_t yy(0); yy <= endY; ++yy){
|
for (uint16_t yy(0); yy <= endY; ++yy){
|
||||||
float dxdy = sx == 0.0f ? 0 : (cx/sx);
|
float dxdy = sx == 0.0f ? 0 : (cx/sx);
|
||||||
uint16_t y = getOrigin().y+yy;
|
uint16_t y = getOrigin().y+yy*mult;
|
||||||
uint16_t x = getOrigin().x+yy*dxdy;
|
uint16_t x = getOrigin().x+yy*mult*dxdy;
|
||||||
square(x,y);
|
square(x,y);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
resetDirty();
|
resetDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
37
src/main.cpp
37
src/main.cpp
@@ -14,34 +14,35 @@ int main(){
|
|||||||
ssize.x = EPD_2IN9_V2_WIDTH;
|
ssize.x = EPD_2IN9_V2_WIDTH;
|
||||||
ssize.y = EPD_2IN9_V2_HEIGHT;
|
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 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<Render::DrawableLine>();
|
auto line = viewer.addDrawable<Render::DrawableLine>();
|
||||||
//auto line2 = viewer.addDrawable<Render::DrawableLine>();
|
auto line2 = viewer.addDrawable<Render::DrawableLine>();
|
||||||
auto line3 = viewer.addDrawable<Render::DrawableLine>();
|
auto line3 = viewer.addDrawable<Render::DrawableLine>();
|
||||||
|
|
||||||
//line->setOrigin(ps);
|
line->setOrigin(ps);
|
||||||
//line->setLength(256);
|
line->setLength(256);
|
||||||
//line2->setLength(256);
|
line2->setLength(256);
|
||||||
line3->setLength(32);
|
line3->setLength(64);
|
||||||
line3->setOrigin(cx);
|
line3->setOrigin(viewer.getCenter());
|
||||||
while (true){
|
while (true){
|
||||||
//ps.x = ssize.y-i;
|
ps.x = ssize.y-i;
|
||||||
//line2->setOrigin(ps);
|
line2->setOrigin(ps);
|
||||||
//line->setThickness(i);
|
line->setThickness(i);
|
||||||
//line2->setThickness(i);
|
line2->setThickness(i);
|
||||||
line3->setThickness(i++);
|
line3->setThickness(i++);
|
||||||
for (float a(0.0f); a<=M_TWOPI; a+=(M_TWOPI/180.0f)){
|
for (float a(0); a<=M_TWOPI; a+=(M_TWOPI/90.0f)){
|
||||||
//line->setRotation(a);
|
line->setRotation(a);
|
||||||
//line2->setRotation(M_PI-a);
|
line2->setRotation(M_PI-a);
|
||||||
line3->setRotation(a);
|
line3->setRotation(a);
|
||||||
//line->setDirty();
|
line->setDirty();
|
||||||
//line2->setDirty();
|
line2->setDirty();
|
||||||
line3->setDirty();
|
line3->setDirty();
|
||||||
viewer.render();
|
viewer.render();
|
||||||
|
printf("Angle: %4.3f\n", a/M_PI*180.0f);
|
||||||
}
|
}
|
||||||
viewer.clearScreen();
|
viewer.clearScreen();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user