c++ - openGL/GLSL : bloom/blur, 渲染到 FBO

标签 c++ opengl shader blur fbo

我又遇到了一个我自己似乎无法解决的僵局。我真的希望有人能帮助我。

我一直在尝试使用 GLSL 创建一个漂亮的小光晕效果,效果非常好。当我尝试在我的场景中加入一些移动的东西时,我注意到我忘记在渲染到它们之前清除我的 FBO。

没有清除它适用于从不改变场景,因为我总是使用相同的纹理。随着 glClear();命令它仍然有效,但仅对于第一帧,之后我得到的只是黑屏。所以我想我的问题是我无法让我的 FBO 在每一帧都持续更新。

我觉得我要么遗漏了一些非常明显的东西,要么做了一些非常错误的事情。

如果您有任何建议,我将不胜感激。

这是我得到的第一帧: enter image description here

来源: (使用开放框架)

设置:

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);}

绘制:

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);
    }};

更新:

至少 glClearColor 的 alpha 值似乎是我的问题的一部分。

我试着弄乱它,我得到的是: (如您所料,具有放大和缩小四边形)

enter image description here

不知怎么的,我似乎在某个地方失去了所有的颜色。 奇怪的是,我的 4 个 FBO 得到的最好结果是 (0, 0, 0, 0),其中一个是 (0, 0, 0, 1)。为所有 FBO 设置 (0, 0, 0, 0) 只会产生一个灰色图片(我假设这是默认窗口,里面没有任何东西)。

这是我的“混合着色器”:

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);
}

有什么猜测吗?

最佳答案

取决于您如何进行混合,但是——您可能需要在清除 FBO 时将清除颜色设置为 0,0,0,0 而不是 0,0,0,1。

关于c++ - openGL/GLSL : bloom/blur, 渲染到 FBO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5779593/

相关文章:

opengl - 正确变换表面法线

opengl - 在opengl中沿旋转方向移动

opengl - 如何通过opengl混合RGB和BGRA原始图像?

c++ - OpenGL/GLSL - 统一 block 数据值不正确

objective-c - OpenGL ES 2.0 多个网格? (只是真实世界的例子)

字符串比较的 C++ 奇怪行为

c++ - 模板基类的调用方法

c++ - 如何使用 Meego Touch Framework 创建 QT 插件?

c++ - 使用智能指针在窗口消息中将对象作为 WPARAM 传递

ios - 多重纹理的最有效方法-iOS,OpenGL ES2,优化