From 79deae78d89757b3e1a53b5d990c28cc70d4175d Mon Sep 17 00:00:00 2001 From: jonas Date: Fri, 14 Dec 2018 18:46:22 +0100 Subject: Performance improvements to cRender::render() by only drawing changed pixels NON-Working --- AmpelJonas/cObjectHandler.cpp | 6 ++-- AmpelJonas/cRender.cpp | 84 +++++++++++++++++++++++++++++++------------ AmpelJonas/cRender.h | 12 +++++-- AmpelJonas/main.cpp | 14 ++++++-- 4 files changed, 86 insertions(+), 30 deletions(-) (limited to 'AmpelJonas') diff --git a/AmpelJonas/cObjectHandler.cpp b/AmpelJonas/cObjectHandler.cpp index a5c5884..d35653a 100644 --- a/AmpelJonas/cObjectHandler.cpp +++ b/AmpelJonas/cObjectHandler.cpp @@ -13,7 +13,7 @@ int cObjectHandler::createObject(cObject *_object) int cObjectHandler::moveObject(int _object, sPos _pos, int _mode) { - if (_object >= objects.size()) //prevent segmentation faults + if (_object >= objects.size()) //prevent segmentation faults return 1; if (!objects[_object]) @@ -41,7 +41,7 @@ int cObjectHandler::write() { render->clear(); - for (int i = 0; i < objects.size(); i++) + for (unsigned long int i = 0; i < objects.size(); i++) { if (objects[i]) // Check if objects[i] is existent { @@ -60,4 +60,4 @@ int cObjectHandler::write() } return 0; -} \ No newline at end of file +} diff --git a/AmpelJonas/cRender.cpp b/AmpelJonas/cRender.cpp index 296d7a2..1463010 100644 --- a/AmpelJonas/cRender.cpp +++ b/AmpelJonas/cRender.cpp @@ -7,21 +7,21 @@ cRender::cRender(char _backound, WORD _color, int _sx, int _sy) iLastError = _OK_; sizeX = sizeY = 0; + cBackound = _backound; + wBackColor = _color; #ifdef __linux__ //In Linux, setting Console size is not supported, so it gets Size of Console (Window) instead. struct winsize w; ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); + wDefColor = _COL_DEFAULT; + setBufferSize( getConsoleWindowSize() ); if(sizeX < _sx || sizeY < _sy) //Notify Program tha screen is too small for desired Size iLastError = _ERR_SCREEN_TOO_SMALL_; - wDefColor = _color; - - setBufferSize( getConsoleWindowSize() ); - #elif _WIN32 //Windows Specific Code hstdout = GetStdHandle(STD_OUTPUT_HANDLE); //get handle @@ -33,10 +33,8 @@ cRender::cRender(char _backound, WORD _color, int _sx, int _sy) setBufferSize({_sx,_sy}); #endif - cBackound = _backound; - wBackColor = _color; - - clear(); //Init backround array + clear(true); //Init backround array + //forceReRender(); }//render() @@ -48,10 +46,12 @@ cRender::~cRender() for (int i = 0; i < sizeX; i++) { free(cScreen[i]); free(wColor[i]); + free(bChanged[i]); } free(cScreen); free(wColor); + free(bChanged); } int cRender::drawPoint(char _c, sPos _pos, bool _overrideCollision, WORD _color) @@ -68,6 +68,9 @@ int cRender::drawPoint(char _c, sPos _pos, bool _overrideCollision, WORD _color) else wColor[_pos.x][_pos.y] = _color; + if(!bBlockRender) //Changemap is not allocated in inherited Classes + bChanged[_pos.x][_pos.y] = true; + return 0; } @@ -130,38 +133,58 @@ int cRender::drawRectangle(char _border, char _fill, sPos _pos1, sPos _pos2, WOR int cRender::render(void) { - setBufferSize(getConsoleWindowSize()); - - gotoxy(0,0); - if (bBlockRender) return _ERR_RENDER_BLOCKED_BY_CHILD_; + setBufferSize(getConsoleWindowSize()); + for (int i = 0; i < sizeY; i++) { for (int o = 0; o < sizeX; o++) { - #ifdef _WIN32 - SetConsoleTextAttribute(hstdout, wColor[o][i] | _COL_INTENSITY); - cout << cScreen[o][i]; - #elif __linux__ - cout << "\033["<< wColor[o][i] <<"m"<< cScreen[o][i]; - #endif + if(bChanged[o][i]) + { + gotoxy(o,i); + + #ifdef _WIN32 + + SetConsoleTextAttribute(hstdout, wColor[o][i] | _COL_INTENSITY); + cout << cScreen[o][i]; + + #elif __linux__ + + cout << "\033["<< wColor[o][i] <<"m"<< cScreen[o][i]; + + #endif + } + //else {} + bChanged[o][i] = false; } - cout << endl; //New Line Feed } return 0; } -int cRender::clear(void) +int cRender::clear(bool _forceReRender) { for (int i = 0; i < sizeY; i++) { for (int o = 0; o < sizeX; o++) { - cScreen[o][i] = cBackound; - wColor[o][i] = wBackColor; + if(((cScreen[o][i] == cBackound) && (wColor[o][i] == wBackColor)) && !_forceReRender) + bChanged[o][i] = false; + else + { + cScreen[o][i] = cBackound; + wColor[o][i] = wBackColor; + bChanged[o][i] = true; + } } } return 0; } +int cRender::clear() +{ + clear(false); +} + + #ifdef _WIN32 //Source: http://www.cplusplus.com/forum/windows/121444/ int cRender::SetConsoleWindowSize(int x, int y) @@ -243,10 +266,12 @@ void cRender::setBufferSize(sPos _size) for (int i = 0; i < sizeX; i++) { free(cScreen[i]); free(wColor[i]); + free(bChanged[i]); } free(cScreen); free(wColor); + free(bChanged); } sizeX = _size.x; @@ -260,9 +285,24 @@ void cRender::setBufferSize(sPos _size) wColor = (WORD**)malloc(sizeof *wColor * sizeX); for (int i = 0; i < sizeX; i++) wColor[i] = (WORD*)malloc(sizeof *wColor[i] * sizeY); + + bChanged = (bool**)malloc(sizeof *bChanged * sizeX); + for (int i = 0; i < sizeX; i++) + bChanged[i] = (bool*)malloc(sizeof *bChanged[i] * sizeY); + + clear(true); } sPos cRender::getSize() { return {sizeX, sizeY}; } + +void cRender::forceReRender() +{ + for (int i = 0; i < sizeY; i++) { + for (int o = 0; o < sizeX; o++) { + bChanged[o][i] = true; + } + } +} diff --git a/AmpelJonas/cRender.h b/AmpelJonas/cRender.h index 30077e9..00f94e2 100644 --- a/AmpelJonas/cRender.h +++ b/AmpelJonas/cRender.h @@ -91,8 +91,11 @@ public: int render(void); //Prints cScreen - int clear(void); + int clear(); + int clear(bool _forceReRender); //clears cScreen + wColor + // for _forceReRender == true, the bChanged[][] is set to true to force Re-Render of whole Screen + // clear(void) calls clear(_forceReRender = false) int getLastError(); //Returns last Error that was not returnable @@ -104,10 +107,13 @@ public: protected: cRender(); //Empty Constructor for being inheritable + void setBufferSize(sPos _size); + bool bBlockRender; //Used by children to block render function char **cScreen; //Pixel Map WORD **wColor; //Color Map + bool **bChanged; //Pixel Change Map char cBackound; //Default backround WORD wBackColor; @@ -128,7 +134,9 @@ private: //Slightly adapted from: http://www.cplusplus.com/forum/windows/121444/ #endif void gotoxy( int x, int y ); - void setBufferSize(sPos _size); + + void forceReRender(); + #ifdef __linux__ sPos getConsoleWindowSize(); #endif diff --git a/AmpelJonas/main.cpp b/AmpelJonas/main.cpp index d88ca9b..ea729ac 100644 --- a/AmpelJonas/main.cpp +++ b/AmpelJonas/main.cpp @@ -6,7 +6,9 @@ int main() { + unsigned long int framecounter = 0; cRender a(' ', _COL_DEFAULT, 10,10); + a.render(); cObjectHandler b(&a); cObject x(1,1); @@ -15,15 +17,17 @@ int main() int dir2 = -1; int cntr = 0; + a.clear(true); b.moveObject(i, {0,30}, _MOVE_ABSOULUTE); x.drawPoint('X', {0,0}, true,_COL_GREEN); + while(1) { b.moveObject(i, {2 * dir1, 1 * dir2}, _MOVE_RELATIVE); b.write(); + a.drawText(to_string(framecounter), {0,0}, _COL_RED); a.render(); - usleep(10*1000); if(x.getPosition().x <= 0) dir1 *= -1; @@ -40,8 +44,12 @@ int main() dir2 *= -1; x.setPosition({x.getPosition().x, a.getSize().y}); } - } - a.render(); + framecounter++; + //cin.get(); + usleep(100*1000); + //for(unsigned int i = 0; i < 6000; i++) + //for(unsigned int o = 0; o < 3000; o++); + } return 0; } -- cgit v1.2.3