Cocos2d-x版本3.17.1
原理
Sprite类默认使用的着色器程序为:
GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP
fragment shader 内容为:
void main()
{
gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
}
其中v_fragmentColor是程序中设置的顶点属性颜色,默认为白色变灰的操作很简单,fragment shader代码改为:
void main(void)
{
vec4 c = texture2D(CC_Texture0, v_texCoord);
c = v_fragmentColor * c;
gl_FragColor.xyz = vec3(0.2126*c.r + 0.7152*c.g + 0.0722*c.b);
gl_FragColor.w = c.w;
}
前两行计算出纹理与顶点属性颜色混合后的颜色第三行通过三个系数,分别乘与RGB分量再相加,构造一个三分量相等的vec3
实际操作:
引擎提供了一个变灰的着色器程序:
GLProgram::SHADER_NAME_POSITION_GRAYSCALE
Sprite类添加gray, ungray方法
void Sprite::gray(){
Texture2D* texture = this->getTexture();
auto programState = GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_GRAYSCALE, texture);
this->setGLProgramState(programState);
}
void Sprite::ungray(){
Texture2D* texture = this->getTexture();
auto programState = GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP, texture);
this->setGLProgramState(programState);
}
这里使用getOrCreateWithGLProgramName(const std::string, Texture2D*)方法的目的是为了兼容ETC格式的压缩纹理格式
结语
如果使用ETC纹理格式,变灰的fragment shader和上面的会有一点点不同详细引擎==ccShader_ETC1AS_PositionTextureGray.frag==文件