views:

232

answers:

3

I have a game engine that uses OpenGL for display. I coded a small menu for it, and then I noticed something odd after rendering the text. http://img43.imageshack.us/i/garbagen.png/

As you see, the font is somewhat unreadable, but the lower parts (like "Tests") look as intended. Seems the position on the screen affects readability, as the edges get cut. The font is 9x5, a value that I divide by 2 to obtain width/height and render the object from the center. So, with 4.5x2.5 pixels (I use floats for x, y, width and height of simple rectangles), the texture is messed up if rendered somewhere other than x.5 or so. However, it only does so in two computers for now, but I would dislike this error to come out since it makes text unreadable. I can make it 4.55x2.55 (by adding a bit of extra size when dividing by 2), and then it renders adequately in all machines (or at least doesn't happen as often in the problematic two), but I fear this is a hack too gross to keep it and doesn't solve the issue entirely, and it might scale the text up making the font look..."fat". So my question is...is there any way I can prevent this, and not exchanging those values to integers? (I need the slight differences floats offers in comparison). Can I find out which width/heights are divisible by two, and those that aren't, handle them differently? If it's indeed a video card issue, would it be possible to circumvent it? Sorry if there's anything lacking for the question, I don't resort to questioning the internet often and I have no coding studies. I'll be happy to provide any line or chunk of code that might be required.

A: 

For best reliability I would find a way to eliminate the fractions. I only have a little experience with XNA and MDX, so I don't know if there is a good reason, but why are you going by the center rather than corner?

Snarfblam
I use the XY positions to center all hitboxes and rotation centers. I thought it was the normal way, actually... Maybe I can translate everything and just do drawing by corner.
DalGr
Well that makes plenty of sense, certainly as far as rotation goes. I've always stuck with multiples of two, anyways. I have a paranoia about what happens when things don't fall on pixel boundaries, what with issues like forced anti-aliasing and smoothing on textures.
Snarfblam
A: 

Trying to do pixel-perfect stuff like this can be hard in OpenGL due to different resolutions, texture filtering etc.

Some things you could try:

  • Draw your font into one large texture (say 512x512).
  • Draw the glyphs larger than you need and anti-alias using the alpha channel (transparency).
  • Leave some blank space (4 or 8 pixels) around each glyph. If you have them pushed up right against eachother (like you would if you were drawing a font for software-rendering back in the DOS days), then filtering will make them bleed into eachother.
  • Or you could take a different approach and make them out of line segments. This may work better for fonts on the scales you're dealing with.
geofftnz
A: 

If you have to draw your text at non-integer coordinates, you should enable texture filtering. Use glTexParameterfv to set GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER to GL_LINEAR. Your text will be blurred, but that cannot be avoided without resorting to pixel perfect (=integer) coordinates.

Note that your 0.05 workaround does nothing but change the way the effective coordinates are rounded to integers. When using GL_NEAREST texture filtering, there's no such thing as a half pixel offset. Even if you specify these coordinates, the texture filter will round them for you. You just push it in the right direction with the additional 0.05.

Malte Clasen
I aim to achieve a retro (16-bit like) feel, which is completely destroyed by filtering. However, your reply gave me a solution.Yes, I add 0.05 to help scaling up, but when reading how you exposed it, I just need to "push in the right direction" indeed. Thank you.
DalGr