2013年10月24日 星期四

GLImageProcessing image effects in opengl

將圖檔存入opengl texture memory
首先要先看懂texture environment的用法 http://www.khronos.org/opengles/sdk/1.1/docs/man/glTexEnv.xml 




brightness
//告訴目前貼圖環境為GL_COMBINE
//告訴目前貼圖環境為GL_COMBINE
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
if (t > 1.0f)
{
//對於GL_COMBINE_RGB參數為GL_ADD 也就是相加
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_ADD);
//顏色ARRAY
glColor4f(t-1, t-1, t-1, t-1);
}
else
{
//對於GL_COMBINE_RGB參數為GL_SUBTRACT 也就是相減
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_SUBTRACT);
//again顏色ARRAY
glColor4f(1-t, 1-t, 1-t, 1-t);
}
//對於RGB的第一個resource為材質
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_TEXTURE);
//對於RGB的第二個resource為顏色array
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PRIMARY_COLOR);
//對於Alpha的方式為GL_REPLACE
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
//第一個resource為材質
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_TEXTURE);

before drawarrays , order is not important .
基本上0.5 1.5左右就全黑全白了 以general color來說




constract


// 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.
此為extrapolate(外推)公式 取X_0 = 0 X_1 = 0.5 X_2 = t                        Y_0 = degen  Y_1 = src  便可算出Y_2

GLfloat h = t*0.5f;
告訴目前貼圖環境為GL_COMBINE
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
//GL_MODULATE  Arg0 × Arg1

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_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_TEXTURE);
//使用第二層紋理 是個灰階圖
GLubyte half[4] = { 0x80, 0x80, 0x80, 0x80 };

glActiveTexture(GL_TEXTURE1);
//這裡只對目前actived texture做enable
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
//GL_ADD_SIGNED Arg0 + Arg1 - 0.5
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_ADD_SIGNED);
//C f represents the primary color of the incoming fragment, and C p represent the color computed from the previous texture stage or C f if processing texture stage 0
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PRIMARY_COLOR);
//Arg1使用GL_SRC_ALPHA = A f
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,     GL_SRC_ALPHA);
//RGB x 2
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


簡單來說就是達成上面算好的公式 第一層用GL_MODULATE 第二層用GL_ADD_SIGNED去混合這些紋理 第二層比較tricky

saturation

這特效使用一個灰階的texture當作基底來合成

首先要產生灰階的texture







saturation


GLfloat lerp[4] = { 1.0, 1.0, 1.0, 0.5 };

GLfloat avrg[4] = { .667, .667, .667, 0.5 }; // average
GLfloat prcp[4] = { .646, .794, .557, 0.5 }; // perceptual NTSC
    //NTSC, named for the National Television System Committee,[1] is the analog television system that is used in most of North America, parts of South America (except Brazil, Argentina, Uruguay, and French Guiana), Myanmar, South Korea, Taiwan, Japan, the Philippines, and some Pacific island nations and territories (see map).
 GLfloat dot3[4] = { prcp[0]*t+avrg[0]*(1-t), prcp[1]*t+avrg[1]*(1-t), prcp[2]*t+avrg[2]*(1-t), 0.5 };
 
 // One pass using two units:
 // Unit 0 scales and biases into [0.5..1.0]
 // Unit 1 dot products with perceptual weights

lerp是第一張texture的constant , avrg為灰階平均像素資料 , prcp是電視顏色基準

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); //Arg0 x Arg2 + Arg1 x (1-Arg2) glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE); //Constant means Color of GL_TEXTURE_ENV_COLOR glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE); glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR, lerp); // Note: we prefer to dot product with primary color, because // the constant color is stored in limited precision on MBX glActiveTexture(GL_TEXTURE1); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); //GL_DOT3_RGB or GL_DOT3_RGBA 4*((Arg0r - 0.5) * (Arg1r - 0.5) + (Arg0g - 0.5) * (Arg1g - 0.5) + (Arg0b - 0.5) * (Arg1b - 0.5)) glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB); //refers to the color computed from the previous texture stage (or the incoming fragment if processing texture stage 0), 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); glColor4f(dot3[0], dot3[1], dot3[2], dot3[3]); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

第一張貼圖使用interpolate看似很威 實際上的constant是 1 1 1 0.5 也就是說除了alpha RGB還是使用bind的texture , 實際上alpha算出來也是1 , 而第二章用DOT3_RGB可以轉換成灰階 , alpha不變 也就能產出灰階圖片了 接著的外推 透過extrapolate算出後在使用 去作rgb scale

1 則留言: