2011-06-21 1 views
3

私はここでこの質問を読んでいます:Can example "GLImageProcessing" work with multi filtersしかし、GLImageProcessingのサンプルコードを編集して複数のフィルタをサポートする方法はまだ分かりません。ここでは、Imaging.cのdrawGLで今行っているコードを示します。GLImage複数のフィルタを処理していますか?

何か助けがありますか?

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

答えて

2

次の2つのバッファ間で交互にこの方式を拡張することができます。

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

これはどこですか?私は「//ディスプレイフレームバッファーに使用されているFBOを記憶しています」から始まり、あなたのコードではまだ運がないことからすべてを置き換えました。 – Flipper

+1

最後のステップでは、フレームバッファの代わりに、もちろん画面に描画する必要があります。そのコード例を編集しました。 – datenwolf

+0

最初に読み込んだときに暗い黒い画像が残っています。スライダを動かすと、黒い部分が左側に、白い部分が右側に移動します。色相のような他の設定では、画像はそこにありますが、2回表示されます...そのうちの1つが反転します。何が起きているのか? – Flipper

1

私は複数のフィルタを組み合わせることができたし、ここでは、ここで作られた提案に基づいて、完全な方法です。

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();  
} 
関連する問題