c++ - 写入 OpenGL 模板缓冲区

标签 c++ opengl glfw stencil-buffer

我一直在阅读 OpenGL 中的模板缓冲区。基本概念是有道理的;只有在与模板缓冲区中的值按位与运算后满足特定条件时,才会绘制片段。但是我不明白的一件事是你实际上是如何写入模板缓冲区的。是否有我在这里缺少的功能?

附言当我说写入时,我的意思是在模板缓冲区中指定特定的值。

最佳答案

没有人回答这个问题,这是一个有效的问题,所以一年多后,这里是您问题的答案。

stencil buffer理论上和back buffer、depth buffer一样是一个缓冲区。他们三个被同时写入(启用时)。您可以通过特定调用启用/禁用写入它们:

  • glColorMask(red, green, blue, alpha) - 用于后台缓冲区
  • glDepthMask(t/f) - 用于深度缓冲区
  • glStencilMask(value) - 用于模板缓冲区

对于深度和模板缓冲区,您可以通过以下方式专门启用/禁用:

  • glEnable/glDisable(GL_DEPTH_TEST)
  • glEnable/glDisable(GL_STENCIL_TEST)

您渲染到屏幕上的任何三角形都将写入所有启用的缓冲区,除非某些操作功能阻止它。对于模板缓冲区,可以使用几个函数进行设置。请在 OpenGL 引用页面上查找功能,但这里是一个简单的示例,它屏蔽了屏幕的一部分,然后仅在屏幕的被屏蔽部分进行渲染,只是为了让您入门。

glClearColor(0, 0, 0, 1);
glClearStencil(0);
glStencilMask(0xFF);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // Do not draw any pixels on the back buffer
glEnable(GL_STENCIL_TEST); // Enables testing AND writing functionalities
glStencilFunc(GL_ALWAYS, 1, 0xFF); // Do not test the current value in the stencil buffer, always accept any value on there for drawing
glStencilMask(0xFF);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); // Make every test succeed

// ... here you render the part of the scene you want masked, this may be a simple triangle or square, or for example a monitor on a computer in your spaceship ...

glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // Make sure you will no longer (over)write stencil values, even if any test succeeds
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // Make sure we draw on the backbuffer again.

glStencilFunc(GL_EQUAL, 1, 0xFF); // Now we will only draw pixels where the corresponding stencil buffer value equals 1

// ... here you render your image on the computer screen (or whatever) that should be limited by the previous geometry ...

glDisable(GL_STENCIL_TEST);

请注意,我故意省略了任何深度代码,以确保您看到它与模板无关。如果渲染 3D 几何体,则可能需要启用它。如果深度测试失败,您甚至可能不需要编写模板值。

请注意,在渲染 mask 几何体时,将模板功能设置为 GL_ALWAYS 很重要,否则,模板缓冲区中的当前值(在示例中已清除)将根据上次使用的值进行测试,并且您的掩蔽几何图形甚至可能根本不会被绘制。

所以没有特殊的函数来写入模板缓冲区。我什至不确定它是否可以像您可以将数据直接写入后台缓冲区和深度缓冲区视频内存一样写入,但这不是应该这样做的方式(因为它非常慢)。模板缓冲区与深度缓冲区共享内存,因此可以通过更改写入函数的参数来实现。不过,我不会指望它适用于所有视频驱动程序。

祝所有需要此信息的人好运!

关于c++ - 写入 OpenGL 模板缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48246302/

相关文章:

pointers - 将 Go 指针传递给 Cgo

c++ - 在GLFW窗口中启用多重采样不会提高抗锯齿的质量

c++不能在构造函数中使用父类型作为参数

C++ 错误清理

c++ - 结构错误表达式必须有 bool 类型

c++ - 将位数组转换为集合

c++ - 在 OpenGL 中创建和使用浮点纹理

c++ - 使用现代 OpenGL 进行 2D 渲染的正交投影

c++ - 将 WGL 与 GLUT 结合起来,以实现 Windows 7 OpenGL 下的形状。缺少 GLUT INIT?

frame-rate - glfwSwapInterval() 可靠吗?