2010-12-07 10 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で実装されています。デモアプリケーションでは、一度にこれらのフィルタの1つだけを適用することができます。任意の数のこれらのフィルタを適用できるようにするためのソリューション、またはその方法の説明は非常に役に立ちます。 – Allyn

+0

私は今、この問題を扱うために、より多くのframebufferオブジェクトを使用しています。 – Cylon

答えて

12

をありがとうございました、1回のパスでトリックを行うだろう、この問題に対する解決策を見つけることが可能でなければなりません。残念なことに、最初のiPhoneのPowerVR MBX GPUには、2つのテクスチャユニット(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つのテクスチャを1回使用することができる理由を知っている。最大のテクスチャを取得する機能はありますか? – Cylon

+0

はい、次のコードで使用可能なテクスチャユニット数をシステムに問い合わせることができます:glGetIntegerv(GL_MAX_TEXTURE_UNITS、&texture_unit_count); – Ozirus

+0

私はシミュレータとタッチの両方で関数を使用して8を得ました – Cylon

関連する問題