c++ - 使用模板缓冲区概述对象会给出错误的结果

标签 c++ opengl shader glfw stencil-buffer

我正在尝试使用模板缓冲区在模型后面绘制轮廓边框。

我使用 2 个渲染 channel ,首先渲染模型并使用 GL_ALWAYS1 写入模板缓冲区,然后渲染稍微放大的版本使用 GL_NOTEQUAL 且引用值为 1 的模型,因此基本上只传递原始立方体外部的片段,从而突出显示。

我得到了奇怪的结果,轮廓没有完全渲染,当我足够移动相机时,它完全消失,就好像放大的立方体的模板测试根本没有通过一样。 这是渲染循环的要点(shader3 仅输出边框颜色):

while (!glfwWindowShouldClose(window))
{
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClearStencil(0);
    renderer.Clear();    
    ...
    glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT, 0.1f, 100.0f);
    UniformMat4f projectionUniform("u_Projection");
    projectionUniform.SetValues(projection);

    glm::mat4 view = camera.GetView();
    UniformMat4f viewUniform("u_View");
    viewUniform.SetValues(view);

    modelUniform.SetValues(glm::translate(glm::mat4(1.0f), glm::vec3(5.0f, 0.0f, 0.0f)));

    shader1.SetUniform(projectionUniform);
    shader1.SetUniform(viewUniform);
    shader1.SetUniform(modelUniform);

    glStencilFunc(GL_ALWAYS, 1, 0xFF);
    glStencilMask(0xFF);

    renderer.Draw(model, shader1);

    modelUniform.SetValues(glm::scale(glm::translate(glm::mat4(1.0f), glm::vec3(5.0f, 0.0f, 0.0f)), glm::vec3(1.1f, 1.1f, 1.1f)));
    shader3.SetUniform(projectionUniform);
    shader3.SetUniform(viewUniform);
    shader3.SetUniform(modelUniform);

    glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
    glStencilMask(0x00);
    glDisable(GL_DEPTH_TEST);
    renderer.Draw(model, shader3);
    glEnable(GL_DEPTH_TEST);
}

我首先使用《孤岛危机》中的nanosuit模型进行了尝试,它的工作原理正如我所描述的那样,没有显示所有部件,并最终在移动相机时消失。我决定尝试一个简单的几何图形来测试这一点,并尝试勾勒出一个简单的立方体并得到相同的结果: enter image description here

最佳答案

问题在于主循环末尾对 glStencilMask(0x00); 的调用。模板掩码的默认值为 0xff (对于 8 位,请参阅 glStencilMask )。 OpenGL 是一个状态引擎。状态会被保留,直到它再次改变(甚至超出框架)。
glClear考虑颜色、深度和模板掩模的状态。如果模板掩码为0x00,则模板缓冲区根本不会被清除。

在清除模板缓冲区以解决问题之前,请设置模板掩码0xff:

glStencilMask(0xFF);
renderer.Clear(); 

关于c++ - 使用模板缓冲区概述对象会给出错误的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58640953/

相关文章:

c++ - QGLwidget 从 qmainwindow 弹出,即使它是 mainwindow.ui

c++ - OpenGL PBO 和纹理对象 : Do I need to allocate memory for both

arrays - 大型数组中的几何着色器错误

java - 在处理中更改聚光灯方向

ios - 如何在 SceneKit 中创建动画纹理? "fallback on default program"错误

c++ - 以十六进制表示位串的最佳实践(Arduino)

c++ - OpenGL with Qt 5 : #error gl. h 包含在 glew.h 之前

c++ - 段错误。地址 0x0 未被堆栈、malloc 或(最近)释放

c++ - 如何有效地将 vector 与 C++ 进行比较?

c++ - 用于区分十进制值和非十进制值的正则表达式