glClear函数:关于参数的问题

时间:2011-09-13 09:52:32

标签: c memory opengl bits

我想了解glClear功能的深层次。我理解它的一般解释 - >清除缓冲区的颜色,深度,模板和积累,但我还有其他问题。 我的朋友假设您清除了代表内存中颜色,深度,模板和积累的位(堆栈?)。通过指定和应用参数:(例如,仅颜色和深度)'掩码',您只清除存储器中的那些位(因此“按位操作”)。

举个例子:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

www.khronos.org对“mask”的参数说明。 mask:掩码的按位OR,表示要清除的缓冲区。

以下是我的问题:

  • 参数GL_COLOR_BUFFER_BIT和GL_DEPTH_BUFFER_BIT各占1位内存吗?或者它们表示了多少位(我想了解如何实际应用位掩码)?
  • 我看不出“OR”掩码如何取消位?如果对标记为“set”(而不是“unset”)的位使用“OR”,它仍将返回零(1或0仍然返回1)?我觉得这完全错了吗?我在这里错过了什么吗?
  • “或”标志(管道)是怎么回事;为什么这些参数没有用通常的逗号分隔,而不是在实际函数中声明的按位操作“OR”?

也许我很困惑,因为我是这个领域的新手。 能否请您详尽解释一下?我不想在OpenGL中继续这些问题时跳过这些问题;我想知道我在做什么,并且这种理解可能会帮助我。谢谢!

3 个答案:

答案 0 :(得分:7)

当您指定要清除的内容时,编写内容的方式可以提供更大的灵活性。这里如何定义标志:

#define GL_COLOR_BUFFER_BIT 1 // 0000 0001
#define GL_DEPTH_BUFFER_BIT 2 // 0000 0010

正如你所看到的,那些是2的幂。这样,在内存中,每个标志只有一位被设置为1(显然在不同的位置)。 当你在这些标志上计算一个按位OR时,你会得到0000 0011.要知道在结果值中是否设置了一个标志,你只需要用已检查的标志计算一个按位AND。

int foo = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; // foo = 0000 0011

if (foo & GL_COLOR_BUFFER_BIT) { // 0000 0011 & 0000 0001 => 0000 0001 (!= 0)
    // clear color buffer(which is located at a position OpenGL knows)
}
if (foo & GL_DEPTH_BUFFER_BIT) { // 0000 0011 & 0000 0010 => 0000 0010 (!= 0)
    // clear depth buffer
}

答案 1 :(得分:3)

您为glClear提供的按位组合不是清除缓冲区的位。缓冲区用其特定的清晰颜色(glClearColor)或清晰的深度值(glClearDepth,我认为?)进行单独清除。 glClear的按位标志只告诉它要清除哪些缓冲区。这些是按位顺序,只需指定多个缓冲区即可清除。

编辑:您可以想象它的工作方式如下:

void glClear(unsigned int bits)
{
    if(bits & GL_COLOR_BUFFER_BIT)    //color bit is set
    {
        //clear color buffer using current clear color
    }
    if(bits & GL_DEPTH_BUFFER_BIT)    //depth bit is set
    {
        //clear depth buffer using current clear depth value (usually 1)
    }
    if(bits & GL_STENCIL_BUFFER_BIT)  //stencil bit is set
    {
        //clear stencil buffer using current clear stencil value (usually 0)
    }
}

答案 2 :(得分:1)

正如其他人所说,那些GL_COLOR_BUFFER_BIT和相关的位掩码与写入各种缓冲区的最终清除值无关。每个都只是一个glClear()内部检查的标志(使用按位AND,正如其他人指出的那样)来决定要对哪些缓冲区进行操作。

一旦检查了缓冲区标志,从概念上讲,glClear()只是循环遍历帧缓冲区中的每个像素,并将其设置为“清除”值,这样就可以绘制一个空白的平板。这些值使用glClearColor()等设置。你可以想象它是这样的:

void glClear(GLuint buffers)
{
  if (buffers & GL_COLOR_BUFFER_BIT) {
    for (int i = 0; i < height; ++i) {
      for (int j = 0; j < width; ++j) {
        colorBuffer[i][j].r = clearColor.r;
        colorBuffer[i][j].g = clearColor.g;
        colorBuffer[i][j].b = clearColor.b;
        colorBuffer[i][j].a = clearColor.a;
      }
    }
  }

  if (buffers & GL_DEPTH_BUFFER_BIT) {
    // Etc, using depthBuffer and glClearDepth value instead here
  }

  // etc. for accum & aux buffers.
}