Tileset rendering

Started by
5 comments, last by Captain P 14 years, 1 month ago
Hello, everyone. I am making a (kinda) game engine, which uses a tileset (two of them per map) to render the background. The design is as follows: There's a Game_Map Object which holds the byte data for the map (loaded from file), and two Image objects containing tilesets, there is also other stuff, non-related to the drawing. The screen is 10x9 tiles wide (as on GBC), but the drawing is extended to 11x10 to allow smooth transition when moving the tilemap. The problem is that I use two for loops to draw each individual tile in place using ImageDraw() which copies the needed tile to the screen. This gets called 110 times (!), so I get only 6-7 fps, 8 on a good day. Now, I understand that this design plainly sucks, so I would like to ask, are there any other efficient ways to do that?
Advertisement
What language and framework are you using? How big are those tiles? Can you show us the relevant code?

After all, drawing 110 relatively small sprites on modern systems shouldn't be that heavy, so there's likely something else going on.
Create-ivity - a game development blog Mouseover for more information.
My hardware can render 100x100 tiles (2 texture mapped quads rendered with blending on top of each other) with 20 fps.
Maybe you bind textures for every single tiles, that can slow things down.
You should batch tiles by texture ID, or bake everything in one atlas texture, so you don't have to bind, just once, or once per frame.
I use VB.Net; tiles are 16x16 and packed in a tileset 128x1024 in size (that's 384 kB). Shrinking the tileset didn't help; and the problem seems to be the line where ImageDraw gets called, because removing it shoots the fps up 60 (rendering only the location message (map name which gets displayed in a box which floats away), which goes pretty damn smooth. As far as I understand objects, removing ImageDraw doesn't affect the Game_Map object holding the tilesets (2x128x1024), so... what could it possibly be? :confused:
Maybe you should render all the tiles first, then all the "location messages". (batch the different kinds of renderings)
And the 2 tilesets mean that you have to do some "switching" between the 2 sets per tile, am I right? I guess that switching slows things down.
Render the whole tile-map with the bottom tileset, then render the whole tile-map with the top tileset.
Quote:Original post by szecs
Maybe you should render all the tiles first, then all the "location messages". (batch the different kinds of renderings)
And the 2 tilesets mean that you have to do some "switching" between the 2 sets per tile, am I right? I guess that switching slows things down.
Render the whole tile-map with the bottom tileset, then render the whole tile-map with the top tileset.


Well, the location message gets drawn last, and removing it altogether changed nothing. Switching? Hurr... I tried removing the ifs, so the top tileset is used for rendering only, no luck.
Sub render (g as Graphics) Dim mp As Map = Me.GameTemp.CurrentMap        Dim x As Integer = Me.GameTemp.X        Dim y As Integer = Me.GameTemp.Y        For ix As Integer = 0 To 12            For iy As Integer = 0 To 11                Dim tile As Integer = 0                tile = mp.GetTile(x - 5 + ix, y - 5 + iy)                               Dim ex As Integer = Me.GameTemp.X * 16 - Me.GameTemp.TrueX                Dim ey As Integer = Me.GameTemp.Y * 16 - Me.GameTemp.TrueY                Dim rown As Integer = tile Mod 8                Dim row As Integer = Math.Floor(tile / 8)                Dim rtile As New Rectangle(rown * 16, row * 16, 16, 16)'the next line is simply the stripped down "render tile" thing. Still 7 fps.   g.DrawImage(mp.Tiles1, ix * 16 + ex - 16, iy * 16 + ey - 16, rtile, GraphicsUnit.Pixel)                            Next        Next         If Me.GameTemp.InfoTimer > 0 Then'this draws the location message, commented out for clarity            ' g.FillRectangle(New SolidBrush(GameTemp.WinColor), 8, GameTemp.InfoTimer - 28, 100, 28)            ' g.DrawRectangle(New Pen(GameTemp.WinBorderColor), 8, GameTemp.InfoTimer - 28, 100, 28)            ' g.DrawString(GameTemp.InfoText, New Font(GameTemp.FontName, GameTemp.FontSize, Fontstyle.Regular, GraphicsUnit.Pixel), New SolidBrush(GameTemp.FontColor), 16, GameTemp.InfoTimer - 24)           ' Me.GameTemp.InfoTimer -= 1        End Ifend sub
From what I can find on this DrawImage function is that it's just rather slow. It looks like you're using code that's geared towards GUI-based, event-driven applications. That often doesn't work well for games. You may want to look for a library or framework that's geared towards real-time graphical applications. I'm not familiar with VB.NET so I can't give you any suggestions though.

But really, something that can't even draw 110 16x16 sprites with decent performance just isn't suited for this kind of application.
Create-ivity - a game development blog Mouseover for more information.

This topic is closed to new replies.

Advertisement