Hi, I've recently been testing out scrolling tile maps in BlitzMax and have run into some problems and would appreciate some help.
When scrolling a tile map there are several options:
1) Lock the screen refresh rate to say 60Hz and scroll 1 pixel or more per frame (integer amounts only), and therefore you will be drawing at integer coordinates. This *does* look very smooth (like an Amiga) but you can't do this in windowed mode because you can't lock the refresh rate. Also if someone has set their video card to Force VSync Off then the game will run at a silly speed.
2) Use delta time or fixed rate logic and scroll by a floating point amount each frame. When drawing ROUND the coordinates. This works but the scrolling is a tiny bit jittery due to the rounding (moire effect) of the floating point coords. So basically OK (loads of PC games do this) but not great.
3) Same as 2 except *don't* round the coordinates. Let BlitzMax draw the tiles at floating point coordinates, which it can do - it just anti-aliases the whole tile to look like it's at a fractional coordinate. Lovely and smooth BUT where the tiles join they have a nasty flickering because the edge is anti-aliased to nothing (see my demo below). I tried adding a 1 pixel border to the tiles (this works for sprites) but it didn't make any difference to the tiles.
4) I had an idea to draw the entire screen on a pixmap and then draw than on the screen at a floating point coordinate, this should look nice as the whole thing will be anti-aliased and there won't be any dodgy tile edges. BUT this would most likely be very slow as drawing tiles to a pixmap and then uploading it to VRAM each frame wouldn't be quick at all (I think).
5) Indiepath suggested using a "mesh" but not being a 3D programmer I only have the vaguest notion of what he's on about. I gather all the tiles could be added to a mesh and then the mesh would be drawn and all the tile edges would blend in together nicely. This make sense and if it was a lot faster than pixmaps, then it's the way to go. But there are no "mesh" commands in BMax do I guess I'd have to go low level DX to get this sorted. However, I've no clue how to do that and that is what this thread is about. Does anyone have any suggestions of resources that may help, thanks! :-)
Anywhere here is a test app:
http://www.greyaliengames.com/misc/scrolltest.zip (685Kb)

You can see that I am moving the images across the screen by a floating point amount (I know there is no delta time, forget that for now). Things to note:
1) Note how the rectangles made with DrawRect are not anti-aliased at all (because the floating point coord is not taking into acount), I posted this in the bug forum. This is what drawing tiles at integer coords looks like, not very nice (i.e. all jiggly).
2) The first pair of tiles show the horrible join problem, see it flickering in the middle as they move? Also the right edge flickers badly.
3) The second pair are actually one large tile loaded in like that, and thus the join is perfect (it's what I imagine the pixmap or mesh method would look like).
4) The last pair are again one large tile but with a 1 pixel border all around to see if that helps the right edge problem, but it doesn't. The right edge problem is only because it's bright white, it will be occuring on the left edge too (and top/bottom if I was scrolling that way as well). Anyway, the edge problem wouldn't be an issue if you predrew the entire screen from tiles using a mesh. BUT it would be an issue if say you had a bitmap background and plonked square platforms on it, these platforms would have dodgy anti-aliasing on the edge, but I'm not sure there is any way around this at all...it's just the way it is.
Anyway, any help and viewpoints are greatly appreciated thanks in advance!
One thing, it's probably not worth trying to persuade me to go the route of option 1) as any games I write need a windowed mode. If I can't find a solution with meshes, then I need to decide on 2) integer jiggling or 3) tile edge flickering, neither of which is particularly great.
When scrolling a tile map there are several options:
1) Lock the screen refresh rate to say 60Hz and scroll 1 pixel or more per frame (integer amounts only), and therefore you will be drawing at integer coordinates. This *does* look very smooth (like an Amiga) but you can't do this in windowed mode because you can't lock the refresh rate. Also if someone has set their video card to Force VSync Off then the game will run at a silly speed.
2) Use delta time or fixed rate logic and scroll by a floating point amount each frame. When drawing ROUND the coordinates. This works but the scrolling is a tiny bit jittery due to the rounding (moire effect) of the floating point coords. So basically OK (loads of PC games do this) but not great.
3) Same as 2 except *don't* round the coordinates. Let BlitzMax draw the tiles at floating point coordinates, which it can do - it just anti-aliases the whole tile to look like it's at a fractional coordinate. Lovely and smooth BUT where the tiles join they have a nasty flickering because the edge is anti-aliased to nothing (see my demo below). I tried adding a 1 pixel border to the tiles (this works for sprites) but it didn't make any difference to the tiles.
4) I had an idea to draw the entire screen on a pixmap and then draw than on the screen at a floating point coordinate, this should look nice as the whole thing will be anti-aliased and there won't be any dodgy tile edges. BUT this would most likely be very slow as drawing tiles to a pixmap and then uploading it to VRAM each frame wouldn't be quick at all (I think).
5) Indiepath suggested using a "mesh" but not being a 3D programmer I only have the vaguest notion of what he's on about. I gather all the tiles could be added to a mesh and then the mesh would be drawn and all the tile edges would blend in together nicely. This make sense and if it was a lot faster than pixmaps, then it's the way to go. But there are no "mesh" commands in BMax do I guess I'd have to go low level DX to get this sorted. However, I've no clue how to do that and that is what this thread is about. Does anyone have any suggestions of resources that may help, thanks! :-)
Anywhere here is a test app:
http://www.greyaliengames.com/misc/scrolltest.zip (685Kb)

Strict Graphics 800,600,0 Local x# = 0 Local y#=50 Local speed#=0.23 Local size=64 Local tiles1:TImage = LoadImage("tiles1.png") Local tiles2:TImage = LoadImage("tiles2.png") Local tiles3:TImage = LoadImage("tiles3.png") While Not KeyHit(KEY_Escape) SetBlend AlphaBlend Cls 'rectangles SetColor 200,200,200 DrawRect x,y,size,size SetColor 200,100,100 DrawRect x+20,y+20,20,20 SetColor 100,100,100 DrawRect x+size,y,size,size 'two images SetColor 255,255,255 DrawImage tiles1,x,y+100 DrawImage tiles1,x+size,y+100 'single combined image DrawImage tiles2,x,y+200 'draw tile with 1 pixel border DrawImage tiles2,x,y+300 'move x:+speed DrawText x,0,0 Flip 1 Wend
You can see that I am moving the images across the screen by a floating point amount (I know there is no delta time, forget that for now). Things to note:
1) Note how the rectangles made with DrawRect are not anti-aliased at all (because the floating point coord is not taking into acount), I posted this in the bug forum. This is what drawing tiles at integer coords looks like, not very nice (i.e. all jiggly).
2) The first pair of tiles show the horrible join problem, see it flickering in the middle as they move? Also the right edge flickers badly.
3) The second pair are actually one large tile loaded in like that, and thus the join is perfect (it's what I imagine the pixmap or mesh method would look like).
4) The last pair are again one large tile but with a 1 pixel border all around to see if that helps the right edge problem, but it doesn't. The right edge problem is only because it's bright white, it will be occuring on the left edge too (and top/bottom if I was scrolling that way as well). Anyway, the edge problem wouldn't be an issue if you predrew the entire screen from tiles using a mesh. BUT it would be an issue if say you had a bitmap background and plonked square platforms on it, these platforms would have dodgy anti-aliasing on the edge, but I'm not sure there is any way around this at all...it's just the way it is.
Anyway, any help and viewpoints are greatly appreciated thanks in advance!
One thing, it's probably not worth trying to persuade me to go the route of option 1) as any games I write need a windowed mode. If I can't find a solution with meshes, then I need to decide on 2) integer jiggling or 3) tile edge flickering, neither of which is particularly great.