2009-10-01 11 views
6

Je veux changer la luminosité et contraste d'une texture sur l'iPhone. J'ai regardé l'exemple fourni par apple (GLImageProcessing) mais il est seulement capable de faire un à la fois (appeler les deux méthodes dans l'échantillon écrase le résultat précédent).Appliquer la luminosité et le contraste avec OpenGL ES

Luminosité fonctionne très bien:

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

Comment puis-je aller à l'ajout de contraste à la texture après? Alternativement serait-il un meilleur choix pour passer à OpenGL ES 2.0 et le faire avec les shaders?

est ici le code de contraste dans l'échantillon de la pomme:

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

Comme vous pouvez probablement deviner mon expérience avec OpenGL (ES) est assez limité donc tout ce qui me pointe dans la bonne direction est très apprécié

+0

Bonjour Antti, avez-vous trouvé un solution à votre problème? J'aimerais savoir aussi. Merci d'avance! –

Répondre

7

Cela est beaucoup plus facile à faire avec un fragment shader, au moins dans OpenGL 2.1 (je n'ai pas utilisé OpenGL ES). Le livre "OpenGL Shading Language" couvre le traitement des images au chapitre 19. Ils donnent des shaders pour ajuster la luminosité et le contraste. Voici ma version, qui combine les deux demi-et-moitié:

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: quelques détails pour l'exhaustivité ...

Luminosité et contraste ont une valeur de base de 1.0, en passant que pour les deux laissera la texture inchangée. Une valeur inférieure à 1.0 diminue la luminosité et une valeur supérieure à 1.0 l'augmente. Une valeur inférieure à 1.0 pour le contraste rendra la texture plus grise (moins de contraste), et une valeur supérieure à 1.0 la rendra moins grise (plus de contraste).

Vous pouvez passer (0,5, 0,5, 0,5, 1,0) pour AverageLuminance pour une valeur de gris rapide et sale, mais de meilleurs résultats seront obtenus en calculant une luminance moyenne correcte pour votre texture.

+0

Je préfère m'en tenir à OpenGL ES 1.1 (en raison de la prise en charge des périphériques), qui ne prend pas en charge les shaders fragmentés. Des pensées sur ce faire sans shaders? Merci pour cela, il est bon d'avoir une sauvegarde – Antti

+0

De rien. Cela m'a donné une bonne excuse pour en faire plus avec les shaders :-) Désolé, je ne serai probablement pas d'une grande aide avec une solution non-shader. Les combinateurs de textures me donnent mal à la tête dans le meilleur des cas, et ceux d'Apple sont plutôt horribles. –

0

Mon GL est un peu rouillé, mais à partir de l'exemple de code, ces deux éléments créent une texture pour se fondre dans la scène existante. Par conséquent, vous pouvez simplement créer les deux textures, en veillant à ce qu'ils ne se piétinent pas les uns les autres et puis mélangez les deux en place. Ils font des choses différentes, donc je doute que vous serez en mesure de les combiner dans la même texture. Je commanderais le contraste d'abord puisque c'est un mélange plus compliqué.

Questions connexes