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

Author Topic: sf::Image subrect exceeds borders  (Read 8019 times)

0 Members and 1 Guest are viewing this topic.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Image subrect exceeds borders
« on: May 02, 2011, 12:54:48 am »
Good evening

In the following code, I create a red image and fill a rectangular part of it with blue color. Then, I create a sprite that takes the whole blue area as sub-rect. Therefore, if I draw the sprite, it should be entirely blue. However, this is not the case. I see a small red border on the left side of the sprite. When I set the X coordinate's decimal part to another value like .49 or .51, everything looks good. I thought the sub-rectangle would be independent of the sprite's position on the screen, how can this happen?

I use Windows 7 64Bit and the Git revision from 2011-04-18, the code has been compiled with Visual Studio 2010.
Code: [Select]
#include <SFML/Graphics.hpp>

int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "Title");
window.SetFramerateLimit(30);

unsigned int x = 301;
unsigned int y = 303;
unsigned int s = 40;

sf::Image red, blue;
red.Create(400, 400, sf::Color::Red);
blue.Create(s, s, sf::Color::Blue);
red.Copy(blue, x, y);

sf::Sprite sprite(red);
sprite.SetSubRect(sf::IntRect(x, y, s, s));
sprite.Move(56.5f, 103.f);

for (;;)
{
sf::Event event;
while (window.PollEvent(event))
{
if (event.Type == sf::Event::Closed || event.Type == sf::Event::KeyPressed)
return 0;
}

window.Clear();
window.Draw(sprite);
window.Display();
}
}
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Image subrect exceeds borders
« Reply #1 on: May 02, 2011, 08:06:08 am »
This must be because of the rasterization rules. I guess that when a texel is exactly at coordinates 0.5, it is rendered on both its left and right pixels. Therefore, your sprite has one extra pixel on one side, and it is out of the sprite's subrect.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Image subrect exceeds borders
« Reply #2 on: May 02, 2011, 08:17:06 pm »
Hm, this bug also appears from time to time in a bigger project, where the sf::View and the sf::Drawable instances always have integral coordinates at the time they are drawn. Unfortunately, I haven't been able to reproduce the behaviour in a minimal example yet.

Or might there be another cause for this (the floats between 0 and 1 are exact enough to mark pixel borders for a few hundred pixels, aren't they)? And do you think the issue is difficult to resolve?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Image subrect exceeds borders
« Reply #3 on: May 02, 2011, 08:38:39 pm »
I can't tell you more about this issue, I'm just guessing. Maybe you can find more useful information about the rasterization rules of OpenGL.

Quote
And do you think the issue is difficult to resolve?

I don't know how it could be solved. Maybe you can add a little offset (like 0.01) to your view/sprites position, so that they are less likely to fall exactly in the middle of a pixel? :?
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Image subrect exceeds borders
« Reply #4 on: May 02, 2011, 09:16:13 pm »
Quote from: "Laurent"
Maybe you can add a little offset (like 0.01) to your view/sprites position, so that they are less likely to fall exactly in the middle of a pixel? :?
That's one of the first things I have tried, to no avail.

Maybe I should experiment a little with sf::Sprite::Render() or the internal OpenGL calls. Is it of help for you if I try to come up with an example that shows the issue for other coordinates than 0.5?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Image subrect exceeds borders
« Reply #5 on: May 02, 2011, 09:23:48 pm »
Quote
Is it of help for you if I try to come up with an example that shows the issue for other coordinates than 0.5?

Yes of course ;)
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Image subrect exceeds borders
« Reply #6 on: May 02, 2011, 10:46:24 pm »
Argh, it was still 0.5, but at the origin. Deep in my code, I use a function to center a drawable's origin, and for odd sizes the decimal part of the origin is 0.5. Nevertheless, a reproducing code example:
Code: [Select]
#include <SFML/Graphics.hpp>

int main()
{
   sf::RenderWindow window(sf::VideoMode(800, 600), "Title");
   window.SetFramerateLimit(30);

   unsigned int x = 301;
   unsigned int y = 303;
   unsigned int s = 40;

   sf::Image red, blue;
   red.Create(400, 400, sf::Color::Red);
   blue.Create(s, s, sf::Color::Blue);
   red.Copy(blue, x, y);

   sf::Sprite sprite(red);
   sprite.SetSubRect(sf::IntRect(x, y, s, s));
   sprite.SetPosition(56.0f, 103.f);
   sprite.SetOrigin(0.5f, 0.f);

   for (;;)
   {
      sf::Event event;
      while (window.PollEvent(event))
      {
         if (event.Type == sf::Event::Closed || event.Type == sf::Event::KeyPressed)
            return 0;
      }

      window.Clear();
      window.Draw(sprite);
      window.Display();
   }
}

I will take a look at OpenGL rasterization when I have some time, maybe I come across something useful (a real solution instead of a workaround). If you suddenly have an idea, don't hesitate to post it, you are the OpenGL pro here ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Image subrect exceeds borders
« Reply #7 on: May 02, 2011, 11:27:59 pm »
Ok, so at least it's consistent and my suggestion still makes sense.

Quote
If you suddenly have an idea, don't hesitate to post it, you are the OpenGL pro here

Sure!
Laurent Gomila - SFML developer

wilbefast

  • Newbie
  • *
  • Posts: 31
    • View Profile
    • http://wilbefast.com
sf::Image subrect exceeds borders
« Reply #8 on: May 13, 2011, 11:53:10 am »
Just to confirm that this problem occurs in 1.6 too, and definitely has something to do with pixel-fractions:
http://www.sfml-dev.org/forum/viewtopic.php?p=31462#31462

The quickest fix seems to be to ensure that everything is cast/rounded to an integer value. Doesn't look quite as nice but you don't get any of the graphical glitches.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Image subrect exceeds borders
« Reply #9 on: May 31, 2011, 12:18:09 am »
I asked a question concerning this OpenGL rasterization problem in another forum and was told that this is the expected behavior. Although I personally find it inconsistent that GL_NEAREST only works for the very most cases, it seems like the only option is to make pixel coordinates fit texture coordinates.

Applied to SFML, this probably means that when you want to draw pixel-perfectly, either the pixel coordinates are rounded, or the texel coordinates are offset in the same way as the pixel coordinates. The ugly workaround would be to add a small epsilon value to pixel coordinates before drawing an object, so that the border case at 0.5 is less likely to be hit.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Image subrect exceeds borders
« Reply #10 on: June 03, 2011, 12:27:52 am »
Do you plan to fix this behavior in SFML, or at least to hint at it?

I'm not sure which approach would be the least painful, but constantly differentiating special cases on user side isn't a very good deal either ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Image subrect exceeds borders
« Reply #11 on: June 03, 2011, 08:35:15 am »
Quote
Do you plan to fix this behavior in SFML

How could I fix this?
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Image subrect exceeds borders
« Reply #12 on: June 03, 2011, 02:31:17 pm »
I think the problem is connected to this thread. The user can partially solve it himself by using workarounds, but he first doesn't expect it and has to find out what is the reason for that behavior. That's why I think you should maybe mention this issue in the tutorial or documenation.

In case you implement a switch for pixel-perfect rendering, you could probably solve this issue by adapting texture coordinates to pixel coordinates (so that GL_LINEAR and GL_NEAREST lead to the same result) or just by rounding pixel coordinates before drawing. For continuous coordinates with smooth transformations, there would be no change.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Image subrect exceeds borders
« Reply #13 on: June 03, 2011, 02:43:40 pm »
Quote
In case you implement a switch for pixel-perfect rendering

That would be the solution but unfortunately it won't be possible anymore in SFML 2. So I'm really left with no solution.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Image subrect exceeds borders
« Reply #14 on: June 03, 2011, 03:03:58 pm »
Quote from: "Laurent"
That would be the solution but unfortunately it won't be possible anymore in SFML 2
I guess because of the new rendering system? I'm really excited about it ;)

But it's a pity if these things are not possible anymore. Do you have a good advice how to achieve such tasks on user side (maybe not now but if everything is finished)?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything