Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
589 views
in Technique[技术] by (71.8m points)

iphone - GLImageProcessing Multiple Filters?

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 for GLImageProcessing to support multiple filters. Here is the code that I am doing now in drawGL of Imaging.c

Any help?

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();
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...