GLImageProcessing Multiple Filters?

后端 未结 2 1430
鱼传尺愫
鱼传尺愫 2020-12-17 05:06

I have read through this question here: Can example "GLImageProcessing" work with multi filters However, I still do not understand how to edit the sample code fo

相关标签:
2条回答
  • 2020-12-17 05:46

    I was able to combine multiple filters and here is complete method based on the suggestions made here.

    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();    
    }
    
    0 讨论(0)
  • 2020-12-17 05:54

    You can extend this scheme by alternating between two buffers:

    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);
    
    0 讨论(0)
提交回复
热议问题