- this line was added because there was a problem, so I don't see how removing it would magically make everything work
Well, because texels and pixels already are aligned in OpenGL, the spec guarantees this (the 0.5 offset is an issue with Direct3D 9 only; starting with Direct3D 10, texels and pixels align in Direct3D as well).
So
without that line, texels and pixels align and therefore no blurring occurs when bilinear filtering is enabled.
But I find it only reasonable to distrust the guy walking in and telling you that the very website of the API itself is wrong about something. I guess it would make me very skeptical myself, to say the least. But maybe i can convince you
(Note that the FAQ just consists of contributions of "various developers" and overall appears to be pretty outdated, so it's not like I'm trying to say the ARB is telling lies. And then, even the MSDN has some examples that do exactly what not to do...happens)
I don't really expect anyone to go and dive into the OpenGL Specification I referred to in my previous post because of this, so let me just summarize what it says in those two places:
In section 3, pixel (fragment) centers, which are the sampling locations for rasterization (see 3.6.1), are defined to be at half-integer coordinates.
Section 3.9.11 then deals with texture filtering. If you look at the equations for how texels get selected for bilinear filtering, it is obvious that texel centers are at half-integer coordinates as well.
From this follows that texels and pixels are aligned. They have to be in any conforming implementation. No need for fancy offsets, especially not 0.375f.
For further demonstration, I modified the code from the sprite rendering tutorial to draw this sprite:
At integer coordinates, I get this output, which is clearly wrong:
Well, actually not wrong but exactly what one would expect to happen when bilinearly filtering this texture at sampling locations offset by 0.375.
If I am right, we ought to see a uniformly grey square if the offset was 0.5 instead of 0.375. And guess what
(The brighter line at the bottom is caused by the GL_CLAMP addressing mode used by sf::Image)
And without any offset:
voilà
Now I don't know what problem this line was supposed to fix, but I guess it actually didn't fix said problem either, whatever it might have been, but only shifted everything in a way that it would not be noticeable under normal circumstances. And I am almost 100% sure that it is the cause of most of these SFML blurring problems like, for example, just recently
here and even issues such as
this,
this and
this.
Turning off filtering does not fix the real issue, which is that texels and pixels do not align.
And then I can't really rotate my sprites anymore because that'd look pretty bad without filtering.
But removing line 191 from Sprite.cpp does fix it.
In fact, whenever I write a sprite renderer, I actually use this as a test to check if my texcoords can possibly be correct. I render a single sprite (preferably of a size as odd as it can get) at integer coordinates, once with bilinear filtering and once without and then diff the resulting images. If there is even the slightest difference (and especially if there is
just a slight difference), then I know that something must be wrong with my texcoords.
I highly recommend this method as I was able to clear up many uncertain situations this way, for example when drawing small images from a large atlas, where it can get pretty hard to tell just by visual inspection if things really are as they are supposed to be or just about 0.0001f off...
- don't waste too much time with this old code, nobody cares about it, SFML 2.0 is nearly finished
I know. The reason why I investigated this is that I remember seeing people with this problem on basically every one of the forums that I usually am active in at some point. So when yesterday there was another question of this kind on one of our forums, I thought that I might just as well have a look at it.
Since I am pretty confident that this is the way to really fix it, I though I should share it, so that at least other people can find it here.
To me it seems that there are still lots of people using 1.6 out there. And even though I don't really use SFML myself because I usually have no application for it, I am very fond of this library. Among all alternatives that I know of, I consider it by far the best option, because it is very simple to use (it really lives up to its name
), clean and reasonably efficient. So I quite frequently recommend it to beginners asking where to start. And I think this is a very important issue because I imagine this to be an especially nasty problem for those beginners as there is basically no way for a beginner to possibly get to grips with this. And then, after getting frustrated by not being able to figure out what he's doing wrong, our beginner is left with such an unsatisfying workaround as having to turn off filtering because it says so somewhere on the internet, wondering why it is even turned on by default in the first place.
I hope you don't get me wrong, I really appreciate what you've done with SFML
I just wanted to point this out because I think that an almost trivial change could provide a fundamental improvement here.
EDIT: I just tried the same thing with SFML 2.0 and it seems to be correct there.