PDA

View Full Version : TileMap showing artefact when scaling



blep
01-10-2014, 10:24 PM
Hi, I'm a new comer to clanlib.

I've played around with the TileMap example, and I've run into display artefact when uncommenting the line that allow zooming (a factor of 20.0 is used in the image below). From the test I did with tiles, it seems to be caused by lack of texture clamping to the rect that was given when adding the frame to the tile sprite.

Is there any way to force this clamping?

24242

rombust
01-11-2014, 08:56 PM
Quick fix:
In TileMap::load()

After: sprite_tiles = ...
Add: sprite_tiles.set_linear_filter(false);

(See http://www.rtsoft.com/forums/showthread.php?4302-Bug-when-I-draw-a-set-of-sprites )

If you don't want to turn off linear filtering, there is another option:

For each image, you repeat the border pixel (outside the image rect).

GUIThemeAeroPacked is created using this method. Since GUIThemeAero uses images as single files, held in Sprite/Image resource files, you can use the "Utilities/TexturePacker" on Microsoft Windows (i'm not sure if it's working on linux).

For my own code, I manually build sprites using this method:
1) Load the PNG contain the tiles into clan::PixelBufer
2) Construct a clan::TextureGroup
3) For each image in the PNG PixelBuffer...
4) Use PixelBufferHelp::add_border() to add the border
5) Call TextureGroup add() to obtain a clan::SubTexture to write into
6) Write into subtexture.get_texture() the pixelbuffer with the added border
7) Insert the subtexture.get_texture() into the sprite using clan::Sprite's add_frame() (Remember to use the correct image rect, excluding the border pixels)

Ideally ClanLib should do that automatically, but it's not an easy task to get correct, and to keep everybody happy.

I use TextureGroup is a single resource in my apps, shared by all Sprite's, that increases optimisation for ClanLib's internal batchers.

I believe you can also create an OpenGL shader that does the same. But it will not work with clan::Sprite or clan::Image

The last option is using glTextureView ( http://www.opengl.org/sdk/docs/man/xhtml/glTextureView.xml ), but that's OpenGL 4.3. C:\Development\ClanLib\Sources\GL\GL3\gl3_texture_ provider.cpp hints at supporting it (a constructor calls glTextureView), but I have never tried it.

blep
01-12-2014, 01:44 PM
Quick fix:
In TileMap::load()

After: sprite_tiles = ...
Add: sprite_tiles.set_linear_filter(false);

(See http://www.rtsoft.com/forums/showthread.php?4302-Bug-when-I-draw-a-set-of-sprites )


Thanks for pointed out the correct way to do this. I've tried it but was callings set_linear_filter() before adding frame. This had no effect.


Quick fix:
If you don't want to turn off linear filtering, there is another option:

For each image, you repeat the border pixel (outside the image rect).

GUIThemeAeroPacked is created using this method. Since GUIThemeAero uses images as single files, held in Sprite/Image resource files, you can use the "Utilities/TexturePacker" on Microsoft Windows (i'm not sure if it's working on linux).

For my own code, I manually build sprites using this method:
1) Load the PNG contain the tiles into clan::PixelBufer
2) Construct a clan::TextureGroup
3) For each image in the PNG PixelBuffer...
4) Use PixelBufferHelp::add_border() to add the border
5) Call TextureGroup add() to obtain a clan::SubTexture to write into
6) Write into subtexture.get_texture() the pixelbuffer with the added border
7) Insert the subtexture.get_texture() into the sprite using clan::Sprite's add_frame() (Remember to use the correct image rect, excluding the border pixels)

Ideally ClanLib should do that automatically, but it's not an easy task to get correct, and to keep everybody happy.

I use TextureGroup is a single resource in my apps, shared by all Sprite's, that increases optimisation for ClanLib's internal batchers.

I believe you can also create an OpenGL shader that does the same. But it will not work with clan::Sprite or clan::Image

The last option is using glTextureView ( http://www.opengl.org/sdk/docs/man/xhtml/glTextureView.xml ), but that's OpenGL 4.3. C:\Development\ClanLib\Sources\GL\GL3\gl3_texture_ provider.cpp hints at supporting it (a constructor calls glTextureView), but I have never tried it.

I'll probably go with the add_border() approach as it will keep the art pipeline simple. I just love discovering high-level feature like TextureGroup and add_border() in clanlib. I was thinking of doing something like TextureGroup (but with a much simpler implementation). It's great to find it's already available!

Out of curiosity, what texture size can we use portably on modern PC? Last time I did some GPU stuff it was around 256x256 but that was a decade ago. Things have obviously changed a lot since then :D.

I'm blown away by the performance of the sprite batcher :hat:. For testing, I had my simple prototype code draw 152 000 sprites per frame (78 000 visible on screen) and I still get ~45 FPS! I do have fairly high-end PC though, and there is only 5 different sprite frames. Being able to draw way more than 10K sprites per frame will make life so much easier...

blep
01-12-2014, 01:51 PM
Quick fix:
In TileMap::load()

After: sprite_tiles = ...
Add: sprite_tiles.set_linear_filter(false);

(See http://www.rtsoft.com/forums/showthread.php?4302-Bug-when-I-draw-a-set-of-sprites )


Thanks for pointing out the correct way to do this. I've tried it but was callings set_linear_filter() before adding frame, it had no effect. This is a good quick fix for the time being.


Quick fix:
If you don't want to turn off linear filtering, there is another option:

For each image, you repeat the border pixel (outside the image rect).

GUIThemeAeroPacked is created using this method. Since GUIThemeAero uses images as single files, held in Sprite/Image resource files, you can use the "Utilities/TexturePacker" on Microsoft Windows (i'm not sure if it's working on linux).

For my own code, I manually build sprites using this method:
1) Load the PNG contain the tiles into clan::PixelBufer
2) Construct a clan::TextureGroup
3) For each image in the PNG PixelBuffer...
4) Use PixelBufferHelp::add_border() to add the border
5) Call TextureGroup add() to obtain a clan::SubTexture to write into
6) Write into subtexture.get_texture() the pixelbuffer with the added border
7) Insert the subtexture.get_texture() into the sprite using clan::Sprite's add_frame() (Remember to use the correct image rect, excluding the border pixels)

Ideally ClanLib should do that automatically, but it's not an easy task to get correct, and to keep everybody happy.

I use TextureGroup is a single resource in my apps, shared by all Sprite's, that increases optimisation for ClanLib's internal batchers.

I believe you can also create an OpenGL shader that does the same. But it will not work with clan::Sprite or clan::Image

The last option is using glTextureView ( http://www.opengl.org/sdk/docs/man/xhtml/glTextureView.xml ), but that's OpenGL 4.3. C:\Development\ClanLib\Sources\GL\GL3\gl3_texture_ provider.cpp hints at supporting it (a constructor calls glTextureView), but I have never tried it.

I'll probably go with the add_border() approach as it will keep the art pipeline simple. I just love discovering high-level feature like TextureGroup and add_border() in clanlib. I was thinking of doing something like TextureGroup (but with a much simpler implementation). It's great to find it's already available!

Out of curiosity, what texture size can we use portably on modern PC? Last time I did some GPU stuff it was around 256x256, but that was a decade ago. Things have obviously changed a lot since then :D.

I'm blown away by the performance of the sprite batcher :hat:. For testing, I had my simple prototype code draw 152 000 sprites per frame (78 000 visible on screen) and I still get ~45 FPS! I do have fairly high-end PC though, and there is only 5 different sprite frames. Being able to draw way more than 10K sprites per frame make life so much easier...

blep
01-12-2014, 06:17 PM
Thanks for pointing out the correct way to use sprite_tiles.set_linear_filter(). I've tried it but was callings set_linear_filter() before adding frame, it had no effect. This is a good quick fix for the time being.

I'll probably go with the add_border() approach as it will keep the art pipeline simple. I just love discovering high-level feature like TextureGroup and add_border() in clanlib. I was thinking of doing something like TextureGroup (but with a much simpler implementation). It's great to find it's already available!

Out of curiosity, what texture size can we use portably on modern PC? Last time I did some GPU stuff it was around 256x256, but that was a decade ago. Things have obviously changed a lot since then :D.

I'm blown away by the performance of the sprite batcher :hat:. For testing, I had my simple prototype code draw 152 000 sprites per frame (78 000 visible on screen) and I still get ~45 FPS! I do have fairly high-end PC though, and there is only 5 different sprite frames. Being able to draw way more than 10K sprites per frame make life so much easier...

sphair
01-12-2014, 06:38 PM
Out of curiosity, what texture size can we use portably on modern PC? Last time I did some GPU stuff it was around 256x256, but that was a decade ago. Things have obviously changed a lot since then :D.


4096x4096 is probably very safe to use these days.

blep
01-15-2014, 08:07 AM
Thanks for the info. That leave a lot of room to work with.