Upscalling a tilemap


sebt3

homebrew player (P. & C.)
Joined
Sep 9, 2008
Messages
4,886
Age
43
Location
France
Website
sebt3.openpandora.org
Hi there,


I want my next game to play the same on the caanoo and pandora. As you (might) know, the caanoo have a 320x240 res.


So I'm planning for a game that can play in that resolution up to 400x240 (I'll find something to do with these extra pixels) and plan on scalling up for the pandora.


So for testing I'm building a test tilemap (randomly generated) and scale use the projection matrix :



Code:
glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(EGE_viewport.cur[0], EGE_viewport.br[0], EGE_viewport.br[1], EGE_viewport.cur[1], 1, -1);

EGE_viewport.cur to EGE_viewport.br is always 400x240 while the viewport is 800x480 obviously.


Here the result :


tilemap.png



that's blurry, so let's scale the texture 2x before hand :


tilemap2x.png



And everything is like the plan.... beside these nasty vertical lines.


when not scaled, these lines arent there, I even tryed to blit 22x22 square every 20px to be sure to overlap, and these lines are still there.


So guys, what am I missing ? Is there a way to remove these ?
 
Are you modifying textures manually? Else you could use glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); Its set to LINEAR as standard wich interpolates smoothly between pixels, NEAREST repeats the nearest source between pixels.


Dont know what is the cause of the lines, can you post more code?
 
Some other options..


.. can you dynamicly handle screen size? ie: scale up in natural 2x2 etc, and clip off the excess? or show more or less tiles in the game, without impacting gameplay?


ie: If its showing a map in a wargame for instance, you can easily show show more or less, and it doesn't really matter (unless a competitive head to head, then one player has an advantage and you have to artificially clip the other to equalize.)


Or a second set of artwork for each platform, in scales of 1.5 or 2 or whatever, hand done, and use #define's in your code for TILE_WIDTH and TILE_HEIGHT, and then set that at compile time. I did that for a few games.. a #defimne to specify which artwork-set, and that in turn sets paramters and filenames and so on, and poof, good to go. ie: Do the time in artwork in gimp, not in code in real time. (Also, runs faster when not hardware assisted, but you don't have that problem.)


sebt3 -- you got a fancy little 2d GL library building up? using cpasjuste's GLES2d lib? or just hand coding each time?


jeff
 
Are you modifying textures manually?
Once uploaded into the sgx, I dont touch them (beside for a bind once in a while.... well my test only upload 1 texture. so no more bind ;P)


I think you might have this problem with sub pixels:
http://gamedev.stack...el-translations
Yep, that's it. I'll need to read up about that. Thanks for the link ;)


EDIT: fixed, thanks.


I was using this when loading the texture :



Code:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

while this was more suited :



Code:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

EDIT2: but that's not enough for the pandora :(

sebt3 -- you got a fancy little 2d GL library building up? using cpasjuste's GLES2d lib? or just hand coding each time?
Build from scratch, starting from the ashes of panmines (changing what's wrong keeping the only good idea ;P)


It's not aimed at becoming a library, but more the base engine of my (hopefully) coming games.


But like always the goal is still to learn things ;)
 
Last edited by a moderator:
Also one thing i remember reading for pixel perfect placement the modelview needs to be first translated 0.675, 0.675, 0 first, maybe that would align the textures.
 
IIRC for pixel perfect 2d sprites (tiles) you need to adjust all the texture co-ords from (x,y) to ( (0.5/TexWidth)+(x/TexWidth), (0.5/TexHeight)+(y/TexHeight) ) where x & y are integers from 0,0 to (TexWidth-1),(TexHeight-1).
 
Overlapping the tiles and making the tiles themselves bigger will not solve this as you have found.


You need to modify the tx coords a little:


Instead of 0.0 and 1.0 try 0.01 and 0.99 or something like that.


Incidentally here is what seems to work for me in Penjin: http://code.google.com/p/penjin/source/browse/trunk/Image.cpp#402
 
I finally got it fixed ...


Say :



Code:
A   	B

  +---+

   | 	|

  +---+

C   	D

then the texcoord have to be :


A ( ((x+0.1)/TexWidth), ((y+0.1)/TexHeight) )


B ( ((x-0.1)/TexWidth), ((y+0.1)/TexHeight) )


C ( ((x+0.1)/TexWidth), ((y-0.1)/TexHeight) )


D ( ((x-0.1)/TexWidth), ((y-0.1)/TexHeight) )
 
Is it just me that thinks not mapping texture coords to the quads coords utterly stupid and totally counter-intuitive?
 
from my engine, OpenGL module:



Code:
void GPU_Camera_Platform::SetProjectionToPixels(uint width, uint height)

{

	CAMERA_MATRIX m;

	m.LoadIdentity();

	m[0][0] = 2.0f / width;

	m[1][1] = -2.0f / height;	

	m[3][0] = -1.0f + (-0.375f / width);

	m[3][1] = 1.0f + (-0.375f / height);

	projection = m;

}





the UV matrix needs to be set to:



Code:
glMatrixMode(GL_TEXTURE);

glLoadIdentity();

glScalef(gl_tex->opengl_texture.size_inverse[0] * tile_width, gl_tex->opengl_texture.size_inverse[1] * tile_height, 1.0f);


this way you can use GL_UNSIGNED_BYTE for tile UVs


you must use tiles sizes that are a power of two (2 ** N) or you will get rounding errors if you ever do scaling and/or rotation and gaps may show up.


and you need to put a repeated border around your tiles inside the texture if you want to use interpolation and for this you will need a different GL_TEXTURE matrix but this looks ugly.


the best for interpolation of a tile map is to, instead, software-render the tile map to a single texture and draw a single quad covering the whole screen this way it will interpolate between the tiles correctly.


you can do partial texture updates as the map is scrolled and/or tiles are animated.


and pre-process the scale2x.
 
Back
Top