每个窗口库都需要为你配置一个模板缓冲。GLFW自动做了这件事,所以我们不需要告诉GLFW来创建一个,但其它的窗口库可能不会默认给你创建一个模板库,所以记得要查看库的文档。
描边效果:
模板缓冲首先会被清除为0,之后在模板缓冲中使用1填充了一个空心矩形。场景中的片段将会只在片段的模板值为1的时候会被渲染(其它的都被丢弃了)。
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);//if时机——已储存的模板值、ref参考值、进行与运算
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); //行为——模板失败、模板通过深度失败、都通过
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glStencilMask(0x00); //地板片段模板值为0
normalShader.use();
DrawFloor()
glStencilFunc(GL_ALWAYS,1 0xFF);
glStencilMask(0xFF); // 立方体片段模板值为1
DrawTwoContainers();
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);//模板值=0时通过测试
glStencilMask(0x00); //边框片段模板值为0
glDisable(GL_DEPTH_TEST);
shaderSingleColor.use();
DrawTwoScaledUpContainers();
//?重新启用深度缓冲
glStencilMask(0xFF);
glEnable(GL_DEPTH_TEST);
模板测试的直接结果是什么?
答:通过模板测试的像素会进入到下一步的深度测试,以期被绘制到color buffer上,没有通过的话,直接丢掉它。
2.stencil buffer的值如何更新?
答:1.glClearStencil(指定值); 重置stencil buffer里的值为指定值。
2.glClear(GLSTENCIL_BUFFER_BIT); 重置stencil buffer里的值为0.
3.通过glStencilOp来指定测试(模板测试或深度测试)通过或未通过时,如何修改stencil buffer里的值,有这些修改方式:GL_KEEP GL_ZERO GL_REPLACE GL_INCR GL_DECR GL_INVERT。
注意有些修改方式的操作数只涉及stencil buffer里的stencil值。而有些涉及到调用方法glStencilFunc时传入的第2个参数:参考值。
ps: glStencilFunc(比较条件,参考值,比较用掩码)。这个函数指定了模板测试如何进行。先使用一个【比较用掩码】(comparison mask)与【模板缓冲区中的值】进按位与运算,再与【参考值】通过【比较条件】进行比较,满足了条件,就说通过了测试。(你可以查阅glStencilOp的资料,来了解测试结果出来后的后续)。_
3.glStencilMask有什么作用?
答:(1)glStencilMask(0x00)可以关闭stencil buffer的写入,这样就算开启了模板测试(glEnable(GL_STENCIL_TEST),测试结果也不会影响stencil buffer里已有的模板值。
(2)glStencilMask(0xff)开启stencil buffer的写入,这时候可以往里更新模板数据。
比如绘制某些物体时,来让物体对应的屏幕像素对应的stencil buffer某些位置的模板值变为1:
glStencilFunc(GL_ALWAYS,1,0xff);
glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
drawAThing();