目的
有時候做需要讓圖片或者按鈕變灰,效果比較好的是修改着色器程序。
環境
1、cocos2dx版本
cocos3.4
2、vs版本
vs2013
具體步驟
1、添加頂點着色器代碼字符串。
GLchar my_vert[] = "\
attribute vec4 a_position;\n\
attribute vec2 a_texCoord;\n\
attribute vec4 a_color;\n\
\n\
#ifdef GL_ES \n\
varying lowp vec4 v_fragmentColor; \n\
varying mediump vec2 v_texCoord; \n\
#else \n\
varying vec4 v_fragmentColor;\n\
varying vec2 v_texCoord; \n\
#endif \n\
\n\
void main() \n\
{ \n\
gl_Position = CC_PMatrix * a_position; \n\
v_fragmentColor = a_color; \n\
v_texCoord = a_texCoord; \n\
}";
2、添加片段着色器代碼字符串
GLchar my_frag[] = "\
#ifdef GL_ES \n\
precision lowp float; \n\
#endif \n\
\n\
varying vec4 v_fragmentColor; \n\
varying vec2 v_texCoord; \n\
\n\
void main() \n\
{\n\
gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);\n\
float f=(gl_FragColor.r+gl_FragColor.g+gl_FragColor.b)/3.0f; \n\
gl_FragColor=vec4(f,f,f,gl_FragColor.a);\n\
}";
3、創建新的GLProgram
GLProgram *p = GLProgram::createWithByteArrays(my_vert, my_frag);
4、將GLProgram加入GLProgramCache
GLProgramCache::getInstance()->addGLProgram(p, "my_pro");
5、替換掉目標的GLProgram
圖片Sprite
auto sprite = Sprite::create("HelloWorld.png");
sprite->setGLProgram(p);
效果如下:
原圖
變灰
按鈕Menu
auto closeItem = MenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(visibleSize.width/2.0,visibleSize.height/2.0);
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu, 1);
//關鍵代碼
Sprite *pNormalSp = (Sprite *)(closeItem->getNormalImage());
pNormalSp->setGLProgram(p);
效果如下:
原圖
變灰
6、關於GLProgram的內存管理
關於要不要釋放掉GLProgram的問題,我個人是建議不釋放的,把它加入GLProgramCache裏就可以了,cocos自己是不會把你的Program清除掉的,你可以通過自己定義的名字去重複使用(我這裏是"my_pro")。獲取方法:
GLProgramCache::getInstance()->getGLProgram("my_pro")
加入GLProgramCache後GLProgram的引用技數會加1。而GLProgramCache並沒有提供從Cache裏刪除的接口,自己把GLProgram delete掉的話不知道會出什麼問題,所以乾脆一直保存在裏面。cocos自己也是一直把基本的GLProgram保存在裏面。
7、關於GLProgram命名
GLProgram的名字不要和cocos自己已有的基本GLProgram的名字重複,它們的名字如下:
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR = "ShaderPositionTextureColor";
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP = "ShaderPositionTextureColor_noMVP";
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST = "ShaderPositionTextureColorAlphaTest";
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST_NO_MV = "ShaderPositionTextureColorAlphaTest_NoMV";
const char* GLProgram::SHADER_NAME_POSITION_COLOR = "ShaderPositionColor";
const char* GLProgram::SHADER_NAME_POSITION_COLOR_TEXASPOINTSIZE = "ShaderPositionColorTexAsPointsize";
const char* GLProgram::SHADER_NAME_POSITION_COLOR_NO_MVP = "ShaderPositionColor_noMVP";
#if CC_TARGET_PLATFORM == CC_PLATFORM_WP8 || defined(WP8_SHADER_COMPILER)
const char* GLProgram::SHADER_NAME_POSITION_COLOR_NO_MVP_GRAYSCALE = "ShaderPositionColor_noMVP_GrayScale";
#endif
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE = "ShaderPositionTexture";
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_U_COLOR = "ShaderPositionTexture_uColor";
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_A8_COLOR = "ShaderPositionTextureA8Color";
const char* GLProgram::SHADER_NAME_POSITION_U_COLOR = "ShaderPosition_uColor";
const char* GLProgram::SHADER_NAME_POSITION_LENGTH_TEXTURE_COLOR = "ShaderPositionLengthTextureColor";
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_NORMAL = "ShaderLabelDFNormal";
const char* GLProgram::SHADER_NAME_LABEL_DISTANCEFIELD_GLOW = "ShaderLabelDFGlow";
const char* GLProgram::SHADER_NAME_LABEL_NORMAL = "ShaderLabelNormal";
const char* GLProgram::SHADER_NAME_LABEL_OUTLINE = "ShaderLabelOutline";
const char* GLProgram::SHADER_3D_POSITION = "Shader3DPosition";
const char* GLProgram::SHADER_3D_POSITION_TEXTURE = "Shader3DPositionTexture";
const char* GLProgram::SHADER_3D_SKINPOSITION_TEXTURE = "Shader3DSkinPositionTexture";
const char* GLProgram::SHADER_3D_POSITION_NORMAL = "Shader3DPositionNormal";
const char* GLProgram::SHADER_3D_POSITION_NORMAL_TEXTURE = "Shader3DPositionNormalTexture";
const char* GLProgram::SHADER_3D_SKINPOSITION_NORMAL_TEXTURE = "Shader3DSkinPositionNormalTexture";