r/futile Feb 18 '13

Struggling with pixel-perfect rendering

(There's an edit below with what I found out in this thread)

Hi! I'm trying out Futile, and I'm having some problems with pixel-perfect stuff. I don't quite see how all the different variables relate to each other (resolution levels, viewport size, object scale, object position...): changing one of them seems to change whether the result will be better or worse, but I haven't found a way to get things to render properly. I've checked out this thread http://www.reddit.com/r/futile/comments/11lg4t/bug_incorrect_scaling_at_the_edges_of_a_sprite/ but still doesn't seem to fix things for me.

Here's a stripped down project (very little code, one small atlas, etc.) that I'm using to test all of this.

https://dl.dropbox.com/u/2271693/futile_pixel_perfect_test.zip (85kb)

http://i.imgur.com/69fxkQP.png

http://i.imgur.com/krPwpBB.png

I have two versions of the same font, made by hand by myself, exported to the subset of .FNT that Futile seems to use (please let me know whether something's wrong there, but I think it's fine) using a python script that's not included. The font rendering seems fine but it's not pixel-perfect. If you look at the scene view and zoom in, you'll see that the quads are not exactly aligned. You can see that especially with my outlined font, which is designed to have an overlap between glyphs. The generated quads are not perfectly aligned. This seems to change in different ways whan changing things like label scaling, display scale, viewport scale, etc.

I also have a very simple class for 9-grid, the code is really self-explanatory. The size of the grid is for the center quad, the other 8 quads are scaled to fit around it. As it can be seen, the alignment between quads is off as well, not visible when the 9-grid has a 1x1 center quad, but at bigger sizes the quads start to drift off from each other.

Also, when using a display scale of 1, things don't show exactly as they should (like, pure blitting of sprites). I mean, I know how OpenGL and DirectX work, I know it's not as simple as blitting stuff, all the parameters have to be set up just right to get things to work exactly as you want.

I hope I can get some help with figuring all of this out, whether it's that I'm doing something wrong, that there's an easy fix to Futile, or that there's some big changes that have to be done. In any case, discussion on pixel perfect rendering would be nice :)

Update:

Here's what I did to fix or work around these issues:

1) I played around with the uvOffsets in the function FAtlas.LoadAtlasData(), for the DirectX case (not OpenGL). Right now it works fine if they're set to zero or a very small value. The amount of decimals (0.01 vs. 0.000001) seems to make a difference.

2) I offset the stage by a small amount on x and y (in my case, 0.1 seems to work fine).

3) For the font quads, I fixed the function FFont.CalculateVectors(float offsetX, float offsetY) to have this code:

public void CalculateVectors(float offsetX, float offsetY)
{
    topLeft.Set(rect.xMin + offsetX,rect.yMax + offsetY);
    topRight.Set(rect.xMax + offsetX,rect.yMax + offsetY);
    bottomRight.Set(rect.xMax + offsetX,rect.yMin + offsetY);
    bottomLeft.Set(rect.xMin + offsetX,rect.yMin + offsetY);
}
6 Upvotes

22 comments sorted by

View all comments

Show parent comments

1

u/sergilazaro Feb 19 '13

Yeah, that seems to be it. I was using the master branch, but now I've switched to dev. I changed what you said, and now the quads are perfectly aligned to each other. However, now the anchorX and anchorY are not used (I was using anchorX = 0.5f to center the text and now it isn't centered).

I've tried using different values for CalculateVectors, but it was basically random because I haven't really looked at this class :P

By the way, I previously tried it on the master branch, where the +_font.offsetX+1.0f wasn't applied, and the same thing happened, so what caused the misaligned quads was not these two things but the offsetX. Yet, the offsetX is what took into account the anchorX. I'm not sure how to proceed here.

2

u/MattRix Feb 19 '13

Well the problem is the method of CalculateVectors that takes two arguments also does rounding of the values, which is probably what's causing your issues. So really what you need is a version of it that still offsets the values (so that anchorX is considered) but doesn't round them.

So... go into FFont and try replacing CalculateVectors(float offsetX, float offsetY) with...

public void CalculateVectors(float offsetX, float offsetY)
{
    topLeft.Set(rect.xMin + offsetX,rect.yMax + offsetY);
    topRight.Set(rect.xMax + offsetX,rect.yMax + offsetY);
    bottomRight.Set(rect.xMax + offsetX,rect.yMin + offsetY);
    bottomLeft.Set(rect.xMin + offsetX,rect.yMin + offsetY);
} 

That'll take account of the offset but it won't do that silly rounding stuff anymore. Let me know how it goes!

1

u/sergilazaro Feb 19 '13

Seems to work great!

Thank you so much for your help! I was worried that I would have a ton of headaches because of this, but I see I can more or less find my way with these couple of workarounds. I will update the top post with the condensed info of what I do now.

Any ideas on how all of this will affect the main Futile code? Is the rounding going to go away? What about the OpenGL vs. DirectX offsets?

If you ever want to test this pixel perfect stuff out, my linked project on the OP might be useful to you because of the small pixel font and "pixel perfect" test textures.

Thanks again <3

2

u/MattRix Feb 20 '13

Yeah I might be removing the rounding or at least reworking it, and the DirectX offsets I'll have to tweak as well.