TextureFont - (yet again), texture coord correction
Posted Friday, 25 July, 2008 - 09:09 by haymo in
... just figured out the possible cause of the artefacts described in that thread. Texture coordinates should obviously be related to the center of the edge pixels in texture image given in TexSubImage2D. Right now, in the TextureFont class they point to the outside edge of those pixels. Therefore - for linear texture mapping - situations exist, where the neighboring pixels from the texture sheet are used for interpolating the edge pixels in the rasterizing step.
After a short test, it seems the corresponding code in TextureFont should be like this:
rectangle = RectangleF.FromLTRB(
(rect.Left + 0.5f) / texture_width,
(rect.Top + 0.5f) / texture_height,
(rect.Right - 0.5f) / texture_width,
(rect.Bottom - 0.5f) / texture_height);
loaded_glyphs.Add(g.Character, rectangle);
(rect.Left + 0.5f) / texture_width,
(rect.Top + 0.5f) / texture_height,
(rect.Right - 0.5f) / texture_width,
(rect.Bottom - 0.5f) / texture_height);
loaded_glyphs.Add(g.Character, rectangle);




Comments
Jul 25
09:41:00Re: TextureFont - (yet again), texture coord correction
posted by the FiddlerI see what you mean, but how could this cause problems in the *middle* of the glyph? If that picture showed an interpolation artifact, wouldn't the problem appear at the border texels only?
Jul 25
12:25:19Re: TextureFont - (yet again), texture coord correction
posted by haymoI guess, the artefacts in the picture (from the old thread) can be explained by that issue. In the word "Roman" for example are 2 vertical lines visible, disturbing the "m" character. The first of them might come from the right edge of the previous char ('o'), the second one comes from the left edge of the 'a' following the 'm' (I suspect).
Aug 03
09:15:48Re: TextureFont - (yet again), texture coord correction
posted by haymoIt took me some hours to figure out, how to archieve the same nice crisp rendering result with the texture offset described above. Especially small fonts looked blurry again. One has to offset and decrease the quads also! Now its working - even when drawing in world coords no such ugly artefacts appeared anymore.
One more thing I found out (by accident). You probably know already:
While storing the glyphs in the texture storage, one does not have to copy the sub-bitmap into a fresh array before. There are usefull PixelStore parameters enabling us to define the offset in the bitmap array:
BitmapData bmp_data = bmp.LockBits(new Rectangle(0,0,bmp.Width,bmp.Height),
ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// setup OpenGL pixel store
GL.PixelStore(PixelStoreParameter.UnpackAlignment,1.0f);
GL.PixelStore(PixelStoreParameter.UnpackRowLength,bmp.Width);
GL.PixelStore(PixelStoreParameter.UnpackSkipRows,bmpRect.Y);
GL.PixelStore(PixelStoreParameter.UnpackSkipPixels,bmpRect.X);
GL.TexSubImage2D(TextureTarget.Texture2D, 0, (int)rect.Left, (int)rect.Top,
bmpRect.Width, bmpRect.Height,
OpenTK.Graphics.PixelFormat.Rgba,
PixelType.UnsignedByte, bmp_data.Scan0);
bmp.UnlockBits(bmp_data);
This theoretically even works with other then 4bpp-formats. One has to watch out for the UnpackAlignment than.
Aug 03
21:33:27Re: TextureFont - (yet again), texture coord correction
posted by the FiddlerThanks, I was sure there was a way to avoid copying the sub-bitmap, but never managed to nail it. This will significantly speed up glyph loading.
Aug 05
00:41:42Re: TextureFont - (yet again), texture coord correction
posted by haymoIn the technical FAQ Wiki on the OpenGL website, I found another (maybe even easier?) workaround:
======================================================
When you have a 2D or 3D or Cubemap texture and you want to clamp the texture coordinates, if you use
glTexParameteri(GL_TEXTURE_X, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_X, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_X, GL_TEXTURE_WRAP_R, GL_CLAMP); //For 3D textures
then when sampling takes place at the edges of the texture, it will filter with border color so you might see black edges.
By default, the border color is black.
Instead of GL_CLAMP, use GL_CLAMP_TO_EDGE.
Link to that wiki
Aug 06
08:55:37Re: TextureFont - (yet again), texture coord correction
posted by the FiddlerAh, of course. Thanks!