Trace
Trace

Reputation: 18869

glClear function: Question about the parameters

I would like to understand the glClear function to its profound level. I understand its general explanation -> clear the buffers for color, depth, stencil and accumulation, but I have additional questions. My friend assumed that you clear the bits that represent the color, depth, stencil and accumulation in the memory (stack?). By specifying and applying the parameters: (eg. only color and depth) 'masks', you clear only those bits in the memory (hence 'bitwise operation').

Take the example:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

Explanation of the parameters by www.khronos.org of "mask". mask: Bitwise OR of masks that indicate the buffers to be cleared.

Here are my questions:

Perhaps I am confusing things, as I am new in this field. Could you please provide me an exhaustive explanation? I prefer not to skip these questions as I move on in OpenGL; I want to know what I am doing and having this understanding may help me along the way. Thanks!

Upvotes: 1

Views: 2894

Answers (3)

Drew Hall
Drew Hall

Reputation: 29055

As others have said, those GL_COLOR_BUFFER_BIT and related bit masks have nothing to do with the eventual clear values written to various buffers. Each is simply a flag that glClear() checks internally (using bitwise AND as others have pointed out) to decide which buffers to act on.

Once the buffer flags have been checked, conceptually, glClear() just loops over every pixel in the frame buffer and sets it to the "clear" value so you have a blank slate to draw on. Those values are set with glClearColor() and the like. You might imagine it like this:

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.
}

Upvotes: 1

Simon
Simon

Reputation: 890

The way of writing things permits more flexibility when you're specifying what you want to clear. Here how the flags could be defined:

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

As you can see, those are power of 2. This way, in memory only one bit is set to 1 for each flag (at different positions, obviously). When you're computing a bitwise OR on those flags, you get 0000 0011. To know if a flag is set in the resulting value, you just need to compute a bitwise AND with the checked flag.

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
}

Upvotes: 7

Christian Rau
Christian Rau

Reputation: 45948

The bitwise combination you give to glClear are not the bits that the buffers are cleared with. The buffer are cleared indivually with their specific clear color (glClearColor) or clear depth value (glClearDepth, I think?). The bitwise flags for glClear only tell it what buffers to clear. These are ored bitwise to simply specify more than one buffer to clear.

EDIT: You can imagine it to work like:

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)
    }
}

Upvotes: 3

Related Questions