Rookie
Rookie

Reputation: 4134

How to render into different layers and then combine them together with OpenGL?

I am rendering several layers, which cannot be rendered on just one frame buffer because the modifications would affect all the other layers under it.

How can I render these layers separately in such a way that I can combine them into one final layer? The layers would be rendered with transparency, so when combining them, they would be blended accordingly to all the layers below.

I am currently using FBO to offscreen render them all in one layer, but as I said above, it's not going to work very well when the top-most layer affects all the bottom layers as well.

So how can I combine two (or more? (whichever way is faster)) FBO's (or some better method for FBO?) together as efficiently as possible? Currently I could render them one by one, put into my RAM and then combine them per pixel basis myself, but that seems like a slow method.

What's the fastest way doing this?

Upvotes: 4

Views: 4423

Answers (3)

Jordi Espada
Jordi Espada

Reputation: 415


Maybe I'm wrong but, you can create a layer management sorted by levels. Then, only you've to draw the first layer to last layer and, if you have the right blend function, you can achieve the desired alpha effect ... also, you can control the total alpha over all scenes. It's important to clear DEPTH BIT BUFFER to render every layer in independently manner.

A bit of pseudocode of this idea can be the following,

Total Alpha = 0.9
For l in layer_list // render layers
    // clear depth bit (important before render every layer)
    glClear(GL_DEPTH_BIT_BUFFER)   

    // render all objects layer of layer 'l' with alpha = layer_alpha * total_alpha
    renderLayer(l, TotalAlpha*l.getAlpha())

End For

Upvotes: 0

datenwolf
datenwolf

Reputation: 162174

Use a 2D texture array. Each layer of the array is one render layer.

Render each layer into its own color attachment texture layer (you can switch FBO color attachment at any time), using glFramebufferTexture3D you can select the target layer.

Then in a fragment shader combine the layers of the 2D array texture as desired.

You can also use multi-rendertargets by binding different texture layers to different render targets.

Upvotes: 4

Anton Guryanov
Anton Guryanov

Reputation: 12467

You can use MRT (multiple render targets). You will need to create and bind framebuffer (seems you already know how to do it), then attach several textures to it like

glFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texA, 0 );
glFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, texB, 0 );

Here I attached two textures (texA & texB, which were created using glGenTextures), as color attachments number 0 and 1. Then you just write your colors in shader using not gl_FragColor output variable, but rather gl_FragData[0] for the first color attachment and gl_FragData[1] for the second.

You can then use second pass to combine images stored in texA and texB textures.

P.S. these are the function calls for OpenGL 2. If you use OpenGL 3, the functions calls are similar (just without EXT), but you'll need to specify outputs for your shader manually. I can post the solution for this if necessary.

Upvotes: 3

Related Questions