[iuud8]基于cocos2dx3.2精灵变灰的shader效果

来源:互联网 发布:台海网络电视台视点 编辑:程序博客网 时间:2024/05/16 00:51

在游戏开发过程中,常常会用到使精灵变灰的功能,例如按钮的不可用,成就未达成等等。但是在cocos2dx中并没有直接提供类似的功能,但还好,基于shader也可以实现类似的效果。修改步骤如下:

首先,需要在cocos2d>>renderer目录中新建两个文件:

1:ccShader_PositionTextureGray.vert 并置入以下代码

const char* ccPositionTextureGray_vert = STRINGIFY(attribute vec4 a_position;attribute vec2 a_texCoord;attribute vec4 a_color;\n#ifdef GL_ES\nvarying lowp vec4 v_fragmentColor;varying mediump vec2 v_texCoord;\n#else\nvarying vec4 v_fragmentColor;varying vec2 v_texCoord;\n#endif\nvoid main(){    gl_Position = CC_PMatrix * a_position;    v_fragmentColor = a_color;    v_texCoord = a_texCoord;});

2:ccShader_PositionTextureGray.frag 并植入以下代码

const char* ccPositionTextureGray_frag = STRINGIFY(#ifdef GL_ESprecision mediump float;#endif                                                   varying vec4 v_fragmentColor;varying vec2 v_texCoord;                                                   void main(){    vec4 normalColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);    //    float gray = dot(normalColor.rgb, vec3(0.299 * 0.5, 0.587 * 0.5, 0.114 * 0.5));    float gray = dot(normalColor.rgb, vec3(0.299, 0.587, 0.114));    gl_FragColor = vec4(gray, gray, gray, normalColor.a);});

在项目中引用这两个文件以后,则开始调用的过程

首先

在ccShaders.h中添加

extern CC_DLL const GLchar * ccPositionTextureGray_frag;    extern CC_DLL const GLchar * ccPositionTextureGray_vert;
在ccShaders.cpp中添加
#include "ccShader_PositionTextureGray.frag"#include "ccShader_PositionTextureGray.vert"

其次

在CCGLProgram.h中添加

static const char* SHADER_NAME_POSITION_TEXTURE_GRAY;
在CCGLProgram.cpp中添加
const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_GRAY = "ShaderPositionTextureGray";

最后需要更改的就是CCGLProgramCache.cpp文件了

1.在shader的枚举类型中添加

kShaderType_PositionTextureGray
2.在GLProgramCache::loadDefaultGLPrograms()函数中添加以下代码
   p = new GLProgram();    loadDefaultGLProgram(p, kShaderType_PositionTextureGray);    _programs.insert( std::make_pair( GLProgram::SHADER_NAME_POSITION_TEXTURE_GRAY, p ) );
3.在GLProgramCache::reloadDefaultGLPrograms()函数中添加以下代码
    p = getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_GRAY);    p->reset();loadDefaultGLProgram(p, kShaderType_PositionTextureGray);
4.在GLProgramCache::loadDefaultGLProgram(GLProgram*p, int type)函数中添加以下代码
 case kShaderType_PositionTextureGray:        {            p->initWithByteArrays(ccPositionTextureGray_vert, ccPositionTextureGray_frag);                        p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);            p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);            p->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORD);                        break;        }


以上修改完成!!!

在项目中使用的时候很简单

auto disabledSprite = Sprite::create(normalImage);        disabledSprite->setGLProgram(GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_GRAY));


以上!!!


更新:

工作中逐渐的发现了另一种简单高效的方法,封装后可以很简便的创建灰色的精灵:

    Sprite* sprite = Sprite::create("fileName");    GLchar* boSource =    "#ifdef GL_ES \n \    precision mediump float; \n \    #endif \n \    uniform sampler2D u_texture; \n \    varying vec2 v_texCoord; \n \    varying vec4 v_fragmentColor; \n \    void main(void) \n \    { \n \    // Convert to greyscale using NTSC weightings \n \    vec4 col = texture2D(u_texture, v_texCoord); \n \    float grey = dot(col.rgb, vec3(0.299, 0.587, 0.114)); \n \    gl_FragColor = vec4(grey, grey, grey, col.a); \n \    }";    GLProgram* boProgram = new GLProgram();    boProgram->initWithByteArrays(ccPositionTextureColor_noMVP_vert, boSource);    sprite->setGLProgram(boProgram);    boProgram->release();    CHECK_GL_ERROR_DEBUG();    sprite->getGLProgram()->bindAttribLocation( GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);    sprite->getGLProgram()->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);    sprite->getGLProgram()->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORD);    CHECK_GL_ERROR_DEBUG();    sprite->getGLProgram()->link();    CHECK_GL_ERROR_DEBUG();    sprite->getGLProgram()->updateUniforms();    CHECK_GL_ERROR_DEBUG();        return sprite;


0 0