Not logged inGosu Forums
Forum back to libgosu.org Help Search Register Login
Up Topic Gosu / Gosu Exchange / [ruby/optim] How to update the modified sprites only?
- By Gavos Date 2010-02-26 02:18
Hi everyone,

As part of a 9-day game development contest (finishing the 28th), I am creating a game (with RubyGosu) that simulates a battle between two swarms of microbs trying to conquier a Petri dish. You can get an idea here: http://gavos.free.fr/volatil/petri3.png

Now I am running into problems with performance. On this screenshot the battle is far from finished, a Petri dish full of microbs would run around 15 FPS. And there is no gameplay logic (on this screenshot) or AI neither...

The way I implemented this was as follow:
- loop through the list of colour squares that are on the field
- draw every square using Gosu::Image.draw

The field is 800x600 large and the squares are 8-pixel large, so I might have to draw up to 7500 images per frame... You can find the code responsible for the graphics here: http://gavos.free.fr/volatil/petri.rb

What I would like to do is:
- loop through the list of colour squares that have been updated at this turn
- only draw those squares on top of the existing screen

Is there any way to do that with Gosu? I am aware of what that technique involves when using double (triple?) buffering but I am kind of desperate, I do not have any other idea for optimisation now. I know it would reduce the number of squares to draw enough to stay over 40 FPS (without game logic / AI). If you think of any other way to optimise that would be great as well :-)  I have started programming in Ruby at the beginning of this week (I am more of a C++ programmer), so there might be obvious ruby-ish optimisations left to do.

There is nothing to win in the contest but I would be disapointed to publish a game that is hardly playable...

Thanks a lot for your answers :-)
- By erisdiscord Date 2010-02-26 03:21
Gosu doesn't provide a way to update only part of the screen as far as I know—you draw everything each turn. I'm pretty sure this is the nature of OpenGL, which is ultimately what you're using behind the scenes.

You could try looking at TexPlay to dynamically modify a single WidthTab by HeightTab texture after each update, paint the pixels corresponding to the changed cells, then draw that single texture to the screen on every draw. I haven't used TexPlay myself, but it should be fast enough to do what you want provided that you do all your texture painting in the same Image#paint block.
- By jsb Date 2010-02-26 09:57
When encountering performance problems with Ruby, I generally suggest using only Integers for computation, ;) but seems you're already doing that. From looking at the code structure, I don't see any room for improvements.
From browsing through the Gosu source I see there is a parameter to Graphics::begin that lets you specify a clear color, although it seems begin is always called internally with its default parameter, Color::BLACK, with no way to change this default value from outside.

Only thing I can think of now would be some OpenGL hacks, i.e. drawing to off-screen textures etc, or trying out banister's TexPlay library.
- By jlnr (dev) Date 2010-02-26 11:57
If the clear color is transparent you will have the weirdest effects due to double-buffering etc... yeah, OpenGL is made to redraw everything every frame :)

I'd also recommend TexPlay. It's pretty close to what I would do with raw OpenGL too I guess.
- By Gavos Date 2010-02-26 22:09
Thanks a million to all of you, this lib is great! And even better, it does not bloat my code at all! And even *more* better, I can decrease the size of my squares!

The proof: http://gavos.free.fr/volatil/petri5.png

If the result happens to be interesting (not quite sure yet, it is kind of an experiment), I will add it to the Showcase forum :-)

Thanks again!
Up Topic Gosu / Gosu Exchange / [ruby/optim] How to update the modified sprites only?

Powered by mwForum 2.29.7 © 1999-2015 Markus Wichitill