0

First my problem: I'm trying to render to multiple buffers in an FBO. I set multiple buffers using glDrawBuffers, and rendering to them using the appropriate gl_FragData. All good and well, but in my situation one of the buffers should be downsampled, by a quarter to be exact (w/2, h/2).

Of course, I can do this by blitting those specific buffers afterwards or I can simply do the downsampling on the CPU (current solution). But then I read about viewport arrays and found this quote in the ARB specification, which seems to be exactly what I want, without any extra conversions.

Additionally, when combined with multiple framebuffer attachments, it allows a different viewport rectangle to be selected for each.

Of course, the specification never mentions afterwards how to do this or what they actually mean, multiple framebuffer attachments is quite generic. I only noticed I can set a specific viewport as an output of the geometry shader (output gl_ViewportIndex). So I could call the geometry twice for each viewport in the array. But as far as I understand, this will simply call the fragment shader with another viewport transformation applied, not one per target buffer. This of course makes not much sense for my usecase, also I can't see how this could ever help to select a viewport per framebuffer attachment

For my situation it does not make much sense to add a geometry shader. And as viewport transform is only applied after the fragment shader, it does make sense to have a viewport per render target, which the previous quote seems to confirm. Is this actually possible, and if so, how would I accomplish this?

Oh, and I've tried the obvious already: resizing the renderbuffer of that target (let's say I use GL_COLOR_ATTACHMENT1) to the downsampled version and setting index 1 of the viewport array to the according size. I ended up with a picture of the lower left quadrant of the image, essentially telling me the viewport was unchanged.

plasmacel
  • 8,183
  • 7
  • 53
  • 101
KillianDS
  • 16,936
  • 4
  • 61
  • 70
  • 1
    "And as viewport transform is only applied after the fragment shader" The viewport transform is applied before rasterization, not after the fragment shader. – Nicol Bolas Aug 01 '12 at 20:13

1 Answers1

4

Viewport arrays can only be used with geometry shaders; without them, array index 0 will be used for all rendering.

Remember: the viewport transform happens before rasterization. Thus, if you want to transform a triangle by multiple viewports, you're effectively asking the system to render that triangle multiple times. And the only way to do that is with a geometry shader that outputs the primitive multiple times.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Of course it is applied at rasterization, that was stupid of me :s, I was confused by the fact that `gl_FragCoord` is in normalized coordinates. Have you any idea what they could have meant with that quote then, because I still don't see how you can have a viewport per attachment? – KillianDS Aug 02 '12 at 06:19
  • @KillianDS: Exactly what it says: the geometry shader can send individual triangles to [individual attached layered images](http://www.opengl.org/wiki/Framebuffer_Object#Layered_Images), and give each triangle a different viewport. The connection between viewports and image layers is not automatic; it's all done in the GS. – Nicol Bolas Aug 02 '12 at 06:31
  • Aha, using `gl_Layer` then, thank you (my experience with geometry shaders is very little). I think I'll stick to the CPU or blit-solution then, duplicating the fragment calculation is not an immediate option. Thank you. – KillianDS Aug 02 '12 at 06:35
  • 1
    "I was confused by the fact that gl_FragCoord is in normalized coordinates." Well, it isn't . It's window space pixel coords. – derhass Nov 05 '21 at 19:21