1

我正在研究字体生成解决方案并面临纹理问题。我正在动态创建纹理图集,然后通过它们的纹理坐标映射每个字母。

这是映射“t”字母的结果:(生成的纹理在顶部,我绘制的在底部)

问题 似乎问题在于图元和纹理区域的大小不匹配,这就是 openGL 尝试调整它大小的原因。加载/渲染纹理时,我在 Min 和 Mag 上都使用 GL_NEAREST

这是渲染代码:

glBegin(GL_TRIANGLE_STRIP);

float twidth = 7.f / 512.f;
float theight = 11.f / 512.f;

float width = 7.f;
float height = 11.f;

float w = width / 2.f;
float h = height / 2.f;

float x = 100;
float y = 100;

float tx = 135.f / 512.f;
float ty = 0;

glTexCoord2f(tx, ty);
glVertex2f(x - w, y-h);

glTexCoord2f(tx + twidth, ty);
glVertex2f(x + w, y-h);

glTexCoord2f(tx, ty + theight);
glVertex2f(x - w, y+h);

glTexCoord2f(tx + twidth, ty + theight);
glVertex2f(x + w, y+h);

glEnd();

这是初始化代码:

glViewport(0,0,width,height);       

glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);   

// Set up the GL state.
glClearColor(1, 1, 1, 1);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);


//glDisable(GL_BLEND);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(0, width, height, 0, -1, 1);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

纹理加载代码:

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 512, 512,
        0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, &texBinary[0]);
4

1 回答 1

3

您的问题源于一个常见的误解,即 OpenGL 如何处理纹理坐标。

纹理坐标 0 和 1 不在像素中心!

纹理实际上是多维采样器,纹理数据为采样器插值提供了支持。现在,这种采样的工作方式对纹理坐标映射施加了一些限制。一个边界条件是,支撑点应该沿维度等距。现在请记住,OpenGL 支持纹理包装。

您的图像基本上是一个光栅,一个样方网格,称为像素。假设您连续获得 8 个像素

   |0|1|2|3|4|5|6|7|

纹理坐标为

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

这是众所周知的栅栏柱问题。你的像素中心实际上是在纹理坐标

(0/8 + 1/8)/2, (1/8 + 2/8)/2, …, (7/8 + 8/8)/2

或更一般的

(2i + 1)/2N

但是,在文本渲染的情况下,您很少需要过滤纹理;如果您缩小光栅化字形,结果会看起来很弱,放大光栅化字形会松散或出现锯齿。

如果您想使用固定功能管道,纹理矩形非常适合这种情况。在要求使用着色器(3 和更高版本)的更高版本的 OpenGL 中,有一个特殊的纹理采样函数,它接受绝对纹理像素索引而不是采样器插值坐标。它们中的任何一个都非常适合这项任务。

如果您使用Vector TexturesDistance Maps,那么您对 ​​glyps 进行采样的方式无论如何都是完全不同的。

于 2012-05-25T19:07:58.653 回答