Opengl + FreeType别名

时间:2014-05-08 11:32:31

标签: opengl freetype

我尝试使用带有FreeType库的OpenGL显示一些文本。它正在工作,但文字看起来并不那么顺利。在FreeType文档中,它表示在加载过程中会有一些抗锯齿对纹理产生影响,但在我的情况下它看起来并不那样。 这就是我正在做的事情:

FT_Init_FreeType(&m_fontLibrary);
FT_New_Face(m_fontLibrary, "src/VezusLight.OTF", 0, &m_BFont);
FT_Set_Pixel_Sizes(m_BFont, 0, 80);
m_glyph = m_BFont->glyph;
GLuint tex;
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glUseProgram(m_textPipeline);
glUniform1i(m_texLocation, 1);
glUseProgram(0);

然后渲染:

glActiveTexture(GL_TEXTURE1);
glEnableVertexAttribArray(m_coordTex);
glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
const char *p;
float x = x_i, y = y_i;
const char* result = text.c_str();
for (p = result; *p; p++)
{
    if (FT_Load_Char(m_BFont, *p, FT_LOAD_RENDER))
        continue;

    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        GL_ALPHA,
        m_glyph->bitmap.width,
        m_glyph->bitmap.rows,
        0,
        GL_ALPHA,
        GL_UNSIGNED_BYTE,
        m_glyph->bitmap.buffer
        );

    float x2 = x - 1024 + m_glyph->bitmap_left;
    float y2 = y - 600 - m_glyph->bitmap_top;
    float w = m_glyph->bitmap.width;
    float h = m_glyph->bitmap.rows;

    GLfloat box[4][4] = {
        { x2, -y2 - h, 0, 1 },
        { x2 + w, -y2 - h, 1, 1 },
        { x2, -y2, 0, 0 },
        { x2 + w, -y2, 1, 0 },
    };



    glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(GLfloat), box, GL_DYNAMIC_DRAW);
    glVertexAttribPointer(m_coordTex, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), NULL);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    x += (m_glyph->advance.x >> 6);
    y += (m_glyph->advance.y >> 6);
}
glDisableVertexAttribArray(m_coordTex);

结果如下所示:

text

我的代码中是否有人发现问题?

2 个答案:

答案 0 :(得分:1)

您的代码存在两个问题。

第一个是缓冲区溢出:box结构中的纹理坐标是vec2,但是你告诉glVertexAttribPointer它是vec4({{1}的步幅重要的是,不匹配的大小参数使得OpenGL在4*sizeof(float)数组的末尾读出超出边界的2个元素。)

您的纹理看起来像素化源于纹理坐标0和1不会位于像素中心,而是位于纹理的边缘。在片段着色器中使用box按像素坐标对像素进行寻​​址,或者将纹理范围重新映射到范围[0 ... 1],如https://stackoverflow.com/a/5879551/524368

中所述

答案 1 :(得分:0)

我认为有透明色或光滑或抗锯齿的字形, 您必须在opengl中启用混合并禁用深度测试。 (你可以通过互联网搜索找出原因和方法)。

这样的事情:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
//and if it didn't work, then disable depth testing by uncommenting this:
//glDisable(GL_DEPTH_TEST); 
希望它有所帮助!