【问题标题】:Can example "GLImageProcessing" work with multi filters示例“GLImageProcessing”可以与多过滤器一起使用吗
【发布时间】:2011-04-29 10:55:44
【问题描述】:

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

【问题讨论】:

  • 有人请回答这个问题!我有同样的问题。
  • 为了提供更多信息,基本上这个应用程序提供了一组过滤器,它们是在openGL-es中实现的。演示应用程序只允许您一次应用这些过滤器之一。允许应用任意数量的这些过滤器的解决方案,或如何操作的描述,将非常有帮助。
  • 我现在正在使用更多的帧缓冲对象来解决这个问题。
  • Cylon - 想了解更多细节吗?
  • Allyn - 评论不要为我发送电子邮件。 Ozirus 的回答对这个问题非常有用。

标签: iphone opengl-es


【解决方案1】:

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

一种更通用的方法是使用帧缓冲区对象来逐字逐句地“渲染到纹理”,这将允许您应用任意数量的过滤器。这是另一个概述该技术的帖子的链接: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
...

【讨论】:

  • 感谢您的回答,我已经这样做了,现在我知道为什么我一次只能使用 2 个纹理。有没有获得最大纹理的功能?
  • 是的,您可以使用以下代码查询系统可用的纹理单元计数:glGetIntegerv( GL_MAX_TEXTURE_UNITS, &texture_unit_count );
  • 我通过模拟器和touch4的功能获得了8个
  • 感谢您的信息。正如我在消息中所写,我在第一代 iPhone 上只有两个...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-21
  • 2021-06-11
  • 1970-01-01
相关资源
最近更新 更多