【问题标题】:Trying to draw text in OpenGL, but texture is offset slightly尝试在 OpenGL 中绘制文本,但纹理略有偏移
【发布时间】:2011-08-30 22:07:28
【问题描述】:

我正在尝试在 OpenGL 中绘制文本。我使用一个小型 C# 程序将从 0x21 到 0x7E 的所有字符绘制到位图中。我将其加载为纹理并尝试使用它来绘制我的文本。它似乎有效,但我似乎遇到了一些奇怪的问题。 http://i54.tinypic.com/mmd7k8.png 请注意“a”旁边的额外像素以及“c”被略微切断的事实。似乎整个事情发生了轻微的变化。有人知道我为什么会遇到这个问题吗?我不想使用 gltext 之类的库,因为我不想依赖 libfreetype,因为我只绘制了几个字符串。这是我正在使用的代码:

static void textDrawChar(char c, int x, int y)
{
GLfloat vert[8];
GLfloat texcoord[8];

vert[0] = x;                            vert[1] = y;
vert[2] = x;                            vert[3] = y + TEXT_HEIGHT;
vert[4] = x + font_char_width[c-0x21];  vert[5] = y + TEXT_HEIGHT;
vert[6] = x + font_char_width[c-0x21];  vert[7] = y;

texcoord[0] = (float)(font_char_pos[c-0x21])/TOTAL_WIDTH;
texcoord[1] = 1.0f;
texcoord[2] = (float)(font_char_pos[c-0x21])/TOTAL_WIDTH;
texcoord[3] = 0.0f;
texcoord[4] = (float)(font_char_pos[c-0x21] + font_char_width[c-0x21])/TOTAL_WIDTH;
texcoord[5] = 0.0f;
texcoord[6] = (float)(font_char_pos[c-0x21] + font_char_width[c-0x21])/TOTAL_WIDTH;
texcoord[7] = 1.0f;

glBindTexture(GL_TEXTURE_2D, texture);
glVertexPointer(2, GL_FLOAT, 0, vert);
glTexCoordPointer(2, GL_FLOAT, 0, texcoord);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices);
}

void textDraw(void)
{
textDrawChar('a', 300, 300);
textDrawChar('b', 300+font_char_width['a'-0x21], 300);
textDrawChar('c', 300+font_char_width['a'-0x21]+font_char_width['b'-0x21], 300);
}

编辑 我在纹理坐标 (0,2,4,6) 中添加了 4,这似乎解决了问题。但是,现在我需要知道这是否会继续工作或可能会因未知原因而中断。这是位图创建代码,以防问题可能存在。

using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;

namespace font_to_bmp
{
class Program
{
    static void Main(string[] args)
    {
        Bitmap b = new Bitmap(1715, 36);
        Graphics g = Graphics.FromImage(b);
        g.FillRectangle(new SolidBrush(Color.Transparent), 0, 0, 1715, 36);
        Font f = new Font("Liberation Sans", 24, GraphicsUnit.Point);
        g.PageUnit = GraphicsUnit.Pixel;
        int curx = 0;
        StreamWriter w = new StreamWriter(new FileStream("font_width.h", FileMode.Create, FileAccess.Write, FileShare.Read));
        w.WriteLine("static const int font_char_width[] = {");
        ArrayList hax = new ArrayList();
        for (int i = 0x21; i <= 0x7E; i++)
        {
            char c = (char)i;
            string s = c.ToString();
            SizeF sz = g.MeasureString(s, f);
            StringFormat sf = new StringFormat();
            sf.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0,1)});
            Region r = g.MeasureCharacterRanges(s, f, new RectangleF(0, 0, 1000, 1000), sf)[0];
            RectangleF r2 = r.GetBounds(g);
            Console.WriteLine("{0} is {1}x{2}", s, r2.Width, r2.Height);
            int w_int = (int)(Math.Ceiling(r2.Width));
            g.DrawString(s, f, new SolidBrush(Color.Black), curx, 0);
            hax.Add(curx);
            curx += w_int;
            w.WriteLine("\t{0},", w_int);
        }
        Console.WriteLine("Total width {0}", curx);
        w.WriteLine("};");
        w.WriteLine();

        w.WriteLine("static const int font_char_pos[] = {");

        foreach(int z in hax)
        {
            w.WriteLine("\t{0},", z);
        }
        w.WriteLine("};");

        w.Close();
        b.Save("font.png");
    }
}
}

【问题讨论】:

    标签: opengl text


    【解决方案1】:

    在纹理中精确定位像素有点棘手。请参阅我在OpenGL Texture Coordinates in Pixel Space 中给出的答案


    这已被问过几次,但我手头没有链接,所以一个快速而粗略的解释。假设纹理是 8 像素宽:

     | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
     ^   ^   ^   ^   ^   ^   ^   ^   ^
    0.0  |   |   |   |   |   |   |  1.0
     |   |   |   |   |   |   |   |   |
    0/8 1/8 2/8 3/8 4/8 5/8 6/8 7/8 8/8
    

    数字表示纹理的像素,条形表示纹理的边缘,并且在最近过滤像素之间的边界的情况下。但是,您想击中像素的中心。所以你对纹理坐标感兴趣

    (0/8 + 1/8)/2 = 1 / (2 * 8)

    (1/8 + 2/8)/2 = 3 / (2 * 8)

    ...

    (7/8 + 8/8)/2 = 15 / (2 * 8)

    或者更一般地说,对于 N 宽纹理中的像素 i,正确的纹理坐标是

    (2i - 1)/(2N)

    但是,如果您想将纹理与屏幕像素完美对齐,请记住您指定的坐标不是四边形的像素,而是边缘,根据投影,边缘可能与屏幕像素边缘对齐,而不是中心,因此可能需要其他纹理坐标。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多