0
votes

Suppose I want to render an OpenGL scene in two viewports. The first viewport renders a colour image, and the second viewport renders a depth image. Each has its own vertex shader and fragment shader, and each has its own shader program. The shaders are similar, the only difference being that for the colour image, the vertex colour is defined in the vertex shader based on the vertex normal, whereas for the depth image, the vertex colour is defined in the fragment shader based on the vertex depth. To perform the rendering, I glUseProgram() the colour shader program, and draw the colour scene, then glUseProgram() the depth shader program, and draw the depth scene.

What I am unsure about, is how glClear() works when there are two shader programs. Do I need to call it twice per rendering loop -- once before rendering the colour image, and once before rendering the depth image? It seems to work when I just call it once, but this seems strange to me. I would have thought that each shader program writes to the colour and depth buffer once each. Therefore, when rendering the depth image, it would have the buffers left over from rendering the colour image...but this does not seem to be the case. Can somebody explain this to me please? Thanks!

1

1 Answers

5
votes

What I am unsure about, is how glClear() works when there are two shader programs.

If you're unsure about how clearing interacts with shaders, then you have some kind of misunderstanding of what's going on.

glClear clears the framebuffer. What shader programs were used to create the pixels in that framebuffer is entirely irrelevant. It doesn't matter how many programs were used to generate the pixel data.

It's conceptually no different from this:

int foo = <insert large expression here>;
foo = 5;

No matter how large and complicated the initialization expression is, writing 5 to the variable will overwrite whatever was there. Just as clearing the framebuffer will clear the framebuffer, no matter how it got there.

Do I need to call it twice per rendering loop -- once before rendering the colour image, and once before rendering the depth image?

Viewports are not real constructs in OpenGL. They're simply a part of the NDC-to-window-space transformation. Your vertices, after clipping, are transformed to a location within the window; the viewport simply lets you decide where within the window they go. You don't see parts that would be outside of the viewport because those vertices were clipped by the clipping stage.

Viewports do not create framebuffers, sub-framebuffers, mini-framebuffers, or anything having to do with framebuffers. Viewports are just a transformation trick for primitives.

And framebuffer clearing operations do not involve primitives. As such, framebuffer clears do not care about the current viewport. They will affect the entire framebuffer.

Framebuffer clears do respect the scissor box, if scissor testing is enabled when you issue the clear. But viewports are irrelevant to clearing.