Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting up OpenGL Multiple Render Targets

Tags:

I've seen a lot of material on this subject, but there are some differences between the examples I've found and I'm having a hard time getting a solid understanding of the correct process. Hopefully someone can tell me if I'm on the right track. I should also mention I'm doing this on OS X Snow Leopard and the latest version of Xcode 3.

For the sake of example, let's say that I want to write to two targets, one for normal and one for color. To do this I create one framebuffer and bind two textures to it, as well as a depth texture:

glGenFramebuffersEXT(1, &mFBO); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);  glGenTextures(1, &mTexColor); glBindTexture(GL_TEXTURE_2D, mTexColor); //<texture params> glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexColor, 0);  glGenTextures(1, &mTexNormal); glBindTexture(GL_TEXTURE_2D, mTexNormal); //<Texture params> glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mTexNormal, 0);  glGenTextures(1, &mTexDepth); glBindTexture(GL_TEXTURE_2D, mTexDepth); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, mTexDepth, 0);  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) 

Before rendering, I would bind the framebuffer again and then do:

GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; glDrawBuffers(2, buffers); 

This would mean further draw calls would draw to my framebuffer. (I think?)

I'd then set my shaders and draw the scene. In my vertex shader I would process normals/positions/colors as usual, and pass the data to the fragment shader. The fragment would then do something like:

gl_FragData[0] = OutputColor; gl_FragData[1] = OutputNormal; 

At this point, I should have two textures; one with colors from all the rendered objects and one with normals. Is all of this correct? I should now be able to use those textures like any other, say rendering them to a fullscreen quad, right?

like image 607
TaylorP Avatar asked Aug 26 '11 15:08

TaylorP


People also ask

What is multiple render targets OpenGL?

In the field of 3D computer graphics, Multiple Render Targets, or MRT, is a feature of modern graphics processing units (GPUs) that allows the programmable rendering pipeline to render images to multiple render target textures at once.

What is framebuffer OpenGL?

A Framebuffer is a collection of buffers that can be used as the destination for rendering. OpenGL has two kinds of framebuffers: the Default Framebuffer, which is provided by the OpenGL Context; and user-created framebuffers called Framebuffer Objects (FBOs).

How do I render FBO?

Basically the steps are: Create FBO with depth renderbuffer and color texture attachment. To render to FBO unbind the target texture, bind FBO, render to FBO. Unbind FBO, bind texture, render. Show activity on this post.

What is a render pass OpenGL?

In multipass techniques, you render the same "object" multiple times, with each rendering of the object doing a separate computation that gets accumulated into the final value. Each rendering of the object with a particular set of state is called a "pass" or "render pass".


1 Answers

Sounds and looks reasonable. This is indeed the common way to do it. If you don't need the depth data as texture for further processing, you can also use a renderbuffer for an attachment, but a texture should also work fine.

You can also use glCheckFramebufferStatusEXT after all the setup is done, to see if the framebuffer is valid in its current configuration, but your code looks fine. If you don't have a problem and this was just for assurance, then rest assured that you're on the right track, otherwise tell us what's wrong.

like image 189
Christian Rau Avatar answered Sep 28 '22 20:09

Christian Rau