SFML community forums
Help => Graphics => Topic started by: interdpth on January 03, 2011, 12:29:31 am
-
Basically what I need to do is copy a whole bunch of small rects from Image B to Image A. I'm currently using Image::copy() to do it, it works but it is oh so very slow, so I'm hoping someone could show me a faster way to do it then what I have?
If so thank you so much.
tileset and tmp are both sf::Image
for (; y < ey; y++)
{
sx = -(ScrollX & (TileSize - 1)) + (2 * TileSize);
//x = ScrollX & (TileSize - 1);
x = ScrollX / TileSize;
ex = x + (ScreenWidth / TileSize) - 4;
//pc = &(BG[ (ScrollX / TileSize) ][y]);
for (; x < ex; x++)
{
tile = MainLayer[y][x] & 0xFF;
if (tile)
{
//MessageBox(0, "non-zero tile!", "blah", 0);
r.Left = (tile & 15) * TileSize;
r.Top = (tile / 16) * TileSize;
r.Width = r.Left + TileSize;
r.Height = r.Top + TileSize;
if(!(sx<0 || sy<0))
tmp.Copy(tileset,sx,sy,r,1);
}
sx += TileSize;
}
sy += TileSize;
}
-
Image::Copy is slow yes. It's meant for composing images at initialization time, not at rendering time. Sprites will always be faster to render, even if there are a lot of them and if they are static.
-
Ok...So what would be a better way to copy the images I need to copy during runtime? I'm using SMFL2 btw
-
SFML 2? Then use sf::RenderImage!
But can't you draw them directly? Is it too slow?
-
I currently copy to a renderimage now...
But Image 2 is image made up of 32x32 tiles, which I then copy to image A based on an index for each tile, I'm working on a game engine so this is kind of needed lol
-
I currently copy to a renderimage now...
And? Is it ok?
But Image 2 is image made up of 32x32 tiles, which I then copy to image A based on an index for each tile, I'm working on a game engine so this is kind of needed lol
Have you tested first, before saying it is needed? ;)
-
I'm getting the same FPS as I did when I didn't use renderimage unless I'm using it wrong.
Can you show me the proper way?
-
I'm getting the same FPS as I did when I didn't use renderimage unless I'm using it wrong.
Can you show me the proper way?
Can you show me how you use it? ;)
It must be used exactly like a RenderWindow, it's the same thing except that it renders to an image rather than to a window.
-
I changed from the copy to using sprites
So my draw code is like this
for (; x < ex; x++)
{
tile = MainLayer[y][x] & 0xFF;
if (tile)
{
//MessageBox(0, "non-zero tile!", "blah", 0);
r1.Left = (tile & 15) * TileSize;
r1.Top = (tile / 16) * TileSize;
r2.Left = sx;
r2.Top = sy;
if(sx>0&&sy>0){
tmpSpr.SetImage(tileset);
tmpSpr.SetSubRect(r1);
tmpSpr.SetPosition(sx,sy);
bbImage.Draw(tmpSpr);
}
}
sx += TileSize;
}
sy += TileSize;
}
Then when I draw
bbImage.Display();
sf::Sprite bbS(bbImage.GetImage());
App.Draw(bbS);
App.Display();
bbImage is the RenderImage
-
Looks good. And this is still not ok?
-
I notice you set the image for the sprite inside your inner loop, and your sprite is named "tmpSpr", leading me to wonder if you are creating a new local sf::Sprite every frame. Create the sprite and set it's image upon initializing your game, then don't do anything every frame except setting the SubRect and Position and Drawing it. Same for the final drawing: don't do
sf::Sprite bbS(bbImage.GetImage());
Instead, make sf:Sprite bbS on app initialization, then in the renderer do:
bbS.SetImage(bbImage.GetImage());
You could play around with it; I'm not sure of the behaviour of RenderImages, and even calling GetImage() every frame may not be necessary. Try just calling it at initialization as well. The less you do in our renderer, the better!