How to use caching to increase render performance?
Posted
by
Christian Ivicevic
on Game Development
See other posts from Game Development
or by Christian Ivicevic
Published on 2012-09-09T09:59:32Z
Indexed on
2012/09/09
15:50 UTC
Read the original article
Hit count: 611
First of all I am going to cover the basic design of my 2d tile-based engine written with SDL in C++, then I will point out what I am up to and where I need some hints.
Concept of my engine
My engine uses the concept of GameScreen
s which are stored on a stack in the main game class. The main methods of a screen are usually LoadContent
, Render
, Update
and InitMultithreading
. (I use the last one because I am using v8 as a JavaScript bridge to the engine.
The main game loop then renders the top screen on the stack (if there is one; otherwise, it exits the game) - actually it calls the render methods, but stores all items to be rendered in a list. After gathering all this information the methods like SDL_BlitSurface
are called by my GameUIRenderer
which draws the enqueued content and then draws some overlay. The code looks like this:
while(Game is running) {
Handle input
if(Screens on stack == 0) exit
Update timer etc.
Clear the screen
Peek the screen on the stack and collect information on what to render
Actually render the enqueue screen stuff and some overlay etc.
Flip the screen
}
The GameUIRenderer
uses as hinted a std::vector<std::shared_ptr<ImageToRender>>
to hold all necessary information described by this class:
class ImageToRender {
private:
SDL_Surface* image;
int x, y, w, h, xOffset, yOffset;
};
This bunch of attributes is usually needed if I have a texture atlas with all tiles in one SDL_Surface
and then the engine should crop one specific area and draw this to the screen.
The GameUIRenderer::Render()
method then just iterates over all elements and renders them something like this:
std::for_each(
this->m_vImageVector.begin(),
this->m_vImageVector.end(),
[this](std::shared_ptr<ImageToRender> pCurrentImage) {
SDL_Rect rc = { pCurrentImage->x, pCurrentImage->y, 0, 0 };
// For the sake of simplicity ignore offsets...
SDL_Rect srcRect = { 0, 0, pCurrentImage->w, pCurrentImage->h };
SDL_BlitSurface(pCurrentImage->pImage, &srcRect, g_pFramework->GetScreen(), &rc);
}
);
this->m_vImageVector.clear();
Current ideas which need to be reviewed
The specified approach works really good and IMHO it is really has a good structure, however the performance could be definitely increased. I would like to know what do you suggest, how to implement efficient caching of surfaces etc so that there is no need to redraw the same scene over and over again?
The map itself would be almost static, only when the player moves, we would need to move the map. Furthermore animated entities would either require updates of the whole map or updates of only the specific areas the entities are currently moving in. My first approaches were to include a flag IsTainted
which should be used by the GameUIRenderer
to decide whether to redraw everything or use cached version (or to not render anything so that we do not have to Clear
the screen and let the last frame persist). However this seems to be quite messy if I have to manually handle in my Render
method of the screen class if something has changed or not.
© Game Development or respective owner