- 1、本文档共5页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
模板测试
模板测试是所有OpenGL测试中比较复杂的一种。
首先,模板测试需要一个模板缓冲区,这个缓冲区是在初始化OpenGL时指定的。如果使用GLUT工具包,可以在调用glutInitDisplayMode函数时在参数中加上GLUT_STENCIL,例如:
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_STENCIL);
在Windows操作系统中,即使没有明确要求使用模板缓冲区,有时候也会分配模板缓冲区。但为了保证程序的通用性,最好还是明确指定使用模板缓冲区。如果确实没有分配模板缓冲区,则所有进行模板测试的像素全部都会通过测试。
通过glEnable/glDisable可以启用或禁用模板测试。
glEnable(GL_STENCIL_TEST);//启用模板测试
glDisable(GL_STENCIL_TEST);//禁用模板测试
OpenGL在模板缓冲区中为每个像素保存了一个“模板值”,当像素需要进行模板测试时,将设定的模板参考值与该像素的“模板值”进行比较,符合条件的通过测试,不符合条件的则被丢弃,不进行绘制。
条件的设置与Alpha测试中的条件设置相似。但注意Alpha测试中是用浮点数来进行比较,而模板测试则是用整数来进行比较。比较也有八种情况:始终通过、始终不通过、大于则通过、小于则通过、大于等于则通过、小于等于则通过、等于则通过、不等于则通过。
glStencilFunc(GL_LESS,3,mask);
这段代码设置模板测试的条件为:“小于3则通过”。glStencilFunc的前两个参数意义与glAlphaFunc的两个参数类似,第三个参数的意义为:如果进行比较,则只比较mask中二进制为1的位。例如,某个像素模板值为5(二进制101),而mask的二进制值因为只比较最后两位,5的最后两位为01,其实是小于3的,因此会通过测试。
如何设置像素的“模板值”呢?glClear函数可以将所有像素的模板值复位。代码如下:
glClear(GL_STENCIL_BUFFER_BIT);
可以同时复位颜色值和模板值:
glClear(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
正如可以使用glClearColor函数来指定清空屏幕后的颜色那样,也可以使用glClearStencil函数来指定复位后的“模板值”。
每个像素的“模板值”会根据模板测试的结果和深度测试的结果而进行改变。
glStencilOp(fail,zfail,zpass);
该函数指定了三种情况下“模板值”该如何变化。第一个参数表示模板测试未通过时该如何变化;第二个参数表示模板测试通过,但深度测试未通过时该如何变化;第三个参数表示模板测试和深度测试均通过时该如何变化。如果没有起用模板测试,则认为模板测试总是通过;如果没有启用深度测试,则认为深度测试总是通过)
变化可以是:
GL_KEEP(不改变,这也是默认值),
GL_ZERO(回零),
GL_REPLACE(使用测试条件中的设定值来代替当前模板值),
GL_INCR(增加1,但如果已经是最大值,则保持不变),
GL_INCR_WRAP(增加1,但如果已经是最大值,则从零重新开始),
GL_DECR(减少1,但如果已经是零,则保持不变),
GL_DECR_WRAP(减少1,但如果已经是零,则重新设置为最大值),
GL_INVERT(按位取反)。
在新版本的OpenGL中,允许为多边形的正面和背面使用不同的模板测试条件和模板值改变方式,于是就有了glStencilFuncSeparate函数和glStencilOpSeparate函数。这两个函数分别与glStencilFunc和glStencilOp类似,只在最前面多了一个参数face,用于指定当前设置的是哪个面。可以选择GL_FRONT,GL_BACK,GL_FRONT_AND_BACK。
注意:模板缓冲区与深度缓冲区有一点不同。无论是否启用深度测试,当有像素被绘制时,总会重新设置该像素的深度值(除非设置glDepthMask(GL_FALSE);)。而模板测试如果不启用,则像素的模板值会保持不变,只有启用模板测试时才有可能修改像素的模板值。(这一结论是我自己的实验得出的,暂时没发现什么资料上是这样写。如果有不正确的地方,欢迎指正)
另外,模板测试虽然是从OpenGL1.0就开始提供的功能,但是对于个人计算机而言,硬件实现模板测试的似乎并不多,很多计算机系统直接使用CPU运算来完成模板测试。因此在一些老的显卡,或者是多数集成显卡上,大量而频繁的使用模板测试可能造成程序运行效率低下。即使是当前配置比较高
文档评论(0)