I've reached another impasse I can't seem to resolve on my own. I really hope someone can help me out.
I've been trying to create a nice little bloom effect using GLSL, which worked quite well. When I tried including something moving into my scene I noticed that I forgot to clear my FBOs before rendering into them.
Without clearing it worked for never changing scenes because I was always using the same texture. With the glClear(); command it still works, but for the very first frame only, all I get after that is a black screen. So I guess my issue is that I can't get my FBOs to continuously be updated every frame.
I feel like I'm either missing something very obvious or doing something horribly wrong.
I'd be thankful for any suggestions you might have.
Here's what I get for the first frame:
Sources: (using openFrameworks)
setup:
void testApp::setup(){
ofSetVerticalSync(true);
ofDisableSetupScreen();
width = ofGetWidth();
height = ofGetHeight();
//complie/link/generate ShaderObjects ....
horizontalBlurFrag.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/fragment_shader_horizontal.glsl", GL_FRAGMENT_SHADER);
verticalBlurFrag.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/fragment_shader_vertical.glsl", GL_FRAGMENT_SHADER);
BlurVertex.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/horizontal_blur.glsl", GL_VERTEX_SHADER);
blendTextures.load("/opt/openframeworks/apps/examples/FBO_basic_shader_new_continued_v4_2/bin/data/blend_shader.glsl", GL_FRAGMENT_SHADER);
fboOriginal.initialize(width, height);
fboH800.initialize(width, height);
fboV800.initialize(width, height);
fboH400.initialize(width, height);
fboV400.initialize(width, height);}
draw:
void testApp::draw(){
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
//set orthographic projection
glOrtho( -1, 1, -1, 1, 1.0, 40.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, width, height);
glDisable(GL_TEXTURE_2D);
fboOriginal.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glPushMatrix();
glScalef(0.1f, 0.1f, 1.0f);
//generating values between 0 and 2
float x = 2 * (sin(time)+1.000001)/2;
//drawSOlidRect(xPos, yPos, width, height, red, green, blue);
drawSolidRect(-8.0f, 8.0f, x, x, 0.4f, 0.4f, 1.0f);
drawSolidRect(-5.0f, 8.0f, x, x, 0.4f, 1.0f, 0.4f);
drawSolidRect(-2.0f, 8.0f, x, x, 0.4f, 1.0f, 1.0f);
drawSolidRect( 1.0f, 8.0f, x, x, 1.0f, 0.4f, 0.4f);
drawSolidRect( 4.0f, 8.0f, x, x, 1.0f, 0.4f, 1.0f);
drawSolidRect( 7.0f, 8.0f, x, x, 1.0f, 1.0f, 0.4f);
glPopMatrix();
glPopAttrib();
fboOriginal.unbind();
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fboOriginal.fboTexture);
BlurVertex.enable();
horizontalBlurFrag.enable();
glUniform1i(glGetUniformLocation(horizontalBlurFrag.program, "RTScene"), 0);
glDisable(GL_TEXTURE_2D);
fboH800.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glPushMatrix();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
glDisable(GL_TEXTURE_2D);
fboH800.unbind();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fboH800.fboTexture);
BlurVertex.enable();
verticalBlurFrag.enable();
glUniform1i(glGetUniformLocation(verticalBlurFrag.program, "RTBlurH"), 0);
glDisable(GL_TEXTURE_2D);
fboV800.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width, height);
glPushMatrix();
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
fboV800.unbind();
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fboV800.fboTexture);
BlurVertex.enable();
horizontalBlurFrag.enable();
glUniform1i(glGetUniformLocation(horizontalBlurFrag.program, "RTScene"), 1);
glDisable(GL_TEXTURE_2D);
fboH400.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glPushMatrix();
glViewport(0, 0, width/4, height/4); //crude downscale
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
glDisable(GL_TEXTURE_2D);
fboH400.unbind();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fboH400.fboTexture);
BlurVertex.enable();
verticalBlurFrag.enable();
glUniform1i(glGetUniformLocation(verticalBlurFrag.program, "RTBlurH"), 1);
glDisable(GL_TEXTURE_2D);
fboV400.bind();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushAttrib(GL_VIEWPORT_BIT);
glPushMatrix();
glViewport(0, 0, width*4, height*4); //crude downscale
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glPopMatrix();
glPopAttrib();
glDisable(GL_TEXTURE_2D);
fboV400.unbind();
glBindTexture(GL_TEXTURE_2D, 0);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fboV800.fboTexture);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fboV400.fboTexture);
BlurVertex.enable();
blendTextures.enable();
glUniform1i(glGetUniformLocation(blendTextures.program, "originalSizeTex"), 0);
glUniform1i(glGetUniformLocation(blendTextures.program, "downscaledTex"), 1);
glDisable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, 1.0f);
glVertex3f(-1.0, 1.0, -1.0);
glMultiTexCoord2fARB(GL_TEXTURE0, 1.0f, 1.0f);
glVertex3f(1.0, 1.0, -1.0);
glMultiTexCoord2fARB(GL_TEXTURE0, 1.0f, 0.0f);
glVertex3f(1.0, -1.0, -1.0);
glMultiTexCoord2fARB(GL_TEXTURE0, 0.0f, 0.0f);
glVertex3f(-1.0, -1.0, -1.0);
glEnd();
glDisable(GL_TEXTURE_2D);}
FBO:
class FrameBufferObject{
public:
//handles
GLuint fbo, fboTexture, fboDepthbuffer;
public:
void initialize(GLuint width, GLuint height){
// generate namespace for the frame buffer, colorbuffer and depthbuffer
glGenFramebuffersEXT(1, &fbo);
glGenTextures(1, &fboTexture);
glGenRenderbuffersEXT(1, &fboDepthbuffer);
//switch to our fbo so we can bind stuff to it
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
//create the colorbuffer texture and attach it to the frame buffer
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fboTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glGenerateMipmapEXT(GL_TEXTURE_2D);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, fboTexture, 0);
// create a render buffer as our depthbuffer and attach it
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fboDepthbuffer);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24,width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fboDepthbuffer);
// Go back to regular frame buffer rendering
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_TEXTURE_2D);
}
void bind(){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
}
void unbind(){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
void clear(){
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}};
UPDATE:
The alpha value one the glClearColor at least seems to be part of my issue.
I tried messing around with it and what i got is this: (with up- and downscaling quads as you'd expect)
Somehow i seem to be losing all color somewhere along the way. Oddly enough i got the best result having (0, 0, 0, 0) for 4 of my FBOs and (0, 0, 0, 1) for one of them. Setting (0, 0, 0, 0) for all FBOs just yields a greyish picture (which i assume is the default window without anything in it).
Here's my "blending-together-shader":
uniform sampler2D originalSizeTex;
uniform sampler2D downscaledTex;
varying vec2 vTexCoord;
void main(void){
vec4 colorOriginal = vec4(0.0, 0.0, 0.0, 0.0);
vec4 colorDownscale = vec4(0.0, 0.0, 0.0, 0.0);
colorOriginal = texture2D(originalSizeTex, vTexCoord.xy);
colorDownscale = texture2D(downscaledTex, vTexCoord.xy);
gl_FragColor = vec4(colorOriginal + colorDownscale);
}
Any guesses?
Depends on how you're doing your blending, but -- you might need to set the clear color to 0,0,0,0 instead of 0,0,0,1 when you clear your FBO.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With