Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1350541
  • 博文数量: 281
  • 博客积分: 8800
  • 博客等级: 中将
  • 技术积分: 3346
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-17 22:31
文章分类

全部博文(281)

文章存档

2013年(1)

2012年(18)

2011年(16)

2010年(44)

2009年(86)

2008年(41)

2007年(10)

2006年(65)

我的朋友

分类: LINUX

2010-10-25 08:29:22

也许你使用过模板缓冲区,但是你真正懂得它的正确用法吗?
   本人根据实践总结出下面几个问题,希望对大家能有所帮助:
   1. 使用模板缓冲区的步骤
    2.glStencilFunc中的参数意义,及如何选择合理参数?
   3.glStencilOp中的参数意义及选用.
  ====================================================================
  问题1:
   简而言之:
           1)指定默认模板值,用其清除模板缓冲区,
           2)开启模板测试功能,  指定模板比较函数, 指定模板测试失败后对相应位置的模板值的操作方式.
          3)用绘图命令绘制一个模板图形
         4) 绘制其他图形
         下面详细叙述:
   如果你要使用一个模板缓冲区,那么首先你要在使用之前象清除颜色缓冲区一样,把原来缓冲区里的无效数据给清理干净,这就是在调用glClear() 时 加上GL_STENCIL_BUFFER_BIT. 也就是象这样:
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)
  与颜色缓冲区类似,你在使用这个函数之前也要指定一个默认填充值, 你可以这样指定 glClearStencil(0);
当然你不一定要用0,就像你清除颜色缓冲区时不一定要指定glClearColor(0,0,0).一样,你要根据你的需要来设定.
   设定好默认值后,并用这个默认值将模板模板缓冲区填满以后,你就可以在你需要的地方开始使用它了:
   glEnable(GL_STENCIL_TEST);
  接下来我们要生成我们的模板,实际上就是通过一组绘图命令,来绘出一个图像,把它当作模板. 比如我们要生成一个镂空的花窗,那么我们可以把这个花窗需要空的部分绘出来,当作模板,使得在进行后续绘图时,落到这个模板上的图像不被绘制,就形成了镂空..   好了,扯远了, 这只是告诉你什么叫模板....... 呵呵,好像没这个必要???
  因为我们在创造我们的模板时使用的也是绘图命令,有时候,我们并不想让这个模板本身被别人看见, (一个图形要被看见 等于 它被写入颜色缓冲并最终被交换到屏幕上来)..为了不让这些创建模板的代码被显示为图形,我们需要禁止颜色缓冲的写入, 这可以通过下面的语句做到
   glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); 它使所有的颜色通道都不可以写入
 同理,如果我们不希望绘制模板的代码影响深度缓冲区,那么我们可以调用 glDisable(GL_DEPTH_TEST); 来禁止深度缓存的写入.
  设置好这些后,我们准备开始绘制模板,
  绘制模板之前, 我们需要给模板本身所绘制的图形指定一个模板值,为什么呢? 因为模板测试类似与深度测试, 它是通过把已有的模板缓冲区的值,与将要绘制的图形的模板值相比较,然后只绘制使得比较结果为真的那些图像...
  现在模板缓冲区里面全是默认值,那么我们需要给模板本身指定一个值,那么在以后进行绘制时,就可以拿要绘制的图像的模板值与这个值做比较从而进行取舍了...
  而怎么样给绘制的图像赋上模板值,并进行比较呢? 这就是通过2,3 问题中所述的两个函数来进行,  请接着往下看...
问题2.    glStencilFunc 用法
  glStencilFunc的原形是: glStencilFunc( GLenum func, GLint ref, GLuint mask);
  它的作用就是来指定 模板测试 的比较函数, 这些函数用来将   "当前绘制图像的模板值" 与 "要写入位置的模板值" 进行比较 以得到一个Ture Or False 值 , 这个比较函数由第一个参数指定,它是一个 枚举值,可选的有 GL_GREATER ,GL_LESS 等,  第二个就是紧跟着这个函数的绘图函数所绘图形,的模板值, 它用来与要绘制的目标位置的模板值,用第一个参数指定的函数进行比较,得到结果..   但是这种比较并不是直接拿这两个值去比, 假如要绘制的目标位置的模板值是B,第二个参数指定的是A, 那么比较是这样进行的, 先将 A与第三个参数 mask 进行AND操作  并同时将 B与mask 进行与操作,然后按指定的比较函数func比较结果 ,
     也就是 ((ref & mask) op (svalue & mask))
   如果A 与B的比较结构为真,则写入,假则不写入...
问题3: glStencilOp用法
  glStencilOp() 函数的原形为: glStencilOp(GLenum fail , GLenum zfail, GLenum zPss );
 它的作用是用来指定,当某些图元在绘制的时候,如果模板测试失败(或者深度测试失败),它怎么修改其打算写入的位置的模板值. 它的三个参数 分别指定了,当模板测试失败了 该如何修改, 深度测试失败了如何修改,以及 深度测试如果成功又该怎么修改....  后面两个参数也就是说,就算模板测试通过,我们也可以通过深度测试的测试结果修改模板值..
  它们的可选值为: GL_KEEP(保持不变), GL_DEC(减少) , GL_INCR(增加) ,GL_REPLACE(替换),
  特别需要注意的是: 这些操作在每个面片被写入的时候都会进行,如果你使用GL_INCR , 可能你只绘制了一个模型,但是,这个模型有几个面片在深度上重叠,那么在每次写入这些面片时,都会引起一次GL_INCR, 也就是模板值 +1 , 如果你不曾注意到这个问题,那么你在测试函数glStencilFunc 中时选用 GL_EQUAL 就会得到不正确的结果..   如果你需要使用GL_EQUAL 建议你在本函数中选用 GL_REPLACE ,这个变量引起函数用 glStencilFunc  中指定的 ref 值来替代 当前要绘制位置的模板值, 这样多次操作不会有影响....
 
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/doing5552/archive/2008/04/16/2297280.aspx
阅读(946) | 评论(0) | 转发(0) |
0

上一篇:测试笔试题

下一篇:gdb 使用 howto

给主人留下些什么吧!~~