简体   繁体   English

模板缓冲区如何在OpenGL中运行

[英]How Stencil Buffer Operates in OpenGL

I'm trying to achieve the following effect in OpenGL as depicted in the given link http://commons.wikimedia.org/wiki/File:OpenGL_Tutorial_Stencil.png , code snippet is also below, this is the official openGL wikipedia tutorial. 我正在尝试在OpenGL中实现以下效果,如给定链接http://commons.wikimedia.org/wiki/File:OpenGL_Tutorial_Stencil.png中所述 ,代码段也在下面,这是官方的openGL Wikipedia教程。

Although it has code and comment out explanations I still find it hard to understand the logic of stencil buffer operation in openGL. 尽管它有代码和注释说明,但我仍然很难理解openGL中模板缓冲区操作的逻辑。 I kindly remind that before starting to stenciling I read most of the instructions in the red book, so I know and I'm familiar with, how glStencilFunc, glStencilOp and glStencilMask etc.. works, but there are still some obscure and unclarified things in my mind related to the stenciling. 我谨提醒您,在开始编排模板之前,我已经阅读了红皮书中的大多数说明,因此我知道并且我熟悉glStencilFunc,glStencilOp和glStencilMask等的工作原理,但是其中仍然有些晦涩和不清楚的内容我的思想与狭窄有关。

Here is my walkthrough on how I interpret the code : 这是我如何解释代码的演练:

  1. With glStencilFunc(GL_NEVER, 1, 0xFF); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); 使用glStencilFunc(GL_NEVER, 1, 0xFF); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); glStencilFunc(GL_NEVER, 1, 0xFF); glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP); I believe that stencil test will always pass and failing the stencil test will result in 1s filled in stencil buffer due to the instructions set in glStencilOp 我相信模板测试将始终通过,并且由于glStencilOp设置的指令,模板测试失败将导致在模板缓冲区中填充1s

  2. If the previous code blocks (#1) sets the all pixels in stencil buffer what we achieve with glStencilMask(0xFF); 如果前面的代码块(#1)设置了模板缓冲区中的所有像素,我们使用glStencilMask(0xFF);可以实现什么glStencilMask(0xFF); procedure call. 过程调用。 Do we guarantee that all the 1s are written into stencil buffer successfully or what actually? 我们是否保证所有的1都成功写入模板缓冲区或实际写入模板缓冲区?

  3. We draw the circle then switch on the masks but this time glStencilMask(0x00) , here is one of the confusion, I think this deals with preventing stencil buffer values to be overriden by new values but code comments says that this simply fills the stencil buffer with 0s. 我们绘制圆圈然后打开蒙版,但是这次是glStencilMask(0x00) ,这是一种困惑,我认为这是为了防止模板缓冲区值被新值覆盖,但是代码注释说这只是填充了模板缓冲区与0s。

  4. Finally, if you we don't change any value (due to glStencilMask(0x00) ) in stencil buffer what is the sense of having the 最后,如果您不更改模板缓冲区中的任何值(由于glStencilMask(0x00) ),则具有

    // fill 0s glStencilFunc(GL_EQUAL, 0, 0xFF); /* (nothing to draw) */ // fill 1s glStencilFunc(GL_EQUAL, 1, 0xFF);

Main program body : 主体程序:

 void onDisplay() {       
  glClearColor(0.1, 0.1, 0.1, 1.0);
  glClear(GL_COLOR_BUFFER_BIT); 

  glClear(GL_DEPTH_BUFFER_BIT);
  glEnable(GL_STENCIL_TEST);
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  glDepthMask(GL_FALSE);
  glStencilFunc(GL_NEVER, 1, 0xFF);
  glStencilOp(GL_REPLACE, GL_KEEP, GL_KEEP);  // draw 1s on test fail (always)

  // draw stencil pattern
  glStencilMask(0xFF);
  glClear(GL_STENCIL_BUFFER_BIT);  // needs mask=0xFF
  draw_circle();

  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  glDepthMask(GL_TRUE);
  glStencilMask(0x00);
  // fill 0s
  glStencilFunc(GL_EQUAL, 0, 0xFF);
  /* (nothing to draw) */
  // fill 1s
  glStencilFunc(GL_EQUAL, 1, 0xFF);

  draw_scene();

  glDisable(GL_STENCIL_TEST);

  glutSwapBuffers();
}

glStencilMask(0xFF) is analogous to the glColorMask(true, true, true, true) or glDepthMask(true) functions - 0xFF is a mask that is bitwise ANDed with any stencil data before it is written to the stencil buffer. glStencilMask(0xFF)类似于glColorMask(true, true, true, true)glDepthMask(true)函数glDepthMask(true)是一个掩码,在将其写入到模板缓冲区之前,它与任何模板数据按位与。 Therefore, via glStencilMask(0xFF) , we are ensuring that any value that OpenGL attempts to write to the stencil buffer is successfully written. 因此,通过glStencilMask(0xFF) ,我们确保OpenGL尝试写入模板缓冲区的任何值均已成功写入。

glStencilMask(0x00) : when 0x00 is bitwise ANDed with any byte, the output will always be 0. So, any time bytes are attempted to be written to the stencil buffer, the byte written in will be 0. Essentially, at this point, it simply ensures that the stencil buffer does NOT have any new data written to it. glStencilMask(0x00) :当0x00与任何字节按位与时,输出将始终为0。因此,任何时候尝试将字节写入模板缓冲区时,写入的字节将为0。它只是确保模板缓冲区没有写入任何新数据。

As per my interpretation, the section with the /* (nothing to draw) */ comment is where you would draw materials intended to be outside the stencil tested circle. 根据我的解释,带有/* (nothing to draw) */注释的部分是您在此处绘制打算在模板测试圆之外的材料的位置 0 is the default value in the stencil buffer; 0是模板缓冲区中的默认值; therefore, since the area in the circle is marked 1, pixels that are outside the circle will pass, and pixels inside will be discarded. 因此,由于圆圈中的区域被标记为1,因此圆圈外的像素将通过,而像素内的像素将被丢弃。 It's simply a placeholder. 它只是一个占位符。

I believe that when the comments say // fill 0s , what they mean is that "anything drawn here will fill the part of the stencil buffer that is set to 0. Considering the call to glStencilFunc with GL_EQUAL and 0 as the arguments, this is what will happen. I also am sure that when the comments say // fill 1s they mean the same but with the part of the stencil buffer set to 1 (ie the area where the circle has been drawn to the stencil buffer.) 我相信,当评论说// fill 0s ,他们的意思是,“在这里画什么将填补被设置为0。考虑调用模板缓存的一部分glStencilFuncGL_EQUAL0作为参数,这是我也确信,当注释说// fill 1s它们的含义相同,但模板缓冲区的一部分设置为1(即,将圆圈绘制到模板缓冲区的区域)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM