Apply brightness and contrast with OpenGL ES

I want to change the brightness and contrast of the texture on the iPhone. I looked at the sample provided by apple ( GLImageProcessing ), but it can only do it one at a time (calling both methods in the sample overwrites the previous result).

Brightness works fine:

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

How do I go with adding contrast to the texture after that? Alternatively, is it better to upgrade to OpenGL ES 2.0 and do it with shaders?

Here's the code for the contrast in the apple sample:

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

As you can guess, my experience with OpenGL (ES) is quite limited, so anything that points me in the right direction is very appreciated

+6
iphone image-processing opengl-es image-manipulation
source share
3 answers

You can display a brightness-adjustable image in a framebuffer texture of the same size, and then adjust the contrast when you render this texture on the screen.

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

Some useful reading for framebuffers and rendering to texture:

+1
source share

This is much easier to do with the fragment shader, at least in OpenGL 2.1 (I did not use OpenGL ES). The OpenGL Shader Language covers image processing in Chapter 19. They provide shaders for adjusting brightness and contrast. Here is my version that combines two and a half:

 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); } 

Edit: A few more details for completeness ...

Brightness and contrast have a base value of 1.0, so passing this value to both will leave the texture unchanged. A value less than 1.0 will decrease the brightness, and a value greater than 1.0 will increase it. A value less than 1.0 for contrast will make the texture more gray (less contrast), and a value greater than 1.0 will make it less gray (more contrast).

You can pass (0.5, 0.5, 0.5, 1.0) for AverageLuminance for a fast and dirty gray value, but the best results will be obtained by calculating the correct average brightness for your texture.

+7
source share

My GL is a little rusty, but from the sample code they create a texture that will blend in with the existing scene. Therefore, you can simply create both textures, making sure that they do not stomp on each other, and then mix them both in place. They do different things, although I doubt that you can combine them in the same texture. At first I ordered a contrast, because it is a more complex mixture.

0
source share

All Articles