2010-12-07 2 views
9

예제 GLImageProcessing을 사용하지만 밝기와 대비를 모두 사용하여 이미지를 처리 ​​할 수 ​​없으므로 밝기와 대비를 모두 조정하는 코드를 작성하지만 모든 사람이 이것에 대해 나에게 도움이 될 수 있습니다, 멀티 텍스처링을 사용하여 검토예제 "GLImageProcessing"은 멀티 필터와 함께 작동 할 수 있습니다.

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

누군가가이 질문에 대답하십시오! 나는 같은 문제가있다. – Allyn

+0

조금 더 많은 정보를 얻으려면 기본적으로이 응용 프로그램에는 OpenGL-es에서 구현되는 일련의 필터가 제공됩니다. 데모 앱을 사용하면 한 번에 이러한 필터 중 하나만 적용 할 수 있습니다. 많은 수의 필터를 적용 할 수있는 솔루션 또는 그렇게하는 방법에 대한 설명이 매우 유용 할 것입니다. – Allyn

+0

지금이 문제를 해결하기 위해 더 많은 framebuffer 개체를 사용하고 있습니다. – Cylon

답변

12

주셔서 감사합니다, 한 번에 트릭을 할 것입니다이 문제에 대한 해결책을 찾을 수 있어야한다. 불행하게도, 첫 아이폰의 PowerVR MBX GPU는 두 텍스처 유닛 (OpenGL ES 1.1 표준에서 요구되는 최소한의 것) 만 가지고있어서 두 필터를 모두 적용 할 수 없습니다. 더 최근의 하드웨어는 최대 8 개의 텍스처 단위를 가질 수 있으며 단일 패스 솔루션을 찾을 수 있다고 생각합니다.

원하는대로 많은 필터를 적용 할 수있는보다 일반적인 방법은 프레임 버퍼 객체를 문자 그대로 "렌더링 - 투 - 텍스처"로 사용하는 것입니다. 여기 기술을 설명하는 다른 게시물에 대한 링크가 있습니다 : OpenGL ES Render to texture.

기본적으로 원본 이미지에 첫 번째 필터를 적용하고 결과를 텍스처 제공 (시스템 제공 프레임 버퍼 대신)해야합니다. 그런 다음 필터링 된 이미지를 포함하는 결과 텍스처를 다음 필터의 입력으로 사용하고 다시 텍스처로 렌더링합니다. 체인의 마지막 필터에 도달 할 때까지 반복하십시오. 이 시점에서 화면에 결과를 표시하려면 렌더링을 수행하기 전에 원래 프레임 버퍼 객체를 복원하십시오.

여기에 2 개 필터 그것을 수행하는 방법에 대한 몇 가지 예제 코드는 다음과 같습니다

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

답변 해 주셔서 감사합니다. 이미이 작업을 수행했으며, 지금은 왜 한 번에 2 개의 텍스처 만 사용할 수 있는지 알고 있습니다. 텍스처가 최대가되는 기능이 있습니까? – Cylon

+0

예, 다음 코드를 사용하여 사용 가능한 텍스처 유닛 수를 시스템에 쿼리 할 수 ​​있습니다. glGetIntegerv (GL_MAX_TEXTURE_UNITS, & texture_unit_count); – Ozirus

+0

나는 simulator와 touch4 모두와 함께 함수를 사용하여 8을 얻었다. – Cylon

관련 문제