iphone - 示例 "GLImageProcessing"可以与多个过滤器一起使用吗

标签 iphone opengl-es

我使用示例 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();

最佳答案

使用多重纹理,应该可以找到解决这个问题的方法,一次性解决这个问题。不幸的是,第一代 iPhone 的 PowerVR MBX GPU 仅具有 2 个纹理单元(OpenGL ES 1.1 标准所需的最小值),这不足以应用这两个滤镜。我认为更新的硬件最多可以有八个纹理单元,并且可以找到单 channel 解决方案。

一种更通用的方法,允许您应用任意数量的过滤器,是使用帧缓冲区对象来“渲染到纹理”。这是另一篇概述该技术的文章的链接:OpenGL ES Render to texture .

基本上,您必须将第一个过滤器应用于原始图像并将结果存储在纹理中(而不是系统提供的帧缓冲区)。然后使用包含已过滤图像的结果纹理作为下一个过滤器的输入,并再次渲染到纹理。重复此操作,直到到达链中的最后一个过滤器。此时,在进行渲染之前恢复原始帧缓冲区对象,以便能够在屏幕上显示结果。

以下是一些关于如何对 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
...

关于iphone - 示例 "GLImageProcessing"可以与多个过滤器一起使用吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4375479/

相关文章:

iphone - 来自另一个开发者帐户的 iTunes Connect 和 bundle ID

iphone - 我如何在我们的应用程序中访问日历事件和计划事件?

ios - iTunes Connect 中用于应用审查的虚拟帐户

ios - 简单的读/写文件方法来访问数字数据?

android - 使用其他方法创建等效的 GL_MAX 混合方程

iphone - NSMutableArray 中的 indexOfObject 返回垃圾值

iphone - 使用 Core Graphics 的优势

android - gluUnProject 总是返回零

ios - 在 IOS 上显示 YUV(yuv420p) 不正确

iphone - iOS 上带有 OpenGL ES 的天空盒 - 无 GLKit + iOS 5.0