在 OpenGL 中使用 Freetype 的字体渲染问题不起作用

Issue with Font Rendering using Freetype in OpenGL is not working

我遇到字体渲染问题。为此,我正在使用教程 https://learnopengl.com/In-Practice/Text-Rendering。 我正在 OpenGLESV3 中开发应用程序。

我为 3D 对象绘制、加载纹理和最后的字体渲染制作了不同的着色器程序。 我在 3D 对象和纹理绘制完成后绘制字体。 但是问题是当我使用正交投影绘制时看不到字体。我只能看到 3D 对象和纹理。 (尽管着色器不同)

当我仅使用正交投影绘制字体时,它绘制得非常完美。

我确定是投影设置的问题,但我无法找出问题所在。 有人可以帮忙吗?

这是我的渲染循环中的代码

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, (GLsizei)SCR_WIDTH, (GLsizei)SCR_HEIGHT);

/********************************* 3D objects Rendering ********************************************************/
glUseProgram(shaderpgmPoints);
projection = glm::perspective(glm::radians(camspec.fov), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
glUniformMatrix4fv(glGetUniformLocation(shaderpgmPoints, "projection"), 1, false, &projection[0][0]);

view = glm::lookAt(camspec.cameraPos, camspec.cameraPos + camspec.cameraFront, camspec.cameraUp);

glUniformMatrix4fv(glGetUniformLocation(shaderpgmPoints, "view"), 1, false, &view[0][0]);

model = glm::mat4(1.0f);
glUniformMatrix4fv(glGetUniformLocation(shaderpgmPoints, "model"), 1, false, &model[0][0]);

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

glBindBuffer(GL_ARRAY_BUFFER, quadBufferObject);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)64);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindBuffer(GL_ARRAY_BUFFER, leftlaneBufferObject);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)192);

;
glEnable(GL_PROGRAM_POINT_SIZE);
glDrawArrays(GL_LINES, 0, 12);
glDisable(GL_BLEND);


glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindBuffer(GL_ARRAY_BUFFER, rightlaneBufferObject);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void*)32);

glLineWidth(10.0f);
glDrawArrays(GL_LINES, 0, 2);
glDisable(GL_BLEND);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glUseProgram(0);
/********************************* 3D objects Rendering -End ********************************************************/


/********************************* Texture Rendering ********************************************************/
glUseProgram(shaderpgmTexture);
glm::mat4 transform = glm::mat4(1.0f);
transform = glm::translate(transform, glm::vec3(0.0f, 0.0f, 0.0f));
glUniformMatrix4fv(glGetUniformLocation(shaderpgmTexture, "transform"), 1, false, &transform[0][0]);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glUniform1i(glGetUniformLocation(shaderpgmTexture, "outputTexture"), 1);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, camTexture);

glBindBuffer(GL_ARRAY_BUFFER, camTextureBufferObject);
// position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// texture coord attribute
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);

glDrawArrays(GL_QUADS, 0, 4);

glDisable(GL_BLEND);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glUseProgram(0);
/********************************* Texture Rendering - End ********************************************************/

/********************************* Font Rendering ********************************************************/
glDisable(GL_DEPTH_TEST);
glUseProgram(shaderpgmFont);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glm::mat4 project = glm::ortho(0.0f, static_cast<GLfloat>(SCR_WIDTH), 0.0f, static_cast<GLfloat>(SCR_HEIGHT));
glUniformMatrix4fv(glGetUniformLocation(shaderpgmFont, "projection"), 1, false, &project[0][0]);
glUniform3f(glGetUniformLocation(shaderpgmFont, "textColor"), 1.0f, 0.0f, 0.0f);
glActiveTexture(GL_TEXTURE0);
GLfloat scale = 1.0f;
GLfloat x = 10.0f;
GLfloat y = 10.0f;
std::string text = "THE";
std::string::const_iterator c;
for (c = text.begin(); c != text.end(); c++)
{
    Character ch = Characters[*c];

    GLfloat xpos = x + ch.Bearing.x * scale;
    GLfloat ypos = y - (ch.Size.y - ch.Bearing.y) * scale;

    GLfloat w = ch.Size.x * scale;
    GLfloat h = ch.Size.y * scale;
    GLfloat vertices[6][4] = {
        { xpos,     ypos + h,   0.0, 0.0 },
        { xpos,     ypos,       0.0, 1.0 },
        { xpos + w, ypos,       1.0, 1.0 },

        { xpos,     ypos + h,   0.0, 0.0 },
        { xpos + w, ypos,       1.0, 1.0 },
        { xpos + w, ypos + h,   1.0, 0.0 }
    };

    // Render glyph texture over quad
    glBindTexture(GL_TEXTURE_2D, ch.TextureID);
    // Update content of VBO memory
    glBindBuffer(GL_ARRAY_BUFFER, FontVertexBufferObject);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices); // Be sure to use glBufferSubData and not glBufferData
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    // Now advance cursors for next glyph (note that advance is number of 1/64 pixels)
    x += (ch.Advance >> 6) * scale; // Bitshift by 6 to get value in pixels (2^6 = 64 (divide amount of 1/64th pixels by 64 to get amount of pixels))
}

glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
glUseProgram(0);
glEnable(GL_DEPTH_TEST);
/********************************* Font Rendering - End********************************************************/

我正在像这样初始化字体缓冲区

    glDisable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(shaderpgmFont);
// FreeType
FT_Library ft;
// All functions return a value different than 0 whenever an error occurred
if (FT_Init_FreeType(&ft))
    std::cout << "ERROR::FREETYPE: Could not init FreeType Library" << std::endl;

// Load font as face
FT_Face face;
if (FT_New_Face(ft, "fonts/arial.ttf", 0, &face))
{
    std::cout << "ERROR::FREETYPE: Failed to load font" << std::endl;
}   
else
{
    // Set size to load glyphs as
    FT_Set_Pixel_Sizes(face, 0, 48);

    // Disable byte-alignment restriction
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    // Load first 128 characters of ASCII set
    for (GLubyte c = 0; c < 128; c++)
    {
        // Load character glyph 
        if (FT_Load_Char(face, c, FT_LOAD_RENDER))
        {
            std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;
            continue;
        }
        // Generate texture
        GLuint texture;
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(
            GL_TEXTURE_2D,
            0,
            GL_ALPHA,
            face->glyph->bitmap.width,
            face->glyph->bitmap.rows,
            0,
            GL_ALPHA,
            GL_UNSIGNED_BYTE,
            face->glyph->bitmap.buffer
        );
        // Set texture options
        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);
        // Now store character for later use
        Character character = {
            texture,
            glm::ivec2(face->glyph->bitmap.width, face->glyph->bitmap.rows),
            glm::ivec2(face->glyph->bitmap_left, face->glyph->bitmap_top),
            face->glyph->advance.x
        };
        Characters.insert(std::pair<GLchar, Character>(c, character));
    }
    glBindTexture(GL_TEXTURE_2D, 0);
    // Destroy FreeType once we're finished
    FT_Done_Face(face);
    FT_Done_FreeType(ft);



    // Configure VAO/VBO for texture quads
    glGenBuffers(1, &FontVertexBufferObject);
    glBindBuffer(GL_ARRAY_BUFFER, FontVertexBufferObject);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glUseProgram(0);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);

在您的初始化函数中,您通过 glVertexAttribPointer 设置了一些 OpenGL 状态,稍后会被破坏。

要解决此问题,请修改您的文本呈现代码,使其在 glBindBuffer 之后进行两次调用 glVertexAttribPointer