启用深度测试时的二维文本工件 Opengl
Posted
技术标签:
【中文标题】启用深度测试时的二维文本工件 Opengl【英文标题】:2d text artifact when depth test is enable Opengl 【发布时间】:2020-12-20 12:57:51 【问题描述】: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));
字体.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);
文本.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);
我已经做过的事情:
最后渲染文本 使用 gl_src_alpha, gl_one_minus_src_alpha
当我禁用深度测试时,它工作得很好,我只是在需要时启用和禁用吗? 如果是这样,在性能(游戏流畅度)方面有多差/多好
我对此进行了一些研究,人们说启用 alpha 混合是指 gl_src_alpha、gl_one_minus_src_alpha
【问题讨论】:
【参考方案1】:当您使用Blending 时,您必须禁用Depth Test。绘制几何图形时启用深度测试,但在绘制文本之前禁用深度测试。深度测试会导致根据深度函数丢弃片段。混合从片段着色器获取片段颜色输出,并将它们与颜色缓冲区中的颜色组合。因此混合只适用于那些没有被丢弃的片段。
【讨论】:
以上是关于启用深度测试时的二维文本工件 Opengl的主要内容,如果未能解决你的问题,请参考以下文章
如何为 GitLab CI 运行器启用 Maven 工件缓存?
深度学习中常用的几种卷积(上篇):标准二维卷积转置卷积1*1卷积(附Pytorch测试代码)