代码之家  ›  专栏  ›  技术社区  ›  Antti

opengl es中亮度与对比度的应用

  •  6
  • Antti  · 技术社区  · 15 年前

    我想改变亮度 对比iPhone上的纹理。我一直在看苹果公司提供的样品( GLImageProcessing )但它一次只能执行一个操作(调用示例中的两个方法将覆盖以前的结果)。

    亮度很好:

    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
    if (brightness >= 1.0f) {
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
        glColor4f(brightness-1, brightness-1, brightness-1, brightness-1);
    } else {
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_SUBTRACT);
        glColor4f(1-brightness, 1-brightness, 1-brightness, 1-brightness);
    }
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
    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_TEXTURE);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    

    在这之后我该如何添加纹理对比度呢?或者,迁移到opengl es 2.0并对着色器执行此操作是一个更好的选择吗?

    以下是苹果公司的样品对比代码:

    glActiveTexture(GL_TEXTURE0);
    glVertexPointer  (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x);
    glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[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_TEXTURE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
    glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
    glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
    
    glActiveTexture(GL_TEXTURE1);
    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);
    
    // 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);
    

    你可能猜到我用OpenGL(ES)的经验是非常有限的,所以任何指向我正确方向的东西都是非常值得赞赏的。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Community CDub    8 年前

    可以将亮度调整后的图像渲染为相同大小的帧缓冲区纹理,然后在将该纹理渲染到屏幕时执行对比度调整。

    Image -> [Brightness] -> Texture -> [Contrast] -> Screen
    

    对帧缓冲区和渲染到纹理的一些有用的读取:

        2
  •  7
  •   Incredulous Monk    15 年前

    使用片段着色器要容易得多,至少在opengl 2.1中是这样(我还没有使用opengl es)。“opengl着色语言”一书涵盖了第19章中的图像处理。它们提供用于调整亮度和对比度的阴影。这是我的版本,它结合了两个半:

    uniform sampler2D Texture;
    uniform float Brightness;
    uniform float Contrast;
    uniform vec4 AverageLuminance;
    
    void main(void)
    {
       vec4 texColour = texture2D(Texture, gl_TexCoord[0].st);
       gl_FragColor = mix(texColour * Brightness, 
          mix(AverageLuminance, texColour, Contrast), 0.5);
    }
    

    编辑: 为了更完整一些细节…

    亮度和对比度的基础值为1.0,因此如果同时传递这两个值,纹理将保持不变。小于1.0的值将降低亮度,大于1.0的值将增加亮度。对于对比度,小于1.0的值将使纹理更为灰色(对比度较低),大于1.0的值将使纹理更为灰色(对比度较高)。

    你可以将平均值(0.5,0.5,0.5,1)传递给一个快速和肮脏的灰色值,但是通过计算一个合适的平均亮度来获得更好的结果。

        3
  •  0
  •   Ben Lachman    15 年前

    我的gl有点生疏,但从示例代码来看,它们都创建了一个与现有场景混合的纹理。因此你可以创造 二者都 质地,确保它们不会互相踩踏 然后 把它们混合在一起。不过,它们做的事情不同,所以我怀疑你能否将它们组合在同一个纹理中。我会先点对比度,因为它是一种更复杂的混合。