首先要先看懂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 weightslerp是第一張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);