【问题标题】:GLImageProcessing Multiple Filters?GLImageProcessing 多个过滤器?
【发布时间】:2011-09-13 06:05:44
【问题描述】:

我在这里阅读了这个问题:Can example "GLImageProcessing" work with multi filters 但是,我仍然不明白如何编辑 GLImageProcessing 的示例代码以支持多个过滤器。这是我现在在 Imaging.c 的 drawGL 中所做的代码

有什么帮助吗?

void drawGL(int wide, int high, float val, int mode)
{
    GLuint ResultFBO;
    GLuint ResultTexture;
    static int prevmode = -1;
    typedef void (*procfunc)(V2fT2f *, float);

    typedef struct {
        procfunc func;
        procfunc degen;
    } Filter;

    const Filter filter[] = {
        { brightness             },
        { contrast               },
        { extrapolate, greyscale },
        { hue                    },
        { extrapolate, blur      }, // The blur could be exaggerated by downsampling to half size
    };
#define NUM_FILTERS (sizeof(filter)/sizeof(filter[0]))
    rt_assert(mode < NUM_FILTERS);


    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0, wide, 0, high, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glScalef(wide, high, 1);

    glBindTexture(GL_TEXTURE_2D, Input.texID);

    // Remember the FBO being used for the display framebuffer
    glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *)&SystemFBO);

    // Create the texture and the FBO the will hold the result of applying the first filter
    glGenTextures(1, &ResultTexture);
    glBindTexture(GL_TEXTURE_2D, ResultTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wide, high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glGenFramebuffersOES(1, &ResultFBO);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultFBO);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, ResultTexture, 0);

    // bind the result FBO
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultFBO);


    // apply 1st filter
    glViewport(0, 0, wide, high);
    filter[mode].func(flipquad, val);

    // restore original frame buffer object
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);

    // use ResultTexture as input for the 2nd filter
    glBindTexture(GL_TEXTURE_2D, ResultTexture);

    // apply 2nd filter
    glViewport(0, 0, wide, high);
    filter[2].func(flipquad, val);

    glCheckError();
}

【问题讨论】:

    标签: iphone opengl-es filter


    【解决方案1】:

    您可以通过在两个缓冲区之间交替来扩展此方案:

    GLuint stageTextures[2];
    glGenTextures(2, stageTextures);
    
    glBindTexture(GL_TEXTURE_2D, stageTexture[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wide, high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    
    glBindTexture(GL_TEXTURE_2D, stageTexture[1]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wide, high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    
    GLuint stageFBO[2];
    glGenFramebuffersOES(2, stageFB0);
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, stageFBO[0]);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, stageTexture[0], 0);    
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, stageFBO[1]);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, stageTexture[1], 0);    
    
    // bind stage 1, sourcing stage 0
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, stageFBO[1]);
    glBindTexture(GL_TEXTURE_2D, stageTexture[0]);
    
    // apply 1st filter
    glViewport(0, 0, wide, high);
    filter[mode].func(flipquad, val);
    
    glBindTexture(GL_TEXTURE_2D, 0); // must unbind texture before FBO with that texture attached can be bound
    
    
    // bind stage 0, sourcing stage 1
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, stageFBO[0]);
    glBindTexture(GL_TEXTURE_2D, stageTexture[1]);
    
    // apply 2nd filter
    glViewport(0, 0, wide, high);
    filter[mode].func(flipquad, val);
    
    glBindTexture(GL_TEXTURE_2D, 0); // must unbind texture before FBO with that texture attached can be bound
    
    // bind stage 1, sourcing stage 0
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, stageFBO[1]);
    glBindTexture(GL_TEXTURE_2D, stageTexture[0]);
    
    // apply 3rd filter
    glViewport(0, 0, wide, high);
    filter[mode].func(flipquad, val);
    
    glBindTexture(GL_TEXTURE_2D, 0); // must unbind texture before FBO with that texture attached can be bound
    
    // and so on. finally
    
    // Bind SystemFBO so the screen is the target, sourcing stage 0/1
    // (depending on if a even or odd number of filters involved)
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
    glBindTexture(GL_TEXTURE_2D, stageTexture[...]); // set to follow the scheme above
    
    // apply n-th filter
    glViewport(0, 0, wide, high);
    filter[mode].func(flipquad, val);
    

    【讨论】:

    • 那么这到底会去哪里呢?我用你的代码替换了从“//记住用于显示帧缓冲区的FBO”开始的所有内容,但仍然没有运气。
    • 在最后一步中,您当然必须绘制到屏幕上,而不是帧缓冲区。我编辑了那个代码示例。
    • @Flipper:我能想到很多事情。您可以看到某些东西的事实意味着过滤器链正在工作。现在您可能会遇到一些不幸的过滤器组合和排序。由于我手头既没有 iOS 设备也没有模拟器,所以很难重现。
    • @Flipper:我真的不知道。那些代码 sn-ps 也不包含实际的过滤器代码,它们只是引用了一些函数。如果您也添加这些内容,或者至少提供一个 URL,我可以在其中获取您调整的原始代码,那就太好了。然后我可以将它移植到基于 PC 的 OpenGL 上并对此进行测试。
    • @Flipper:原始代码使用辅助辅助纹理,在您的代码 sn-p(s) 中不可见。这改变了要采取的整个方法!给我一些时间将该程序移植到我的系统并进行修改。
    【解决方案2】:

    我能够组合多个过滤器,这是基于此处提出的建议的完整方法。

    void drawGL(int wide, int high, float val, int mode)
    {
    
        static int prevmode = -1;
        typedef void (*procfunc)(V2fT2f *, float);
    
        typedef struct {
                procfunc func;
                procfunc degen;
        } Filter;
    
        const Filter filter[] = {
                { brightness             },
                { contrast               },
                { extrapolate, greyscale },
                { hue                    },
                { extrapolate, blur      },        // The blur could be exaggerated by downsampling to half size
        };
        #define NUM_FILTERS (sizeof(filter)/sizeof(filter[0]))
        rt_assert(mode < NUM_FILTERS);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrthof(0, wide, 0, high, -1, 1);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glScalef(wide, high, 1);
    
    glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *)&SystemFBO);
    // Create the texture and the FBO the will hold the result of applying the first filter
    glGenTextures(1, &ResultTexture.texID);
    glBindTexture(GL_TEXTURE_2D, ResultTexture.texID);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, wide, high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    glGenFramebuffersOES(1, &ResultTextureFBO);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultTextureFBO);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, ResultTexture.texID, 0);
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, ResultTextureFBO);
    glBindTexture(GL_TEXTURE_2D, Input.texID);
    
        glViewport(0, 0, wide, high);
    brightness(flipquad, val);
        glCheckError();
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
    glBindTexture(GL_TEXTURE_2D, ResultTexture.texID);
    
        glViewport(0, 0, wide, high);
    hue(fullquad, val);
        glCheckError();    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-19
      • 2019-06-19
      • 1970-01-01
      • 1970-01-01
      • 2020-10-25
      • 2016-08-10
      相关资源
      最近更新 更多