SFML community forums

Help => Graphics => Topic started by: irri on December 23, 2008, 01:48:00 pm

Title: Optimizing tile-grid drawing
Post by: irri on December 23, 2008, 01:48:00 pm
Hello!

I'm working on a tilebased game, 480x288px, each tile is 32x32 ==> 15x9 tiles = 135 tiles on screen at the same time.

On my computer (Intel Pentium Core2Duo 3.0 GHz) the process takes around 5-8 % of my CPU. (I'm running Ubuntu, if that makes any sense)

A few days ago I tried to run the application on my laptop (Intel Pentium M 1.3GHz, also Ubuntu) and then the process of the game took around 50-80 % of the CPU!

I came to the conclusion that my draw-code couldn't be very optimized.
I use only one sprite, and changes the image every draw-loop if it is needed.

Here is my Draw method:
Code: [Select]
void Tilegrid::DrawTiles(sf::RenderWindow & App, const Character & player)
{
// Calculate the tiles the player is within range, plus an extra offset
int extra_offset = 1;

int Xa = int( -0.5f+((float)player.GetPosition().x-(float)GameEngine::WINDOW_WIDTH/2)/(float)GameEngine::TILE_WIDTH ) -extra_offset;
int Xb = int( 0.5f+((float)player.GetPosition().x+(float)GameEngine::WINDOW_WIDTH/2)/(float)GameEngine::TILE_WIDTH ) +extra_offset;

int Ya = int( -0.5f+((float)player.GetPosition().y-(float)GameEngine::WINDOW_HEIGHT/2)/(float)GameEngine::TILE_HEIGHT ) -extra_offset;
int Yb = int( 0.5f+((float)player.GetPosition().y+(float)GameEngine::WINDOW_HEIGHT/2)/(float)GameEngine::TILE_HEIGHT ) +extra_offset;

// If the variables isn't in range, make them so.
(Xa < 0) ? Xa=0 : 0;
(Xb > gridsize.x) ? Xb=gridsize.x : 0;
(Ya < 0) ? Ya=0 : 0;
(Yb > gridsize.y) ? Yb=gridsize.y : 0;

int imgNr = -1;
for(int i=Xa; i<Xb; i++)
{
for(int j=Ya; j<Yb; j++)
{
// Set position
mySprite.SetPosition(i*GameEngine::TILE_WIDTH, j*GameEngine::TILE_HEIGHT);

// If a secondary img is available. Draw it underneath the main one.
if (grid[j][i].GetImage2() != -1)
{
mySprite.SetSubRect( grid[j][i].GetRect2() );
App.Draw(mySprite);
}

// new_imgNr is for optimizing.
// It don't have to re-GetRect if the same img was used last tile.
// This doesn't apply if a secondary image is used.
int new_imgNr = grid[j][i].GetImage();
if (imgNr != new_imgNr || grid[j][i].GetImage2() != -1)
{
imgNr = new_imgNr;
mySprite.SetSubRect( grid[j][i].GetRect() );
}

// Draw main sprite
App.Draw(mySprite);
}
}
}


It must be another way, more CPU friendly. Any ideas?

Thanks
Philip Irri

edit: oh, I just noticed there was another thread discussing this.. oh well
Title: Optimizing tile-grid drawing
Post by: jdindia on December 24, 2008, 06:23:47 am
Your code looks fine.  I'd check other parts of your program.  A few hundred tiles should get drawn quickly.
Title: Optimizing tile-grid drawing
Post by: irri on December 24, 2008, 10:52:34 am
Quote from: "jdindia"
Your code looks fine.  I'd check other parts of your program.  A few hundred tiles should get drawn quickly.


It is those lines of codes that makes the process work so hard.
If I remove the whole DrawTiles, the CPU goes down to 0-1 % on my laptop.

It seems that the sf::RenderWindow::Draw is the one who causes the bad performance.
Because if I remove all but the Draw-line the CPU is still around 50-80%.

Code: [Select]
void Tilegrid::DrawTiles(sf::RenderWindow & App, const Character & player)
{
for(int i=0; i<20; i++)
{
for(int j=0; j<20 j++)
{
// Draw main sprite
App.Draw(mySprite);
}
}
}
Title: Optimizing tile-grid drawing
Post by: jdindia on December 26, 2008, 03:57:38 pm
Hrmm.  Do you have a really bad graphics card on your laptop?

Also, I'm not sure you can really use cpu use as a metric for optimizing.  If you aren't doing any other background tasks, your game should be using all of the CPU.  A better measure would be framerate.
Title: Optimizing tile-grid drawing
Post by: heishe on December 27, 2008, 10:50:50 pm
it doesnt matter how much % it takes away. just make sure your frames ps stay high.
Title: Optimizing tile-grid drawing
Post by: irri on December 27, 2008, 10:59:42 pm
Quote from: "heishe"
it doesnt matter how much % it takes away. just make sure your frames ps stay high.

Ok, well, they don't.  :?
It is the Draw-method which takes the FPS down. hmm..