Search code examples
webglwebgl2

What are drawBuffers?


The opengl docs as well as OpenGL ES docs state regarding clearBuffer[fiuv]:

If buffer is GL_COLOR, a particular draw buffer GL_DRAW_BUFFERi is specified by passing i as drawbuffer

Indeed, the WebGL spec defines values for DRAW_BUFFER0 .. DRAW_BUFFER15

But what are these things? I've heard of framebuffers, and renderbuffers... but what are drawbuffers? how do I create one? What's the relationship to framebuffers? How do I know which one I'm supposed to clear if I have some deferred rendering pipeline that uses multiple framebuffers?

note: this may seem like a duplicate of Regarding drawBuffer in glClearBufferiv but that question is old, tagged under OpenGL, and doesn't answer the same question exactly


Solution

  • Framebuffers have attachments. Those attachments are also referred to as "drawbuffers" when a framebuffer is the currently bound DRAW_FRAMEBUFFER as they are the buffers that will be drawn to.

    There is a function gl.drawBuffers that let you choose which attachments will actually be written to

    gl.drawBuffers([
      gl.COLOR_ATTACHMENT0,  // draw to the first attachment
      gl.NONE,               // don't draw to the 2nd attachment,
      gl.COLOR_ATTACHMENT2,  // draw to the 3rd attachment
    ]);
    

    Note that these settings are part of the currently bound framebuffer's state. They are not global settings. (and there is a set of this state for the canvas itself when you call the function above with no framebuffer bound)

    Similarly you can call gl.clearBufferXXX to clear a specific attachment of the currently bound framebuffer. For example clearing the 3rd attachment as in

    const drawbuffer = 2
    gl.clearBufferfv(gl.COLOR, drawBuffer, [1, 0, 0, 1]);
    

    Then the 3rd color attachment on the currently bound DRAW_FRAMEBUFFER will be cleared. (0 being the first, 1 being the 2nd, 2 being the 3rd attachment)

    The only use of the constants DRAW_BUFFER0 ... DRAW_BUFFER15 is to query the values set by gl.drawBuffers. Eg. gl.getParameter(gl.DRAW_BUFFER2) gets the drawbuffer setting for the currently bound framebuffer.