写入 OpenGL 模板缓冲区

pap*_*man 6 c++ opengl stencil-buffer glfw

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

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

sci*_*pie 6

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

模板缓冲区理论上是一个缓冲区,类似于后台缓冲区和深度缓冲区。他们三个同时写入(启用时)。您可以通过特定调用启用/禁用写入它们:

  • 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);
Run Code Online (Sandbox Code Playgroud)

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

请注意,在渲染遮罩几何图形时,将模板函数设置为 GL_ALWAYS 很重要,否则,模板缓冲区中的当前值(在示例中已清除)将针对上次使用的任何内容和您的遮蔽几何图形进行测试甚至可能根本不会被绘制。

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

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