网上搜集了下模板测试的知识,有些都实现了很棒的效果,但大都没有介绍glStencilOp函数里的深度测试情况,这里修改编程宝典里的代码测试下。
先看看OpenGL编程指南里glStencilOp/glStencilOpSeparate函数的介绍:
下面开始进行测试修改:
1 没有模板测试的效果图:
2.使用模板测试
代码:
//绘制正文体
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_STENCIL_TEST);
//模板测试永远不通过
glStencilFunc(GL_NEVER, 0, 0);
//模板值加1
glStencilOp(GL_INCR, GL_KEEP, GL_KEEP);
cubeBatch.Draw();
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glDisable(GL_STENCIL_TEST);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
cubeBatch.Draw();
//绘制地板
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_STENCIL_TEST);
//模板值等于0时绘制
glStencilFunc(GL_EQUAL, 0, 0xff);
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBrown);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
floorBatch.Draw();
效果如图:
简单的修改下模板值为1时绘制地板:
glStencilFunc(GL_EQUAL, 1, 0xff);
效果如图:
直接让模板测试通过,进行深度测试会如何呢?
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_STENCIL_TEST);
//关闭深度测试
glDisable(GL_DEPTH_TEST);
glStencilFunc(GL_ALWAYS, 0, 0);
//模板测试直接通过,关闭深度测试时深度测试通过,第三个参数进行了加1操作
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
cubeBatch.Draw();
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glDisable(GL_STENCIL_TEST);
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// Draw the front side cube
cubeBatch.Draw();
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
//模板值等于0时绘制
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_EQUAL, 0, 0xff);
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBrown);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
floorBatch.Draw();
效果如下图:可以看出,模板测试直接通过,片元没有被丢弃,实体的正方体显示出来了,和线的立方体重合了。模板为0的地板也画出来了。
修改下画模板值为1的地方:
glStencilFunc(GL_EQUAL, 1, 0xff);
在立方体前面加个平面图:
现在有深度值了,修改下模板测试的代码:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_STENCIL_TEST);
//模板测试总是通过
glStencilFunc(GL_ALWAYS, 0, 0);
//深度测试失败模板值加1
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
cubeBatch.Draw();
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glDisable(GL_STENCIL_TEST);
glDisable( GL_DEPTH_TEST );
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Draw the front side cube
cubeBatch.Draw();
glEnable( GL_DEPTH_TEST );
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glDisable( GL_DEPTH_TEST );
glEnable(GL_STENCIL_TEST);
//模板值为0时绘制
glStencilFunc(GL_EQUAL, 0, 0xff);
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBrown);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
floorBatch.Draw();
效果如图: