another question about OpenGL ES rendering to texture

Posted by ensoreus on Stack Overflow See other posts from Stack Overflow or by ensoreus
Published on 2010-05-04T11:42:08Z Indexed on 2010/05/04 11:48 UTC
Read the original article Hit count: 246

Hello, pros and gurus!

Here is another question about rendering to texture.

The whole stuff is all about saving texture between passing image into different filters. Maybe all iPhone developers knows about Apple's sample code with OpenGL processing where they used GL filters(functions), but pass into them the same source image. I need to edit an image by passing it sequentelly with saving the state of the image to edit. I am very noob in OpenGL, so I spent increadibly a lot of to solve the issue. So, I desided to create 2 FBO's and attach source image and temporary image as a textures to render in.

Here is my init routine:

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glEnable(GL_TEXTURE_2D); 
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *)&SystemFBO); 

    glImage = [self loadTexture:preparedImage]; //source image      

    for (int i = 0; i < 4; i++)
    {
        fullquad[i].s *= glImage->s; 
        fullquad[i].t *= glImage->t; 
        flipquad[i].s *= glImage->s; 
        flipquad[i].t *= glImage->t; 
    }

    tmpImage = [self loadEmptyTexture]; //editing image
    glGenFramebuffersOES(1, &tmpImageFBO);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, tmpImageFBO);
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tmpImage->texID, 0);
    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); 
    if(status != GL_FRAMEBUFFER_COMPLETE_OES) {
        NSLog(@"failed to make complete tmp framebuffer object %x", status);
    }


    glBindTexture(GL_TEXTURE_2D, 0);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

    glGenRenderbuffersOES(1, &glImageFBO);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, glImageFBO); 
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, glImage->texID, 0);
    status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) ; 
    if(status != GL_FRAMEBUFFER_COMPLETE_OES) { 
        NSLog(@"failed to make complete cur framebuffer object %x", status); 
    } 

    glBindTexture(GL_TEXTURE_2D, 0);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

When user drag the slider, this routine invokes to apply changes

-(void)setContrast:(CGFloat)value{
contrast = value;
if(flag!=mfContrast){
    NSLog(@"contrast: dumped");
    flag = mfContrast;
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, glImageFBO);
    glClearColor(1,1,1,1);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0, 512, 0, 512, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glScalef(512, 512, 1);
    glBindTexture(GL_TEXTURE_2D, tmpImage->texID);
    glViewport(0, 0, 512, 512);
    glVertexPointer(2, GL_FLOAT, sizeof(V2fT2f), &fullquad[0].x);
    glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &fullquad[0].s);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
}

glBindFramebufferOES(GL_FRAMEBUFFER_OES,tmpImageFBO);

glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, 512, 0, 512, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(512, 512, 1);

glBindTexture(GL_TEXTURE_2D, glImage->texID);
glViewport(0, 0, 512, 512);
[self contrastProc:fullquad value:contrast];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
[self redraw];

}

Here are two cases: if it is the same filter(edit mode) to use, I bind tmpFBO to draw into tmpImage texture and edit glImage texture. contrastProc is a pure routine from Apples's sample. If it is another mode, than I save edited image by drawing tmpImage texture in source texture glImage, binded with glImageFBO. After that I call redraw:

glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, kTexWidth, 0, kTexHeight, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(kTexWidth, kTexHeight, 1);
glBindTexture(GL_TEXTURE_2D, glImage->texID);

glViewport(0, 0, kTexWidth, kTexHeight);
glVertexPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);

And here it binds visual framebuffer and dispose glImage texture.

So, the result is VERY aggresive filtering. Increasing contrast volume by just 0.2 brings image to state that comparable with 0.9 contrast volume in Apple's sample code project. I miss something obvious, I guess. Interesting, if I disabple line

glBindTexture(GL_TEXTURE_2D, glImage->texID);

in setContrast routine it brings no effect. At all. If I replace tmpImageFBO with SystemFBO to draw glImage directly on display(and disabling redraw invoking line), all works fine.

Please, HELP ME!!! :(

© Stack Overflow or respective owner

Related posts about opengl-es

Related posts about iphone