• 在cocos2d中添加自己的shader教程


    mark下:转载:http://www.cocoachina.com/bbs/read.php?tid=220630
     
    1.cocos2d的shader都是共用的, 存放在   GLProgramCache 中。 当setGLProgram() 的时候是从GLProgramStateCache 中寻找是否有这个shader的State, 有就返回,这个也是共用的,任意一个GLProgramState修改了, 都会影响到使用这个shader的对象

    添加shader的方法:


    先编写shader: (直接复制cocos/renderer/ 下的 **.frag或者**.vert )  frag是PS阶段的shader  .vert是VS,然后按照自己的修改。
    注意 这些shader在加载的时候,cocos2d会自动添加几个必须的属性变量:  


        const GLchar *sources[] = {
    #if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 && CC_TARGET_PLATFORM != CC_PLATFORM_LINUX && CC_TARGET_PLATFORM != CC_PLATFORM_MAC)
            (type == GL_VERTEX_SHADER ? "precision highp float; " : "precision mediump float; "),
    #endif
            "uniform mat4 CC_PMatrix; "
            "uniform mat4 CC_MVMatrix; "
            "uniform mat4 CC_MVPMatrix; "
            "uniform vec4 CC_Time; "
            "uniform vec4 CC_SinTime; "
            "uniform vec4 CC_CosTime; "
            "uniform vec4 CC_Random01; "
            "uniform sampler2D CC_Texture0; "
            "uniform sampler2D CC_Texture1; "
            "uniform sampler2D CC_Texture2; "
            "uniform sampler2D CC_Texture3; "
            "//CC INCLUDES END ",
            source,
        };


    这段代码在: bool GLProgram::compileShader(GLuint * shader, GLenum type, const GLchar* source) 中,所以你在编写自己的shader时候要注意不要和上面的变量重名
    编写方式:
    现在ccShaders.h中添加shader的编码保存的变量:(拿做的灰度效果为列:)
    extern CC_DLL const GLchar * ccPositionTextureColor_noMVP_gray_frag; 


    我直接修改 ccShader_PositionTextureColor_noMVP.frag 这个文件的
    源文件:


    const char* ccPositionTextureColor_noMVP_frag = STRINGIFY(
    #ifdef GL_ES
    precision lowp float;
    #endif


    varying vec4 v_fragmentColor;
    varying vec2 v_texCoord;


    uniform int n_isGray;


    void main()
    {
     if (n_isGray == 1)
     {
      float alpha = texture2D(CC_Texture0, v_texCoord).a;
      float grey = dot(texture2D(CC_Texture0, v_texCoord).rgb, vec3(0.299, 0.587, 0.114));
      gl_FragColor = vec4(1, grey, grey, 0.0);
     }
     else
     {
      gl_FragColor = v_fragmentColor * texture2D(CC_Texture0, v_texCoord);
     }

    }
    );




    修改后:
    const char* ccPositionTextureColor_noMVP_gray_frag = STRINGIFY(
    #ifdef GL_ES
    precision lowp float;
    #endif


    varying vec4 v_fragmentColor;
    varying vec2 v_texCoord;


    void main()
    {
     float alpha = texture2D(CC_Texture0, v_texCoord).a;
     float grey = dot(texture2D(CC_Texture0, v_texCoord).rgb, vec3(0.299, 0.587, 0.114));
     gl_FragColor = vec4(grey, grey, grey, alpha);
    }
    );


    红色部分是修改掉的 注意 const char* ccPositionTextureColor_noMVP_gray_frag = STRINGIFY( 红色部分要和你在ccShaders.h中声明的变量一致!
    然后在ccShaders.cpp中引用 编写好的shader文件 : #include "ccShader_PositionTextureColor_noMVP_gray.frag"


    这样编写部分就结束


    现在开始添加到默认shader里面:
    先到 CCGLProgram.h   GLProgram 中添加添加我们这个shader的名字:(这个名字只是对外使用的键值)
    static const char* SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY;  
    在.cpp中加上: 
    const char* GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY = "ShaderPositionTextureColor_noMVP_gray";


    然后到CCGLProgramCache.cpp 中的 最上面有一堆枚举, 添加一个自己shader的枚举 比如我添加的 kShaderType_PositionTextureColor_noMVP_gray,


    然后在 void GLProgramCache::loadDefaultGLPrograms() 中写加载我们shader的代码:
     p = new GLProgram();
     loadDefaultGLProgram(p, kShaderType_PositionTextureColor_noMVP_gray);
     _programs.insert( std::make_pair( GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY, p ) );


    到void GLProgramCache::loadDefaultGLProgram(GLProgram *p, int type) 中,配置我们shader用的VS 和PS阶段的 的相关代码:(因为做灰度只需要改动pos部分,所以可以直接用cocos2d现有的VS阶段的代码ccPositionTextureColor_noMVP_vert)


    case kShaderType_PositionTextureColor_noMVP_gray:
       p->initWithByteArrays(ccPositionTextureColor_noMVP_vert, ccPositionTextureColor_noMVP_gray_frag);
       break;


    这样shader就添加好了, 使用方法:


     GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY);
      sprite->setGLProgram(program);


    还原的话就
    GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP);
    sprite->setGLProgram(program);


    你可以脱离这套共用GLProgramState的方式 直接用: (这样你就可以控制这个shader某一个值,而不影响其他使用这个shader的对象了)
    GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP_GRAY); 
    GLProgramState* state = GLProgramState::create(program);
    sprite->setGLProgramState(state):


    本人没学过opengel今天ui那边需要灰度,才开始看的, 写得不好,大家就将就看吧~
    还要说一个地方


    std::string GLProgram::logForOpenGLObject(GLuint object, GLInfoFunction infoFunc, GLLogFunction logFunc) const
    {
        std::string ret;
        GLint logLength = 0, charsWritten = 0;


        //infoFunc(object, GL_INFO_LOG_LENGTH, &logLength);        //编译错误的话,到这里就崩溃了~~  不知道为什么, 
     glGetShaderiv(object, GL_INFO_LOG_LENGTH, &logLength);     //我直接改成调用opengel函数, 
        if (logLength < 1)
            return "";


        char *logBytes = (char*)malloc(logLength);
       // logFunc(object, logLength, &charsWritten, logBytes);
     glGetShaderInfoLog(object, logLength, &charsWritten, logBytes);
        ret = logBytes;


        free(logBytes);
        return ret;
    }


    这里是我这篇笔记的地址: http://note.youdao.com/share/?id=f72378178898d34affe13a6dddd75df3&type=note

     

  • 相关阅读:
    python--执行文件的绝对路径
    python----slots属性安全类
    linux----LAMP之编译安装apache
    MySQL----alter table modify | change的不同
    数据库5
    数据库4
    数据库3
    数据库2
    数据库1
    MySQL exists 和 not exists 的用法
  • 原文地址:https://www.cnblogs.com/wangtingyi/p/6078474.html
Copyright © 2020-2023  润新知