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