0

Situation

I am writing an image compositor, and I am using FBOs.

As gl can not read a texture that it is currently writing to, currently I am using a pseudo "Fbo Flip Chain" logic. I create a list of about 10 FBO and each time I render I move to the next FBO which can happily read from one of the previous FBO textures.

However this is deeply flawed because of the way I am currently doing my composting an fbo can be overwritten when it is still needed in its current state. I tied a "locking/unlocking" logic but it is flakey.

An image currently goes through the following stages:

  • Draw The Image to a texture (using fbo)
    • fbo flip
  • Composite all of the Images "children" onto image
    • fbo flip for each child this is the issue
  • convert the image to the destination type
    • fbo flip
  • Blend the image with its destination
    • fbo flip
  • pass texture along for composting with siblings

I have decided to re-factor this flip chain-compositing idea. The way I see it, it would be better to do one of the following:

Possible Solutions

  1. Each image would contain its own multiple fbos, each with its own render target, switching to a designated fbo at each stage*
  2. Each Image would contain one fbo and mutiple texture targets, changing the attachment for each stage*
  3. Each image would have 2 render targets ("front", "back"), there would be 1 master fbo and the master fbo would overwrite the "front" texture, while reading from the "back" texture (thinking more like a back buffer and a front buffer). At the end of each stage* swap them over.

*(each stage = where a flip is currently performed)

I am currently leaning towards number 2, each image would end up with 4/5 textures, that would be designated to each stage. And when the image is "drawn" it can test if it can start its draw from a different stage.

e.g. the image has been drawn and is already converted to the correct type, so take the "post_convert" texture and just blend.

Issues:

  • I am unsure which is quicker, attaching and detaching render targets. or binding FBOs...
  • There is an awful lot of textures and fbos being thrown around at the moment. And I am very wary of the fact that I am programming with GL in C# so I need to nail down a system of managing the gl memory alongside C#s GC.
chrispepper1989
  • 2,100
  • 2
  • 23
  • 48
  • I'm not quite sure what you're trying to do there (compositing can be done by reading 10 input textures and outputting to a single FBO...?) but surely switching FBOs -- while being slow -- is faster than changing attachments as the latter forces the implementation to run completeness checks whereas the former doesn't. That said, if you have array textures and texture barrier available, that'll be what you'll likely want to use for your sort of ping-pong compositing or what it is (... which is like a hundred times or so faster). – Damon Feb 11 '15 at 12:43
  • I create N textures for N post-processes. Each post process has its own framebuffer. The textures are passed into the processes manually. So yes, you're eating a lot of texture memory but you know when it comes down to it you can manually optimise many of the textures away by reusing them. It would even be possible to write an algorithm to do this. My first go would be for code clarity, so having one texture per process is best. Only optimise when you're close to shipping. – Robinson Feb 11 '15 at 12:44
  • @Damon thanks, that clarifies the choice between 1 and 2. The composites are actually more like "layers" and multiple layers are blended together. In essence what I am creating is something that allows me to blit things on top of each other with more blend options then the standard blend options. And with the ability to group layers into one pure composite. I can see what you mean by the use of array textures but I don't think its workable here. – chrispepper1989 Feb 11 '15 at 13:10
  • @Robinson so you have multiple fbos with its own render target? Thanks for your comment, that is pretty much exactly what I needed to hear – chrispepper1989 Feb 11 '15 at 13:11
  • Yes but the post process doesn't "own" the texture. In practice there's one per process (or two for a Gaussian blur - an h texture and a v texture) but they're passed into the process. It leaves open the option to optimise later when you see that a texture can be re-used later on in the pipeline. – Robinson Feb 11 '15 at 13:24
  • 1
    _"multiple layers, nonstandard blend modes"_ -- So basically you're rewriting Photoshop in OpenGL? Use shader subroutines, set the correct function pointer uniform for each layer, bind all 10 (or 20 if you will) layers as array texture, and run a loop which first reads the texture layer _n_ and then calls the function pointer _n_ with that input. Write out one color value to a single VBO, once. – Damon Feb 11 '15 at 13:38
  • Excellent suggestion @Damon. And yes thats a pretty good analogy. I am unfamiliar with shader subroutines. Would they be used in a for loop allowing you to access each layer level within one shader? could each "layer" have a different texture matrix / way of aligning it. Would be super if you could post an answer with a quick and dirty example? – chrispepper1989 Feb 11 '15 at 14:01
  • @Robinson one thing confusing me with the fbo renders at the moment, do you set the viewport to the width and height of the fbo render texture – chrispepper1989 Feb 11 '15 at 14:02
  • Yes. Even if I don't expect it to change, I still set it. Makes changing things easier. – Robinson Feb 11 '15 at 14:03

0 Answers0