2010-12-07 14 views
9

GLImageProcessing örneğini kullanıyorum, ancak görüntüyü hem parlaklık hem de kontrast ile işleyemiyor, dolayısıyla hem parlaklığı hem de kontrastı ayarlamak için kodu yazarım, ancak bütün, kimse bu konuda bana yardımcı olabilir edebilir, Multitexturing kullanarak incelemeÖrneğin "GLImageProcessing" çoklu filtrelerle çalışabilir

//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

Biri bu soruya cevap lütfen! Bende aynı sorun var. – Allyn

+0

Biraz daha fazla bilgi vermek için, temel olarak bu uygulama, openGL-es'te uygulanan bir dizi filtreye sahiptir. Demo uygulaması, yalnızca bu filtrelerden birini tek seferde uygulamanıza izin verir. Bu filtrelerin herhangi bir sayısının uygulanmasına izin veren bir çözüm veya nasıl yapılacağının açıklaması çok yardımcı olacaktır. – Allyn

+0

Şimdi bu sorunla çalışmak için daha fazla framebufferobject kullanıyorum. – Cylon

cevap

12

için teşekkür ederim, bir geçişte hile yapacağını bu soruna bir çözüm bulmak mümkün olmalıdır. Ne yazık ki, ilk iPhone'un PowerVR MBX GPU'su, her iki filtreyi uygulamak için yeterli olmayacak olan 2 doku birimine (OpenGL ES 1.1 standardı için gereken minimum) sahiptir. Daha yeni donanımın sekiz doku birimine kadar olabileceğini düşünüyorum ve tek bir geçiş çözümü bulunabilir.

İstediğiniz kadar filtre uygulamanıza olanak tanıyan daha genel bir yaklaşım, tam anlamıyla "oluşturma işlemi" için çerçeve arabelleği nesneleri kullanmaktır. İşte tekniği özetleyen başka bir gönderinin bir bağlantısı: OpenGL ES Render to texture. Temel olarak, ilk resmi orijinal görüntüye uygulamanız ve sonucu bir dokuda (sistem tarafından sağlanan çerçeve arabelleği yerine) depolamanız gerekir. Ardından filtrelenmiş resmi içeren sonuç dokusunu bir sonraki filtre için girdi olarak kullanın ve yine dokuya işleyin. Zincirin son filtresine ulaşıncaya kadar tekrarlayın. Bu noktada, sonucu ekranda görüntüleyebilmek için, oluşturmayı yapmadan önce orijinal çerçeve arabelleği nesnesini geri yükleyin.

İşte 2 filtreler için bunu yapmak için bazı örnek kod:

// 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

Cevabınız için teşekkür ederim, bunu zaten yaptım ve şimdi neden sadece 2 dokuyu tek kullanabileceğimi biliyorum. Max dokular elde etmek için işlev var mı? – Cylon

+0

Evet, mevcut doku birimi sayımı için sistemi aşağıdaki kodla sorgulayabilirsiniz: glGetIntegerv (GL_MAX_TEXTURE_UNITS, & texture_unit_count); – Ozirus

+0

Her iki simülatör ve touch4 – Cylon