将纹理坐标与原始大小匹配

时间:2012-05-25 18:53:10

标签: opengl-es opengl-es-2.0 textures texture-mapping

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

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

Problem 似乎问题是原始和纹理区域的大小不匹配,这就是为什么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]);

1 个答案:

答案 0 :(得分: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

然而,在文本渲染的情况下,您很少想要过滤纹理;如果你缩小栅格化的字形,结果会看起来很弱,放大栅格化的字形松散的crispnes或得到别名。

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

如果你使用矢量纹理距离地图,那么你对glyps进行采样的方式就完全不同了。