2010-12-07 18 views
9

J'utilise l'exemple GLImageProcessing, mais il ne peut pas traiter l'image à la fois avec la luminosité et le contraste, donc j'écris le code pour ajuster la luminosité et le contraste, mais il ne peut pas fonctionner à tout, peut quelqu'un peut me aider à ce sujet, je vous remercie pour examenL'exemple "GLImageProcessing" fonctionne avec plusieurs filtres

//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(); 
+0

Quelqu'un s'il vous plaît répondre à cette question! J'ai le même problème. – Allyn

+0

Pour donner un peu plus d'informations, en gros cette application a un ensemble de filtres fournis, qui sont implémentés dans openGL-es. L'application de démonstration vous permet seulement d'appliquer l'un de ces filtres à la fois. Une solution permettant d'appliquer un nombre quelconque de ces filtres, ou la description de la façon de le faire, serait très utile. – Allyn

+0

J'utilise plus framebufferobject pour travailler avec ce problème maintenant. – Cylon

Répondre

12

l'utilisation du multitexturing, il devrait être possible de trouver une solution à ce problème qui ferait l'affaire en une seule passe. Malheureusement, le GPU PowerVR MBX du premier iPhone ne dispose que de 2 unités de texture (le minimum requis par la norme OpenGL ES 1.1), ce qui ne suffirait pas à appliquer les deux filtres. Je pense que le matériel plus récent peut avoir jusqu'à huit unités de texture et une solution à un seul passage pourrait être trouvée.

Une approche plus générique, qui vous permettra d'appliquer autant de filtres que vous le souhaitez, consiste à utiliser littéralement des objets de frame buffer pour "render-to-texture". Voici un lien vers un autre article qui décrit la technique: OpenGL ES Render to texture.

Fondamentalement, vous devez appliquer le premier filtre à l'image d'origine et stocker le résultat dans une texture (au lieu du tampon de trame fourni par le système). Ensuite, utilisez la texture de résultat qui contient l'image filtrée en entrée pour le filtre suivant et, à nouveau, rendez la texture. Répétez jusqu'à ce que vous atteigniez le tout dernier filtre de la chaîne. À ce stade, restaurez l'objet tampon d'image d'origine avant d'effectuer votre rendu afin de pouvoir afficher le résultat à l'écran.

Voici quelques exemples de code sur la façon de le faire pour 2 filtres:

// 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 
... 
+0

je vous remercie pour votre réponse, je l'ai déjà fait avec cela, et maintenant je sais pourquoi je ne peux utiliser que 2 textures une fois. Y at-il une fonction pour obtenir des textures max? – Cylon

+0

Oui, vous pouvez demander au système le nombre d'unités de texture disponibles à l'aide du code suivant: glGetIntegerv (GL_MAX_TEXTURE_UNITS, & texture_unit_count); – Ozirus

+0

j'ai eu 8 en utilisant la fonction avec simulateur et touch4 – Cylon