OpenGL: distorted textures when they are not divisible by 2
I have a game engine that uses OpenGL for rendering. I coded a small menu for it and then I noticed something strange after rendering the text. http://img43.imageshack.us/i/garbagen.png/
As you can see, the font is somewhat unreadable, but the lower parts (for example, "Tests") look as intended. The position on the screen seems to affect readability as the edges are cropped. The font is 9x5, the value I divide by 2 to get the width / height and display the object from the center. So with 4.5x2.5 pixels (I'm using floats for the 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 this on two computers, but I would not like this error as it makes the text unreadable. I can do this 4.55x2.55 (adding a little extra size when dividing by 2) and then it renders adequately on all machines (or at least not so often in the problematic two), but I'm afraid to hack this too rough,to keep it, and it doesn't completely solve the problem, and it might rescale the text to make the font look ... "bold". So my question is ... is there a way to prevent this and not swap those values ββfor integers? (I need slight differences from the float suggestions). May I know which width / height is divisible in two and the ones that don't handle them differently? If this is indeed a video card issue, can there be a workaround? Sorry if something is missing for the question, I do not resort to asking often about the Internet, and I have no research on coding. I'll be happy to provide any line or piece of code you might need.is there a way to prevent this and not swap these values ββfor integers? (I need slight differences from the float suggestions). May I know which width / height is divisible in two and the ones that don't handle them differently? If this is indeed a video card issue, can there be a workaround? Sorry if something is missing for the question, I do not resort to asking often about the Internet, and I have no research on coding. I'll be happy to provide any line or piece of code you might need.is there a way to prevent this and not swap these values ββfor integers? (I need slight differences from the float suggestions). May I know which width / height is divisible in two and the ones that don't handle them differently? If this is indeed a video card issue, can there be a workaround? Sorry if something is missing for the question, I do not resort to asking often about the Internet, and I have no research on coding. I'll be happy to provide any line or piece of code you might need.if something is missing for a question, I do not resort to asking often about the Internet, and I have no research on coding. I'll be happy to provide any line or piece of code you might need.if something is missing for a question, I do not resort to asking often about the Internet, and I have no research on coding. I'll be happy to provide any line or piece of code you might need.
If you need to draw text in non-integer coordinates, you must enable texture filtering. Use glTexParameterfv , to set GL_TEXTURE_MIN_FILTER
and GL_TEXTURE_MAG_FILTER
to GL_LINEAR
. Your text will be blurry, but this cannot be avoided without resorting to pixel perfect (= integer).
Note that your 0.05 workaround doesn't change anything, how the effective coordinates are rounded to whole numbers. When using texture filtering, GL_NEAREST
there is no such thing as a half pixel offset. Even if you supply these coordinates, the texture filter will round them for you. You just push it in the right direction with an extra 0.05.
source to share
Trying to render pixel-like material like this can be difficult 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 smooth using the alpha channel (transparency).
- Leave some white space (4 or 8 px) around each glyph. If you nudge them directly against eachother (as if you were painting a font for software rendering in the DOS days) then filtering will make them bleed in eachother.
- Or you can take a different approach and infer them from line segments. This might work better for fonts on the scales you are dealing with.
source to share