iDevGames Forums
Glow/bloom in OpenGL - Printable Version

+- iDevGames Forums (
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Glow/bloom in OpenGL (/thread-1836.html)

Glow/bloom in OpenGL - Jar445 - Jan 28, 2009 12:20 PM

I'm trying to figure out how to add a glow effect where certain areas of a model (individual polygons in my case). So far I think the general strategy is:
  1. Render the scene normally
  2. Render the regions I want to glow offscreen (to a frame buffer object?)
  3. Blur the image that has the glowing parts
  4. Render the image on top of the real scene (does that mean this image is a texture I drew to?)

Am I on the right track? Also note that I'm using shaders, though I'm fairly new at them.

Glow/bloom in OpenGL - TomorrowPlusX - Jan 28, 2009 03:48 PM

That's pretty much the trick. What you'll want to do is render the parts you want to glow in white ( or whatever color ) over black into an FBO.

You can blur the FBO pretty easily using two 1D gaussian kernels -- once horizontally, and once vertically. That's pretty important if you want to keep performance acceptable.

Than you can use additive blending ( glBlendFunc( GL_ONE, GL_ONE ) ) to draw the FBO atop the scene.

I'm happy to share my GLSL gaussian blur code if you're interested.

Glow/bloom in OpenGL - arekkusu - Jan 28, 2009 06:20 PM

Or, depending on your content, combine steps 1 and 2 by putting the glow factor into the destination alpha.

Glow/bloom in OpenGL - Jar445 - Jan 29, 2009 09:37 AM


Does this mean that I need three sets of shaders; one for drawing the scene, one for drawing the glowing parts to the FBO, and one for drawing the FBO contents on top of the scene?

Glow/bloom in OpenGL - arekkusu - Jan 30, 2009 10:21 AM

You've got (at least) three state vectors.

Glow/bloom in OpenGL - Jar445 - Jan 31, 2009 02:28 PM

Well, it doesn't help that I've never used frame buffer objects before. Nor have I used textures that much. Blush

To teach myself frame buffer objects I've been trying to render my scene to a texture then render a quad with that texture, but nothing shows up. This is how I'm trying to set things up, where the code is strewn about in an NSOpenGLView subclass:
GLuint fbo; // Frame buffer object
GLuint fboDepthbuffer; // Render buffer object

GLuint sceneTex; // Texture


// Set up the colour texture
glGenTextures(1, &sceneTex);
glBindTexture(GL_TEXTURE_2D, sceneTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 128, 128, 0,

glBindTexture(GL_TEXTURE_2D, 0);

// Set up the render buffer for depth testing
glGenRenderbuffersEXT(1, &fboDepthbuffer);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepthbuffer);
  128, 128);

glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

// Set up the frame buffer
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

  GL_TEXTURE_2D, sceneTex, 0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


// Resizing ----------------

int width = [self bounds].size.width;
int height = [self bounds].size.height;

if (height == 0)
    height = 1;

glViewport(0, 0, width, height);

GLdouble fAspect = (GLdouble)width / (GLdouble)height;


gluPerspective(fovy, fAspect, zNear, zFar);


// Drawing ----------------

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);

if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)



glClearColor(1.0, 0.0, 0.0, 1.0);

// Hopefully this will fill the texture red


glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

glClearColor(0.0, 0.0, 0.0, 1.0);


glBindTexture(GL_TEXTURE_2D, sceneTex);

    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(-10.0f, -10.0f);

    glTexCoord2f(1.0f, 0.0f);
    glVertex2f(10.0f, -10.0f);

    glTexCoord2f(1.0f, 1.0f);
    glVertex2f(10.0f, 10.0f);

    glTexCoord2f(0.0f, 1.0f);
    glVertex2f(-10.0f, 10.0f);

glFlush(); // By now I expect to see a red square on a black background, but I see no red at all

Glow/bloom in OpenGL - arekkusu - Jan 31, 2009 04:29 PM

Your framebuffer setup looks fine. But your quad drawing is at Z = 0, so it's probably clipped by your perspective projection. To debug, ignore the FBO stuff and just draw a white untextured quad.

Glow/bloom in OpenGL - Jar445 - Jan 31, 2009 06:13 PM

Yeah, it was just the location of my quad that was off.

Though it does raise the issue of how to effectively size my scene texture and draw it so that I cover the entire window, taking into account window resizing. For one thing, do you suppose it would make sense to call glOrtho2d before rendering the final texture quad?

Also, is it true that multisampling doesn't work when I'm drawing to a texture? I suppose a way to work around that, assuming I want full-screen antialiasing, is to either blur the scene in my fragment shader or to use mipmapping.

Glow/bloom in OpenGL - arekkusu - Jan 31, 2009 07:00 PM

How to draw the quad entirely depends on what you're trying to do. If you want to fill the entire window with a glow texture, a 2D ortho projection makes that easy. Equivalently, the identity projection matrix, with a quad sized to the unit square [-1, 1] will also fill the entire viewport.

Sizing the texture, taking into account aspect ratio etc, is something you'll need to experiment with to see what resolution ratio between window/offscreen is acceptable.

Multisampling does not work with textures, but EXT_framebuffer_multisample will let you create a multisample renderbuffer. You have to explicitly perform the downsample resolve using EXT_framebuffer_blit. These are fairly new extensions, and aren't supported on all hardware. An alternative way to get multisampled render-to-texture is to use NSOpenGLContext's createTexture:fromView:internalFormat: method. That will give you a texture from the view attached to the context, based on whatever pixel format the context is using, including multisampling. It will implicitly do the resolve for you, like regular multisampling. And it works on all renderers that support multisampling (which sadly, doesn't include the Intel GMA renderers in MacBooks/iMacs/Minis.)

If you need some sort of antialiasing even on renderers that don't support multisampling, you can do your own supersampling, by rendering to a texture 2x larger than your target size and then drawing it with linear filtering. You can also mix this technique with regular multisampling, to get more than the 4 or 8 samples the hardware supports.