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

Author Topic: Add Vector2i overload to transformable.setPosition()  (Read 5147 times)

0 Members and 2 Guests are viewing this topic.

SoggyBiscuit

  • Newbie
  • *
  • Posts: 2
    • View Profile
Add Vector2i overload to transformable.setPosition()
« on: February 23, 2019, 08:04:55 am »
Or in the tutorial, sprites and textures, mention that textures whose host shape (or I presume sprite) have a position that is in between pixels (i.e. a float position) can cause intended behaviour of a failed render of a working texture IntRect as stated elsewhere on this forum:
Quote
It's not a bug, this is the intended behaviour. It happens when your sprite is at decimal coordinates.
It seems odd this tutorial doesn't mention this problem despite recommending animation sheets and tilesets, which is where this problem is made obvious.

Two sample pictures of before and after I made a workaround in my program of defining position and size as Vector2i and inserting that into a Vector2f constructor before creating my shapes:
(click to show/hide)

Whilst my workaround is easy, if peculiar looking for doing sf::Vector2f(sf::Vector2i(x, y)), it took a long time to realise my code wasn't positioning wrongly, it wasn't magically modifying the IntRect for the texture rectangle, but it was intended behaviour. It would also appear that normally generated shapes with SFML, without a texture, are unaffected.

This is neither simple (you have to ignore giving decimal coordinates despite them being defined only as a float in setter functions), common behaviour (textureless shapes, what you use to build up your program before adding textures, are unaffected) nor expected behaviour for anyone new to the scene (the tutorial isn't intended for anyone who is intimately familiar with OpenGL or how your library talks to it). So I would at least like a mention in the tutorial if not also an overloaded function for Vector2i to represent a perfectly valid way to not cause any further issues that doesn't rely on "free pixels" between textures on the sprite sheet as that does not solve pixel bleeding.

I imagine you need coordinates/size to be defined as a float for some reason, despite this flaw and what is probably an odd quirk given that there is no pixel 0.5 0.5 on my monitor, which is why I'm not requesting replacing existing behaviour.

It was even said at the time in the linked thread:
Quote
Quote
Is the behavior already mentioned somewhere in the documentation/tutorials or do you think it occurs too rarely?
It is mentioned in the tutorials that don't exist yet ;D
So I think, given that was posted in 2012, 7 years is long enough to wait for a few sentences in one tutorial.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Add Vector2i overload to transformable.setPosition()
« Reply #1 on: February 23, 2019, 10:26:18 am »
It is mentionned in the API documentation. And if you read that piece of doc, you'll see that it's not just about entity's coordinates. The final pixel positions also depends on the current view, viewport, etc. So providing an overload for integer coordinates would only solve the problem in some specific cases. In any case, you have to understand the problem, and know everything that can have an impact on it.

Quote
I imagine you need coordinates/size to be defined as a float for some reason
For moving / rotating entities. If you disallow decimal coordinates, they will look jerky.
Laurent Gomila - SFML developer

SoggyBiscuit

  • Newbie
  • *
  • Posts: 2
    • View Profile
Re: Add Vector2i overload to transformable.setPosition()
« Reply #2 on: February 23, 2019, 11:49:38 am »
Ah, I have found it in transformable after you said and didn't even say which one it was in, tucked away and written in a manner that wouldn't seem out of place on the tutorial pages as a footnote given its unique oddity that certainly is of use to new coders.
Quote
A note on coordinates and undistorted rendering:
By default, SFML (or more exactly, OpenGL) may interpolate drawable objects such as sprites or texts when rendering. While this allows transitions like slow movements or rotations to appear smoothly, it can lead to unwanted results in some cases, for example blurred or distorted objects. In order to render a sf::Drawable object pixel-perfectly, make sure the involved coordinates allow a 1:1 mapping of pixels in the window to texels (pixels in the texture). More specifically, this means:
  • The object's position, origin and scale have no fractional part
  • The object's and the view's rotation are a multiple of 90 degrees
  • The view's center and size have no fractional part
Well that shouldn't be a bother, since if I have elements with pixel art I shan't be moving, rotating or viewporting them in fractions of pixels.

Though it doesn't document how to solve this conundrum for when you intend for smooth movement, full rotation or really anything about how to understand the problem nor everything that has an impact on it.

However given that the documentation is blaming OpenGL for the fault, including that in my searches has yielded better answers. Unfortunately it seems the only solution applicable to SFML is creating wraparound, disused border pixels. A shame that.