ImGui + OpenGL,渲染功能无法渲染字体

时间:2018-01-18 02:03:41

标签: c++ opengl graphics textures

正如标题所说,我正在使用ImGui而我无法使用渲染功能来渲染字体。

我做过的事情:

  1. 使用RenderDoc验证我的纹理已正确加载
  2. 已验证我的顶点属性指针符合ImGui的约定(结构数组)。
  3. 下面是我的渲染代码。您还可以在此处查看开发人员的OpenGL示例代码:https://github.com/ocornut/imgui/blob/master/examples/opengl3_example/imgui_impl_glfw_gl3.cpp

    // Setup some GL state
    glEnable(GL_BLEND);
    glBlendEquation(GL_FUNC_ADD);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_SCISSOR_TEST);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    
    // Setup orthographic projection
    glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
    const float ortho_projection[4][4] =
    {
        { 2.0f/io.DisplaySize.x, 0.0f,                   0.0f, 0.0f },
        { 0.0f,                  2.0f/-io.DisplaySize.y, 0.0f, 0.0f },
        { 0.0f,                  0.0f,                  -1.0f, 0.0f },
        {-1.0f,                  1.0f,                   0.0f, 1.0f },
    };
    
    // Setup the shader. bind() calls glUseProgram and enables/disables the proper vertex attributes
    shadeTextured->bind(); 
    
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, g_FontTexture);
    
    shadeTextured->setUniformM4(Shader::uhi_transform, *(glm::mat4*)&ortho_projection[0][0]);
    shadeTextured->setUniformSampler(1, 0);
    
    // Set my vertex attribute pointers for position and tex coords
    glVertexAttribPointer(0,
                          2,
                          GL_FLOAT,
                          GL_FALSE,
                          sizeof(ImDrawVert),
                          (GLvoid*)IM_OFFSETOF(ImDrawVert, pos));
    
    glVertexAttribPointer(1,
                          2,
                          GL_FLOAT,
                          GL_FALSE,
                          sizeof(ImDrawVert),
                          (GLvoid*)IM_OFFSETOF(ImDrawVert, uv));
    
    // Loop through all commands ImGui has 
    for (int n = 0; n < draw_data->CmdListsCount; n++) {
        const ImDrawList* cmd_list = draw_data->CmdLists[n];
        const ImDrawIdx* idx_buffer_offset = 0;
    
        glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle);
        glBufferData(GL_ARRAY_BUFFER,
                     (GLsizeiptr)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert),
                     (const GLvoid*)cmd_list->VtxBuffer.Data,
                     GL_STREAM_DRAW);
    
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_ElementsHandle);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                     (GLsizeiptr)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx),
                     (const GLvoid*)cmd_list->IdxBuffer.Data,
                     GL_STREAM_DRAW);
    
        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
            glScissor((int)pcmd->ClipRect.x,
                      (int)(fb_height - pcmd->ClipRect.w),
                      (int)(pcmd->ClipRect.z - pcmd->ClipRect.x),
                      (int)(pcmd->ClipRect.w - pcmd->ClipRect.y));
            glDrawElements(GL_TRIANGLES,
                           (GLsizei)pcmd->ElemCount,
                           sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT,
                           idx_buffer_offset);
    
            idx_buffer_offset += pcmd->ElemCount;
        }
    }
    

    以下是我编写的(非常非常简单的)着色器。着色器之前已对按钮进行纹理化处理,因此我假设它们在功能上是正确的。

    顶点着色器:     #version 330核心

    layout (location = 0) in vec2 pos;
    layout (location = 1) in vec2 texCoord;
    
    out vec2 fragTexCoord;
    
    uniform mat4 transform;
    
    void main() {   
        gl_Position = transform * vec4(pos, 0.0, 1.0);
        fragTexCoord = texCoord;
    }
    

    片段着色器:

    #version 330 core
    
    out vec4 fragColor;
    
    in vec2 fragTexCoord;
    uniform sampler2D sampler;
    
    void main() {
        fragColor = texture(sampler, fragTexCoord);
    }
    

    我完全失败了!任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

调试错误的OpenGL设置/状态可能非常困难。目前还不清楚为什么你没有完全使用imgui_impl_glfw_gl3.cpp中提供的代码并重写你自己的代码,但你可能会做的是:

  • 从所谓的工作imgui_impl_glfw_gl3.cpp重新开始,然后一步一步地把它变成你自己的,看看是什么让它破裂?
  • 暂时禁用剪刀。
  • 由于您已经在使用RenderDoc:它是否显示正确的网格?它显示的顶点是否正常?