简体   繁体   English

启用深度测试时的二维文本工件 Opengl

[英]2d text artifact when depth test is enable Opengl

Main.cpp主文件

//Variables
const unsigned int width = 896, height = 504;

//Initiating GLFW Window
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

//Creating a GLFW window
window = glfwCreateWindow(width, height, "Jaguar", NULL, NULL);

//Checking if Window was initiated
if (window == NULL) {
    std::cout << "GLFW FAILED TO INITIATE WINDOW!\n";
    glfwTerminate();
}

glfwMakeContextCurrent(window);

//Centering Window 
int windowWidth, windowHeight;
glfwGetWindowSize(window, &windowWidth, &windowHeight);
const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, mode->width / 2 - windowWidth / 2, mode->height / 2 - windowHeight / 2);

//Setting-Up window's icon
GLFWimage icon[1];
icon[0].pixels = stbi_load("resources/images/gui/icon/icon.png", &icon[0].width, &icon[0].height, 0, 4);
glfwSetWindowIcon(window, 1, icon);
stbi_image_free(icon[0].pixels);

//Checking if Glad was initiated
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
    std::cout << "GLAD FAILED TO BE INITIATED\n";
}

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

stbi_set_flip_vertically_on_load(true);

//Setting-Up Viewport
glViewport(0, 0, width, height);

//Intitiating MainMenu
states.push(new MainMenuState(*window, &states));

font.cpp字体.cpp

FT_Library ft;

if (FT_Init_FreeType(&ft)) {
    std::cout << "FREETYPE::Failed to initialize library\n";
}
FT_Face face;
if (FT_New_Face(ft, filePath, 0, &face)) {
    std::cout << "FREETYPE::Failed to load to font: " << filePath << "\n";
}

// set size to load glyphs as
FT_Set_Pixel_Sizes(face, 0, px);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

for (unsigned char c = 0; c < 128; c++) {

    if (FT_Load_Char(face, c, FT_LOAD_RENDER)) {
        std::cout << "FREETYPE::Failed to load glpyh\n";
    }
    unsigned int texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, face->glyph->bitmap.width,
        face->glyph->bitmap.rows, 0, GL_RED, GL_UNSIGNED_BYTE,
        face->glyph->bitmap.buffer);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    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<char, Character>(c, character));
}
FT_Done_Face(face);
FT_Done_FreeType(ft);

text.cpp文本.cpp

// activate corresponding render state  
shader.use();
glUniform3f(glGetUniformLocation(shader.id, "textColor"), color.x, color.y, 
color.z);
glActiveTexture(GL_TEXTURE0);
glBindVertexArray(VAO);

// iterate through all characters
std::string::const_iterator c;
for (c = string.begin(); c != string.end(); c++)
{
   
    Character ch = font.Characters[*c];
   
    float xpos = position.x + ch.bearing.x * scale;
    float ypos = position.y - (ch.size.y - ch.bearing.y) * scale;

    float w = ch.size.x * scale;
    float h = ch.size.y * scale;
    // update VBO for each character
    float vertices[6][4] = {
        { xpos,     ypos + h,   0.0f, 0.0f },
        { xpos,     ypos,       0.0f, 1.0f },
        { xpos + w, ypos,       1.0f, 1.0f },

        { xpos,     ypos + h,   0.0f, 0.0f },
        { xpos + w, ypos,       1.0f, 1.0f },
        { xpos + w, ypos + h,   1.0f, 0.0f }
    };
    // render glyph texture over quad
    glBindTexture(GL_TEXTURE_2D, ch.textureId);
    // update content of VBO memory
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    // render quad
    glDrawArrays(GL_TRIANGLES, 0, 6);
    // now advance cursors for next glyph (note that advance is number of 
1/64 pixels)
    position.x += (ch.advance >> 6) * scale; // bitshift by 6 to get value in 
pixels (2^6 = 64)
}
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);

Things I have already done:我已经做过的事情:

Render text last used gl_src_alpha, gl_one_minus_src_alpha上次使用的渲染文本 gl_src_alpha, gl_one_minus_src_alpha

when i have depth testing disable it works just fine do I just enable and disable when needed??当我禁用深度测试时,它工作得很好,我只是在需要时启用和禁用吗? if so how bad/good is it when it come to performance(game smoothness)如果是这样,在性能方面有多差/多好(游戏流畅度)

I have done some research on it and people are saying enable alpha blending do they mean gl_src_alpha, gl_one_minus_src_alpha我已经对此进行了一些研究,人们说启用 alpha 混合他们的意思是 gl_src_alpha,gl_one_minus_src_alpha

When you use Blending , you must disable the Depth Test .当您使用混合时,您必须禁用深度测试 Enable the depth test when you draw the geometry, but disable the depth test before drawing the text.绘制几何图形时启用深度测试,但在绘制文本之前禁用深度测试。 The depth test causes fragments to be discarded depending on the depth function.深度测试导致根据深度 function 丢弃片段。 Blending takes the fragment color outputs from the Fragment Shader and combines them with the colors in the color buffers.混合从片段着色器获取片段颜色输出,并将它们与颜色缓冲区中的 colors 组合。 Hence Blending is only applied to those fragments that are not discarded.因此,混合仅适用于那些未被丢弃的片段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM