rendering tiles w/ static render method

I’m not sure how to go about rendering tiles “properly”, if I were to create each tile as an individual object and call its render method – the game’s fps would drop dramatically (to about 20fps or so)

at line 76:
https://github.com/codecub/slicktest/blob/master/tribelife/src/Slick.java
(tile rendering method)

see Grass.java:
https://github.com/codecub/slicktest/blob/master/tribelife/src/Grass.java

so yeah: “Is there a better way to render tiles individually?”

I believe the problem lies in the fact that whenever I create an object out of a grass tile, calling “different rendering methods” (different objects w/ same render method, new instance) really slows down the rendering altogether

should I just create a static render method? how will it then take into account individual tile object data (x, y etc)?

http://puu.sh/ze5Z

(21x15, 27*27 tile size)

and yeah, I know slick2d contains a tilemap library (but still)

Haven’t had a chance to look through the code, but these are the two common performance killers for tile maps:

  • Are you using an Image.draw call per tile? If so, try using Image.startUse/drawEmbedded/endUse instead. Performance should improve a lot. Image.draw exists as a convenience which does (more or less) the following:
image.startUse();
image.drawEmbedded(...);
image.endUse();

To improve performance, I’d suggest using startUse/drawEmbedded/endUse as much as possible. It works on an a single texture (i.e. the backing OpenGL texture); so even if you’re using multiple sub-images, scaled copies, etc. you will still be able to draw them all in the same “batch.” In theory, your entire game could be rendered in the same startUse/endUse as long as it’s all contained on the same sprite sheet. So your tile renderer might look more like this:

grassSprite.startUse();
for (.. rows ..)
    for (.. columns ..)
        grassSprite.drawEmbedded( ... );
grassSprite.endUse();

Just a note; if you want to render a different texture, or change the blend mode, or change the transform (translate/scale/etc), or what have you, you’ll need to first “flush” it by calling endUse(), then change the state, then start again with startUse().

  • Are your game tiles contained in a sprite sheet? If not, this can be another source of performance loss.

If you fix those you should be able to render thousands of tiles per frame with no performance loss!

More info here:
http://slick.cokeandcode.com/wiki/doku.php?id=performance_memory_tips

thanks for the tips, but I tried using startUse(), drawEmbedded() and endUse() but I still get some fps drops

it’s not so much that I’m receiving low fps at the moment with my current rendering technique but the fact that if I want to call multiple render methods for every tile as an “object” the fps will drop insanely

I took a browse through the code. Some other things which you should fix:

  • You only need to set the filter (linear or nearest) once. Ideally you should set it at image initialization. Setting it before you render every font glyph and tile can cause a significant drop in performance. NB: the filter only applies to the backing ‘texture’ of an image; so changing the filter of a sub-image will affect all other sub-images that point to the same backing texture.
  • SpriteSheet.getSubImage(int, int, int, int) creates a new image when called – you should generally avoid using it per frame (it seems you’re using it in your glyph class).
    [li]As suspected, your tile and font rendering relies on Image.draw – use drawEmbedded instead.

Setting the filter each render and not using drawEmbedded seem to be the main culprits in your code. Try fixing those and report back with the new FPS. (Obviously it will drop significantly as soon as you start rendering some images.)

Have you read much about design patterns? You use some very weird standards that will make debugging your application a lot more difficult. :o

thanks! I’ll try to see what I can do and report back

(especially about the design patterns bit)

changing the filter calls worked

(now I get max fps)

:wink: