Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can example "GLImageProcessing" work with multi filters

I use the example GLImageProcessing, but it can not process the image with both brightness and contrast, so i write the code to adjust both brightness and contrast, but it can't work at all, can anybody can help me about this, thank you for review

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


//bind result fbo
glBindFramebufferOES(GL_FRAMEBUFFER_OES, resultFBO);
glViewport(0, 0, result.wide*result.s, result.high*result.t);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_BLEND);



//process 1 adjust brightness
float t = 1.2;
glVertexPointer  (2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

static GLfloat constColor[4] = { 0.1, 0.2, 0.3, 0.4 };
if (t > 1.0f)
{
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_ADD);
    //glColor4f(t-1, t-1, t-1, t-1);
    constColor[0] = t-1;
    constColor[1] = t-1;
    constColor[2] = t-1;
    constColor[3] = t-1;
}
else
{
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_SUBTRACT);
    constColor[0] = 1-t;
    constColor[1] = 1-t;
    constColor[2] = 1-t;
    constColor[3] = 1-t;
}


glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor);

glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_CONSTANT);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_TEXTURE);


//process 2 adjust contrast
t = 1.6;
GLfloat h = t*0.5f;

// One pass using two units:
// contrast < 1.0 interpolates towards grey
// contrast > 1.0 extrapolates away from grey
//
// Here, the general extrapolation 2*(Src*t + Dst*(0.5-t))
// can be simplified, because Dst is a constant (grey).
// That results in: 2*(Src*t + 0.25 - 0.5*t)
//
// Unit0 calculates Src*t
// Unit1 adds 0.25 - 0.5*t
// Since 0.5*t will be in [0..0.5], it can be biased up and the addition done in signed space.
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
//glVertexPointer  (2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].x);
//glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &flipquad[0].s);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_PREVIOUS);


glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE2);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_ADD_SIGNED);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,     GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,        2);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_PREVIOUS);

glColor4f(h, h, h, 0.75 - 0.5 * h); // 2x extrapolation
validateTexEnv();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

//save to file
snapshot(result,"/test3.jpg");

// Restore state
glDisable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,     GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE,        1);
glActiveTexture(GL_TEXTURE0);
//process 3 adjust hue

//process 4 mask

//save to buffer

//bind system rbo
glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
glCheckError();
like image 317
Cylon Avatar asked Feb 03 '23 00:02

Cylon


1 Answers

Using multitexturing, it should be possible to find a solution to this problem that would do the trick in one pass. Unfortunately, the first iPhone's PowerVR MBX GPU only features 2 texture units (the minimum required by the OpenGL ES 1.1 standard) which would not be enough to apply both filters. I think more recent hardware can have up to eight texture units and a single pass solution could be found.

A more generic approach, that will allow you to apply as many filters as you want, is to use frame buffer objects to literally "render-to-texture". Here is a link to another post that outlines the technique: OpenGL ES Render to texture.

Basically, you must apply the first filter to the original image and store the result in a texture (instead of the system provided frame buffer). Then use the result texture which contains the filtered image as input for the next filter and, again, render to texture. Repeat until you reach the very last filter of the chain. At this point, restore the original frame buffer object before doing your rendering in order to be able to display the result on screen.

Here is some sample code on how to do it for 2 filters:

// 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, width, height, 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
...

// 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
...
like image 97
Ozirus Avatar answered Feb 05 '23 17:02

Ozirus