SFML community forums

Help => Graphics => Topic started by: Octav on July 21, 2013, 09:57:51 pm

Title: [SOLVED] Strange distortion bug when zooming with a sf::View
Post by: Octav on July 21, 2013, 09:57:51 pm
SOLUTION IS ON PAGE 3

I have had this bug for a while, but all my attempts to fix it have been null. I have a simple sf::View set up as a member of the player class, and here's some bits of code:

Game.cpp:
player -> Camera = window.getDefaultView();

Player.cpp:

void Player::updateCamera()
{
        Camera.setCenter(pos); // pos is the position of the player
}

However when I zoom in the game, some pixels look distorted, you can see thin lines, wave pattern at the floor where there's only straight lines, etc.

(http://puu.sh/3I7zE)
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Laurent on July 22, 2013, 08:02:29 am
It's hard to keep a pixel perfect rendering in this case: your world units no longer match the window's pixels, so OpenGL has to distort things to compensate.

There's no easy workaround, unfortunately. What you can do is to try different sizes for your view, and maybe you'll notice a rule for sizes that produce artifacts (typically, that would be non-integer or odd sizes), and avoid them.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 22, 2013, 11:24:43 am
It's hard to keep a pixel perfect rendering in this case: your world units no longer match the window's pixels, so OpenGL has to distort things to compensate.

There's no easy workaround, unfortunately. What you can do is to try different sizes for your view, and maybe you'll notice a rule for sizes that produce artifacts (typically, that would be non-integer or odd sizes), and avoid them.

I see, would there be any drastic change that I could do to keep a certain ratio in things? Surely someone must have had this problem before or there must be a cause
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 22, 2013, 06:27:59 pm
I forgot an important detail, which could be the problem!

My tiles are all 30x30. I'll try to make them 32x32 and get back to this thread to post the solution.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: G. on July 22, 2013, 07:20:23 pm
Distortions are unavoidable.
If your tiles are 32*32, when you zoom they are maybe displayed as 38*38, that's 6 rows and columns of new pixels so obviously the pixel patterns can't be the same.

You could allow only zoom values that keeps the pixel ratio where 32*32 tiles would become 64*64, then 96*96, etc. Pixel patterns would stay intact.

Or you could try to smooth them (using sf::Texture::setSmooth (http://www.sfml-dev.org/documentation/2.0/classsf_1_1Texture.php#a0c3bd6825b9a99714f10d44179d74324)) but you may not like it.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 22, 2013, 08:26:16 pm
OK I set the textures to 32:32, still the same distortion bug
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 22, 2013, 08:58:30 pm
There is literally no zoom level that actually doesn't make things distorted, I tried everything. Does anyone know the cause, or maybe a fix? :/
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Laurent on July 22, 2013, 09:11:12 pm
Quote
There is literally no zoom level that actually doesn't make things distorted
An exact x2 zoom doesn't give a perfect result?
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 22, 2013, 10:29:36 pm
Quote
There is literally no zoom level that actually doesn't make things distorted
An exact x2 zoom doesn't give a perfect result?

We have tried all sorts of methods, including just using a precise setSize, and we've set a very small scale for zooming so that we can find a good non-distorted version of the game as well but no results. We've tried zooming for a specific factor, like 2x, 3x, etc, but still, there is a noticeable distorsion. Changing the texture size to 32x32 did make things appear a bit better, but not by much.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Laurent on July 22, 2013, 10:47:05 pm
You should try to reproduce this problem in a minimal app (just a sprite and a view). This way I (and others) can test it easily.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 23, 2013, 03:58:39 pm
Okay, I've managed to reproduce this bug on a very small scale, it's not as serious as in the game but it's the same bug, you can clearly see a distortion when you zoom in or out. I didn't want to include our whole map system so I just made it load a picture of a map. I know it's not the same as a vertexarray, but it's as minimal as I can get.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Laurent on July 23, 2013, 05:59:47 pm
I tested your code and I can't reproduce unexpected results.

The result is sometimes not a 1:1 rendering of the original image, but that's clearly because of what G. said.

Quote
If your tiles are 32*32, when you zoom they are maybe displayed as 38*38, that's 6 rows and columns of new pixels so obviously the pixel patterns can't be the same.

So, on my side, everything is ok.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 24, 2013, 10:41:17 am
Alright, I just thought that it wasn't supposed to be like that, because when I make the artwork and see it a bit distorted it ruins some of my plans.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Laurent on July 24, 2013, 11:54:15 am
Activating linear filtering (texture.setSmooth(true)) might give a better (smoother) result, but it would also ruin your pixel art.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 24, 2013, 01:33:47 pm
We tried that, and it works, I'm not sure if we'll use the smoothening, we might just keep this small distortion right now, we're only worried because we plan to commercialize the game
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: netrick on July 24, 2013, 02:21:38 pm
A KISS solution would be just not to use zoom in pixel-art game and leave it for 3D games. It depends on the game design though.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Nexus on July 24, 2013, 02:56:20 pm
A KISS solution would be just not to use zoom in pixel-art game and leave it for 3D games.
Not using the SFML view zooming functionality "for simplicity" is very questionable, I'm sure Octav has his reasons why he needs this feature. There are many use cases even for 2D games.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: netrick on July 24, 2013, 04:01:36 pm
Yes, but zooming causes graphical glitches in pixel art. He wants to solve it and I just say that not using zoom is the simplest solution - sometimes we forget that we can remove a problematic feature and do great without it.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: G. on July 24, 2013, 04:13:50 pm
I wouldn't call "don't zoom" a solution to "how to avoid distortion when using zoom?". :D
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 04:20:50 pm
You guys are saying this is normal, but just look at this image.

(http://puu.sh/3N0j2)

I want to release a game to a wider audience. Those are horizontal pixels. And no matter what I zoom, it stays distorted, we have tried the smallest scales possible. I have tried everything. There has to be a cause to this, because this is horrible. I spend hours on artwork, and to see it look like this in-game is so terrible :/
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: FRex on July 27, 2013, 04:36:14 pm
How are you drawing that? VertexArrays? Sprites? Something else?
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 04:38:20 pm
How are you drawing that? VertexArrays? Sprites? Something else?

VertexArray. Also we tried setSmooth() but it doesn't help much. It still keeps some very ugly distorsion, it just messes it up even more.

void MapLayer::ConstructMap()
{
        mapVertices.clear();

        int index = 0;
        int index_y = 0;

        for(auto&& i : tileData)
        {
                for(auto&& j : i)
                {
                                //====================================================================\\
                                // Figure showing the quad order. Important.                          \\
                                //====================================================================\\
                                //  (up_l_point)    (up_r_point)       |                              \\
                                //        +-----------+                |        (1)    (2)            \\
                                //        |           |                |          +----+              \\
                                //        |           |                |          |    |              \\
                                //        |           |                |          +----+              \\
                                //        |           |                |        (4)    (3)            \\
                                //        +-----------+                |                              \\
                                // (down_l_point)     (down_r_point)   |    Order of the points       \\
                                //====================================================================\\

                                // Declare 4 points of the quad
                                sf::Vertex up_l_point;
                                sf::Vertex up_r_point;
                                sf::Vertex down_r_point;
                                sf::Vertex down_l_point;

                                // Set their positions
                                up_l_point.position =   sf::Vector2f((float)(index*tile_size), (float)(index_y*tile_size));
                                up_r_point.position =   sf::Vector2f((float)(index*tile_size + tile_size), (float)(index_y*tile_size));
                                down_r_point.position = sf::Vector2f((float)(index*tile_size + tile_size), (float)(index_y*tile_size + tile_size));
                                down_l_point.position = sf::Vector2f((float)(index*tile_size), (float)(index_y*tile_size + tile_size));

                                 // Set their texture bounding box
                up_l_point.texCoords =   sf::Vector2f((j%tiles_per_row) * tile_size +0.5f, (j/tiles_per_row) * tile_size +0.5f);
                up_r_point.texCoords =   sf::Vector2f((j%tiles_per_row * tile_size) + tile_size-0.5f, (j/tiles_per_row) * tile_size+0.5f);
                down_r_point.texCoords = sf::Vector2f((j%tiles_per_row) * tile_size + tile_size-0.5f, (j/tiles_per_row * tile_size) + tile_size-0.5f);
                down_l_point.texCoords = sf::Vector2f((j%tiles_per_row) * tile_size +0.5f, (j/tiles_per_row * tile_size) + tile_size-0.5f);

                                mapVertices.append(up_l_point);
                                mapVertices.append(up_r_point);
                                mapVertices.append(down_r_point);
                                mapVertices.append(down_l_point);

                                index++;
                }
                index = 0;
                index_y++;
        }
}
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: FRex on July 27, 2013, 04:47:55 pm
Did you try adding and subtracting 0.5 to the positions like you do to textures so that positions too end with 0.5 and tile is tile_size-1.f wide and high?
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 04:53:52 pm
Did you try adding and subtracting 0.5 to the positions like you do to textures so that positions too end with 0.5 and tile is tile_size-1.f wide and high?

Yes, I tried that as well, and the tile_size is 32x32
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: FRex on July 27, 2013, 04:56:36 pm
I mean like this so that it'd create 1:1 mapping between coordinates and texture pixels:
// Set their positions
                up_l_point.position =   sf::Vector2f((float)(index*tile_size) + 0.5f, (float)(index_y*tile_size)+0.5f);
                up_r_point.position =   sf::Vector2f((float)(index*tile_size + tile_size)-0.5f, (float)(index_y*tile_size)+0.5f);
                down_r_point.position = sf::Vector2f((float)(index*tile_size + tile_size)-0.5f, (float)(index_y*tile_size + tile_size)-0.5f);
                down_l_point.position = sf::Vector2f((float)(index*tile_size)+0.5f, (float)(index_y*tile_size + tile_size)-0.5f);
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 04:59:38 pm
I mean like this so that it'd create 1:1 mapping between coordinates and texture pixels:
// Set their positions
                up_l_point.position =   sf::Vector2f((float)(index*tile_size) + 0.5f, (float)(index_y*tile_size)+0.5f);
                up_r_point.position =   sf::Vector2f((float)(index*tile_size + tile_size)-0.5f, (float)(index_y*tile_size)+0.5f);
                down_r_point.position = sf::Vector2f((float)(index*tile_size + tile_size)-0.5f, (float)(index_y*tile_size + tile_size)-0.5f);
                down_l_point.position = sf::Vector2f((float)(index*tile_size)+0.5f, (float)(index_y*tile_size + tile_size)-0.5f);

That seems to produce a better result, however, it also creates a border between the tiles.
(http://puu.sh/3N1rQ.png)
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: FRex on July 27, 2013, 05:14:35 pm
 :-\
What about removing all 0.5fs from both textures and positions?
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 05:18:50 pm
:-\
What about removing all 0.5fs from both textures and positions?

Nope. Still horrible distorsion. Here's the code for my zooming:

if(sf::Keyboard::isKeyPressed(sf::Keyboard::F5) && zoomTimer < 0) {camera.zoom(0.9f); zoomTimer = 0.02f;}
   if(sf::Keyboard::isKeyPressed(sf::Keyboard::F6) && zoomTimer < 0) {camera.zoom(1.1f); zoomTimer = 0.02f;}
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: FRex on July 27, 2013, 05:25:39 pm
If it renders good with no zoom you could try to render it to a texture that has default view without zooms before drawing it to window with zoomed view, have you tried that?
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 05:35:40 pm
If it renders good with no zoom you could try to render it to a texture that has default view without zooms before drawing it to window with zoomed view, have you tried that?

I don't quite understand this, however even without a zoom you can notice some strange graphical bugs
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: eXpl0it3r on July 27, 2013, 05:40:19 pm
I don't quite understand this, however even without a zoom you can notice some strange graphical bugs
Then I really start to doubt, that it's an issue with SFML/OpenGL.
Are your graphics driver uptodate?

Can you put together a minimal and complete example that reproduces the problem, so we can test it on our own and see if it's related to your hardware, a mistake in the code or an actual OpenGL issue.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Nexus on July 27, 2013, 05:47:45 pm
Can you try it with sf::Sprite, just to make sure there is no mistake in the computation of your texture and vertex coordinates?

Test it with the following code, store a single tile in the file "tile.png":
#include <SFML/Graphics.hpp>

int main()
{
        sf::RenderWindow window(sf::VideoMode(640, 480), "SFML Application");
        window.setFramerateLimit(20);

        sf::Texture texture;
        texture.loadFromFile("tile.png");

        sf::Sprite sprite(texture);
        const float tileSize = texture.getSize().x;

        sf::View view = window.getDefaultView();

        while (window.isOpen())
        {
                sf::Event event;
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed)
                                return 0;

                        if (event.type == sf::Event::KeyPressed)
                        {
                                if (event.key.code == sf::Keyboard::F)
                                        view.zoom(1.f/0.9f);
                                else if (event.key.code == sf::Keyboard::D)
                                        view.zoom(0.9f);
                                else if (event.key.code == sf::Keyboard::Escape)
                                        return 0;
                        }
                }

                window.setView(view);
                window.clear();
               
                for (unsigned int x = 0; x < 10; ++x)
                {
                        for (unsigned int y = 0; y < 10; ++y)
                        {
                                sprite.setPosition(x * tileSize, y * tileSize);
                                window.draw(sprite);
                        }
                }

                window.display();
        }
}

You're aware that by using this approach, there will be rounding errors for the zoom? You should recompute the zoom factor based on an integer level, so that it is truly reversible.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 06:01:41 pm
I don't quite understand this, however even without a zoom you can notice some strange graphical bugs
Are your graphics driver uptodate?

Yes, and I don't work alone on this project, and my teammate and other people have had the same distorsion bug.

I don't quite understand this, however even without a zoom you can notice some strange graphical bugs
Can you put together a minimal and complete example that reproduces the problem, so we can test it on our own and see if it's related to your hardware, a mistake in the code or an actual OpenGL issue.

I already have, and it only uses a simple sprite, check page 1
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 06:04:08 pm
Alright a person told me that for him, my code works fine, but he is using SFML 2.1 and I am using the old version. I will try to install 2.1 and get back to this thread.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: eXpl0it3r on July 27, 2013, 07:12:09 pm
I already have, and it only uses a simple sprite, check page 1
Oh I was looking for a code section and not a attachment. :D

Anyways, it works fine on my PC (AMD Radeon 7xxxM series) - except the obvious distortion when zooming out, due to the fact that not all pixel can be represented anymore.
I'm using my Nighlty Build, which is currently the same as SFML 2.1.

(http://i.imgur.com/NaBtADl.png)

(http://i.imgur.com/RCDOW6P.png)

Test it with the following code, store a single tile in the file "tile.png":
Works fine here as well.
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 07:18:35 pm
Fixed it.

Earlier, I had this code:
 // Set their texture bounding box
                up_l_point.texCoords =   sf::Vector2f((j%tiles_per_row) * tile_size +0.5f, (j/tiles_per_row) * tile_size +0.5f);
                up_r_point.texCoords =   sf::Vector2f((j%tiles_per_row * tile_size) + tile_size-0.5f, (j/tiles_per_row) * tile_size+0.5f);
                down_r_point.texCoords = sf::Vector2f((j%tiles_per_row) * tile_size + tile_size-0.5f, (j/tiles_per_row * tile_size) + tile_size-0.5f);
                down_l_point.texCoords = sf::Vector2f((j%tiles_per_row) * tile_size +0.5f, (j/tiles_per_row * tile_size) + tile_size-0.5f);

And removing 0.5f did the trick. Apparently that kills the whole thing. It wasn't a bug with the camera, it was a bug with the way I programmed the vertexarray. It looks perfect now. Thanks a lot everyone!
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: FRex on July 27, 2013, 07:37:46 pm
:-\
What about removing all 0.5fs from both textures and positions?

Nope. Still horrible distorsion.(...)
*grumble grumble*  >:(
Title: Re: Strange distortion bug when zooming with a sf::View
Post by: Octav on July 27, 2013, 08:30:27 pm
:-\
What about removing all 0.5fs from both textures and positions?

Nope. Still horrible distorsion.(...)
*grumble grumble*  >:(

I'm sorry about that, silly mistake, because I didn't add the 0.5f and I didn't realize it was added to the X and Y coords. That position has two sizes, and I was only deleting the ones at the end, silly mistake  ;D