8:30 – FP
 I think I found GLSL documentation! http://www.opengl.org/sdk/docs/manglsl/
 A working convolution filter that blurs anything above a certain luminance:

#version 150 // glow.fs // outputs the color negative of a texture // in vec2 vTexCoord; uniform int screenWidth; uniform int screenHeight; uniform sampler2D textureUnit0; vec4 getTexOffset(const sampler2D texUnit, const vec2 texCoord, const float dx, const float dy){ vec2 offset = texCoord + vec2(dx, dy); return texture(textureUnit0, offset); } void main(void) { float dx = 1.0 / float(screenWidth); float dy = 1.0 / float (screenHeight); float x; float y; vec4 blurSum = vec4(0, 0, 0, 0); float patchSize = 4.0; float xmin = patchSize*dx; float xmax = patchSize*dx+dx*0.5; float ymin = patchSize*dy; float ymax = patchSize*dy+dx*0.5; float count = 0; for(x = xmin; x < xmax; x += dx){ for(y = ymin; y < ymax; y += dy){ blurSum += getTexOffset(textureUnit1, vTexCoord, x, y); if(count > 1000){ discard; } count += 1.0; } } float weight = 1.0/count; vec4 blured = vec4(blurSum.r*weight, blurSum.g*weight, blurSum.b*weight, 1.0); vec4 sharp = texture(textureUnit0, vTexCoord); float luminance = blured.r + blured.g + blured.b; if(luminance > 1.0){ gl_FragColor = blured; }else{ gl_FragColor = sharp; } }
 And here’s the picture it produces. Note the sharp moon and gridlines with the blurry sun đź™‚
 Next on the hit parade, add a test to see if the corners of the convolution filter touch anything above the luminance threshold and discard if it doesn’t. My guess is that should speed up things a lot. Done. Discovered that there are some odd problems that crop up as the screen gets made quite large. This could have something to do with the fact that I’m not checking to see that the convolution patch’s coordinates can run off the texture (i.e not clamped between 0.0 and 1.0)?
 Migrate the screen drawing to a DrawableObject class. I’m pretty sure it should work there, as long as it’s called after postDraw3D(). In fact, it should be possible to have multiple screen drawing classes, though I’m not sure why.
 Add shader directory to svn repo – done
 And it appears that after a while, something is clogging the graphics pipeline, because the drawing slows way done. This does look like it’s due to the shader, as the neg.fs doesn’t seem to be slowing things down. Yep, Â adding clamping to the glow.fs shader fixed that problem. Still have the problem where the screen texture gets messed up if the window gets too big…
 So here’s the better version of the fragment shader

#version 150 // glow.fs // outputs the color negative of a texture // in vec2 vTexCoord; uniform int screenWidth; uniform int screenHeight; uniform sampler2D textureUnit0; void luminanceTest(const sampler2D texUnit, const vec2 texCoord, const float xmin, const float xmax, const float ymin, const float ymax, const float luminance){ vec2 ll = clamp(texCoord + vec2(xmin, ymin), 0.0, 1.0); vec2 lr = clamp(texCoord + vec2(xmax, ymin), 0.0, 1.0); vec2 ur = clamp(texCoord + vec2(xmax, ymax), 0.0, 1.0); vec2 ul = clamp(texCoord + vec2(xmin, ymax), 0.0, 1.0); vec4 total = texture(texUnit, ll); total += texture(texUnit, lr); total += texture(texUnit, ur); total += texture(texUnit, ul); float weight = 1.0/4.0; float val = (total.r + total.g + total.b)*weight; if(val < luminance){ discard; } } vec4 getTexOffset(const sampler2D texUnit, const vec2 texCoord, const float dx, const float dy){ vec2 offset = texCoord + vec2(dx, dy); clamp(offset, 0.0, 1.0); return texture(texUnit, offset); } void main(void) { float dx = 1.0 / float(screenWidth); float dy = 1.0 / float (screenHeight); float x; float y; vec4 blurSum = vec4(0, 0, 0, 0); float patchSize = 4.0; float xmin = patchSize*dx; float xmax = patchSize*dx+dx*0.5; float ymin = patchSize*dy; float ymax = patchSize*dy+dx*0.5; float count = 0; luminanceTest(textureUnit0, vTexCoord, xmin, xmax, ymin, ymax, 1.0); for(x = xmin; x < xmax; x += dx){ for(y = ymin; y < ymax; y += dy){ blurSum += getTexOffset(textureUnit0, vTexCoord, x, y); if(count > 1000){ discard; } count += 1.0; } } vec4 sharp = texture(textureUnit0, vTexCoord); float weight = 1.0/count; vec4 blured = vec4(blurSum.r*weight, blurSum.g*weight, blurSum.b*weight, sharp.a); float luminance = blured.r + blured.g + blured.b; if(luminance > 1.0){ gl_FragColor = blured; }else{ gl_FragColor = sharp; } }