Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Which way to go for scaling graphics?  (Read 2411 times)

0 Members and 1 Guest are viewing this topic.

wo

  • Newbie
  • *
  • Posts: 2
    • View Profile
Which way to go for scaling graphics?
« on: August 06, 2015, 02:55:14 am »
Hi. I have a simple map renderer which uses a vertex array and a spritesheet. I also have a camera class which feeds the renderer with precalculated amounts of horizontal and vertical tiles which can be seen with the current resolution. My base resolution (resolution which the sprites are made for) is 1080 px height and my map cell is 45 px height. So for example when I run a 640 x 480 px window there are rendered 32 x 24 tiles. But this is not really important. The problem is when using a vertex array and scaling the quad positions. It's important to say that I am using setSmooth(true) on my spritesheet texture and forcing roundf() inside quad position parameters so they are integrals.

quad[0].position = sf::Vector2f(roundf((x * cellDimension.x) * scale), roundf(verticalPositionInWindow * scale));
quad[1].position = sf::Vector2f(roundf((x * cellDimension.x + frameDimension.x) * scale), roundf(verticalPositionInWindow * scale));
quad[2].position = sf::Vector2f(roundf((x * cellDimension.x + frameDimension.x) * scale), roundf((verticalPositionInWindow + frameDimension.y) * scale));
quad[3].position = sf::Vector2f(roundf((x * cellDimension.x) * scale), roundf((verticalPositionInWindow + frameDimension.y) * scale));

It works great without any artifacts when downscaling from 1080 px or simply the scale value is <= 1.0. There are no glitches and black lines or any sprite bleedings. However when upscaling from 1080 px or simply the scale value is > 1.0 there are black lines drawn onto the screen, white lines, sprite bleeding. Probably you know what I mean, it's a common problem with bilinear scaling method, so when I have the quad set to a greater size than texture piece size it becomes strangely interpolated causing artifacts and glitches. I tried to add padding to my spritesheet but still at best I ended with grey lines between tiles.

Another way which I wanted to try is to create a 1080 px in height RenderTexture. The vertex array is drawn simply without scaling onto this texture, then the sprite with this texture is scaled to any value I want and finally this sprite is drawn to the window. The result is the same as previously but there are no artifacts and glitches since this is just a prerendered texture, single image which I can transform freely without this spritesheet interpolation mess.

Which way should it be done properly? I think that rendering a texture with a size of base resolution isn't good idea considering performance. But this way it just works. If I want to go with first solution it will be surely way faster but I don't know how to solve upscaling problem with spritesheet.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Which way to go for scaling graphics?
« Reply #1 on: August 06, 2015, 12:56:39 pm »
It's important to say that I am using setSmooth(true) on my spritesheet texture
This is almost certainly the reason behind the artifacts.
Smoothing takes into account the pixels around the pixel that it's interested in. When it's interested in a pixel at the edge, it takes into account the pixels past its edge.

I tried to add padding to my spritesheet but still at best I ended with grey lines between tiles.
Which type of padding? Black, grey, white, transparent? Probably the best padding is to extend the edge of that sprite/tile so that its neighbouring pixels are the same.
For example, this 16x16 tile:

would look like this after padding (18x18):
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

wo

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Which way to go for scaling graphics?
« Reply #2 on: August 06, 2015, 02:10:32 pm »
I know about extending borders around tiles but I just realised that the problem was stupidly exactly due to an empty tile which was the one without any spacing and there was an unused tile directly next to it in the spritesheet so the edge was mixed with another color. Thank you and sorry for trouble :)