Может ли пример "GLImageProcessing" работать с несколькими фильтрами - PullRequest
9 голосов
/ 07 декабря 2010

Я использую пример GLImageProcessing, но он не может обработать изображение с яркостью и контрастностью, поэтому я пишу код для регулировки яркости и контрастности, но он не может работать вообще, кто-нибудь может мне помочь с этимСпасибо за отзыв

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

1 Ответ

12 голосов
/ 27 декабря 2010

Используя мультитекстурирование, должна быть возможность найти решение этой проблемы, которое решило бы проблему за один проход.К сожалению, первый iPhone PowerVR MBX GPU имеет только 2 текстурных блока (минимум, требуемый стандартом OpenGL ES 1.1), которого будет недостаточно для применения обоих фильтров.Я думаю, что более новое оборудование может иметь до восьми текстурных блоков, и может быть найдено решение за один проход.

Более общий подход, который позволит вам применять столько фильтров, сколько вы хотите, состоит в использовании буфера кадров.объекты буквально "рендеринг в текстуру".Вот ссылка на другой пост, в котором излагается техника: OpenGL ES Визуализация на текстуру .

По сути, вы должны применить первый фильтр к исходному изображению и сохранить результат в текстуре (вместо системы предусмотрен буфер кадров).Затем используйте результирующую текстуру, которая содержит отфильтрованное изображение, в качестве входных данных для следующего фильтра и, снова, визуализируйте в текстуру.Повторяйте, пока не дойдете до самого последнего фильтра цепи.На этом этапе восстановите исходный объект буфера кадров перед выполнением рендеринга, чтобы иметь возможность отображать результат на экране.

Вот пример кода о том, как это сделать для 2 фильтров:

// 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
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...