没有人回答这个问题,这是一个有效的问题,所以一年多后,这里是您问题的答案。
模板缓冲区理论上是一个类似于后台缓冲区和深度缓冲区的缓冲区。同时写入其中三个(启用时)。您可以通过特定调用启用/禁用对它们的写入:
- 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 几何体,您可能需要启用它。如果深度测试失败,您甚至可能不需要编写模板值。
请注意,在渲染遮罩几何体时,将模板函数设置为 GL_ALWAYS 很重要,因为否则,模板缓冲区中的当前值(在示例中已清除)将针对上次使用的内容进行测试,并且您的遮罩几何图形甚至可能根本没有绘制出来。
所以没有特殊的函数可以写入模板缓冲区。我什至不确定它是否可以像您可以将数据直接写入后台缓冲区和深度缓冲区视频内存一样写入,但这不是它应该这样做的方式(因为它非常慢)。模板缓冲区与深度缓冲区共享内存,因此可以通过更改写入函数的参数来实现。不过,我不会指望它适用于所有视频驱动程序。
祝所有需要此信息的人好运!