Cocos2d x 如何在Cocos2dx中为电枢对象设置着色器

Cocos2d x 如何在Cocos2dx中为电枢对象设置着色器,cocos2d-x,Cocos2d X,我有3个问题: 我知道何时我想通过使用spr1->setShaderProgram(glProgram)为Sprite对象设置着色器。但是,我想为电枢对象设置着色器。我该怎么做 在CCSprite中,我可以使用setBlendFunc,在电枢中如何 我读了这篇文章,我看到了检测两个精灵之间碰撞的想法。但是我想写一个扩展函数,它可以检测不同对象之间的碰撞,比如精灵对精灵,精灵对电枢,虚拟对电枢。我该怎么做 谢谢今天我遇到了和你一样的情况。幸运的是,我从其他人那里找到了解决办法。主要的一点是编写电枢

我有3个问题:

  • 我知道何时我想通过使用
    spr1->setShaderProgram(glProgram)
    为Sprite对象设置着色器。但是,我想为电枢对象设置着色器。我该怎么做

  • 在CCSprite中,我可以使用setBlendFunc,在电枢中如何

  • 我读了这篇文章,我看到了检测两个精灵之间碰撞的想法。但是我想写一个扩展函数,它可以检测不同对象之间的碰撞,比如精灵对精灵,精灵对电枢,虚拟对电枢。我该怎么做


  • 谢谢

    今天我遇到了和你一样的情况。幸运的是,我从其他人那里找到了解决办法。主要的一点是编写电枢的一个子类,比如ShaderArmature,并使用着色器渲染每个骨骼的每个子对象——在我的例子中,着色器用于使电枢变灰

    您可以创建一个ShaderFormat对象并调用其setgrayState()以启用灰色化,并调用SetUseAstate()以移除灰色化效果

    1,将ShaderArmature.h和ShaderArmature.cpp添加到同一目录下的accounter.h中

    ShaderArmature.h

    ShaderArmature.cpp

    GrayScalingShader.vsh


    希望这会有帮助。

    电枢到底是什么?@learncoos2d:读这篇文章。我喜欢一个甚至没有提到课程是什么或做什么的课堂参考。和盔甲有关吗?骨骼动画?@LearnCos2D:那么你对我的3个问题有什么想法吗?不,我不是a-x用户。我想1和2可能不可能,因为这个类似乎正在执行自定义绘图。3可能是一个多边形相交问题,取决于是否以及如何获得电枢的多边形形状。
    //
    //  Created by Wangyq on 2017/8/13.
    //
    //
    
    #ifndef __SHADERARMATURE_H__
    #define __SHADERARMATURE_H__
    
    //
    //---------shaderArmature.h
    ///
    #include "cocos2d.h"
    //#include "extensions/cocos-ext.h"
    #include "cocostudio/CocoStudio.h"
    //USING_NS_CC_EXT;
    USING_NS_CC;
    namespace cocostudio{
    class CC_STUDIO_DLL ShaderArmature : public Armature
    {
    public:
        ShaderArmature();
        virtual ~ShaderArmature();
    
        bool init(const std::string& name) override;
    
        static ShaderArmature *create(const std::string& name) ;
    
        virtual void initShader(bool shaderState);
        //    void setBackgroundNotification();
    
    //    draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags)
        virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t transformUpdated) override;
        //    void listenBackToForeground(Ref *obj);
        void setIceState();
        void setUsuaState();
    
        void setblurState();
        void setbanishState();
        void setfrozenState();
        void setgrayState();
        void setinvisState();
        void setmirrorState();
        void setpoisonState();
        void setstoneState();
    protected:
        std::string _fragSourceFile;
        std::string _vertSourceFile;
        //GLchar * fragSource;
        //GLchar * vertSource;
        GLchar fragSource[2048];
        GLchar vertSource[2048];
        bool bSetShader;
    };
    
    }
    #endif /* __SHADERARMATURE_H__ */
    
    //
    //  ShaderArmature.cpp
    //  cocos2d_libs
    //
    //  Created by Wangyq on 2017/8/13.
    //
    //
    
    #include "ShaderArmature.h"
    
    using namespace cocos2d;
    
    
    namespace cocostudio {
        ShaderArmature::ShaderArmature(){
    
        }
        ShaderArmature::~ShaderArmature(){
    
        }
        bool ShaderArmature::init(const std::string& name)
        {
            return Armature::init(name);
        }
        ShaderArmature *ShaderArmature::create(const std::string& name)
        {
            ShaderArmature *armature = new ShaderArmature;
            if (armature && armature->init(name))
            {
                armature->autorelease();
                return armature;
            }
            else{
                CC_SAFE_DELETE(armature);
                return nullptr;
            }
        }
    
    
        void ShaderArmature::initShader(bool shaderState){
            //Traverse every bone to set shader
            for (auto& object : _boneDic)
            {
                if (Bone *bone = dynamic_cast<Bone *>(object.second))
                {
                    if (bone == nullptr)
                        continue;
    
                    //-----------------!! IMPORTANT !!-----------------
                    //Each bone may have more than one child, like several frames, also need to assign shader to them
                    //Without this step, only the first frame will have the shader effect.
                    const Vector<DecorativeDisplay*> list = bone->getDisplayManager()->getDecorativeDisplayList();
                    for (auto& display : list)
                    {
                        Node* node = display->getDisplay();
                        if (node == nullptr)
                            continue;
    
                        if (shaderState){
                            auto program = new GLProgram();
                            program->initWithByteArrays(vertSource, fragSource);
    
    
                            node->setGLProgram(program);
    
                            program->autorelease();
    
                            CHECK_GL_ERROR_DEBUG();
    
                            program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_POSITION, GLProgram::VERTEX_ATTRIB_POSITION);
                            program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_COLOR, GLProgram::VERTEX_ATTRIB_COLOR);
                            program->bindAttribLocation(GLProgram::ATTRIBUTE_NAME_TEX_COORD, GLProgram::VERTEX_ATTRIB_TEX_COORDS);
    
                            CHECK_GL_ERROR_DEBUG();
    
                            program->link();
    
                            CHECK_GL_ERROR_DEBUG();
    
                            program->updateUniforms();
    
                            CHECK_GL_ERROR_DEBUG();
    
                        }
                        else{//addNormal shader
                            node->setGLProgram(ShaderCache::getInstance()->getProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP));
                        }
                    }
                }
    
            }
        }
        void ShaderArmature::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
        {
            Armature::draw(renderer, transform, flags);
        }
    
        void ShaderArmature::setIceState(){
            _fragSourceFile = "shader/IceShader.fsh";
            _vertSourceFile = "shader/IceShader.vsh";
            fragSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
    
            vertSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
            initShader(true);
        }
    
        void ShaderArmature::setUsuaState(){
            initShader(false);
        }
    
        void ShaderArmature::setblurState(){
            _fragSourceFile = "shader/Blur.fsh";
            _vertSourceFile = "shader/Blur.vsh";
            fragSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
    
            vertSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
            initShader(true);
        }
    
        void ShaderArmature::setbanishState(){
            _fragSourceFile = "shader/BanishShader.fsh";
            _vertSourceFile = "shader/BanishShader.vsh";
            fragSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
    
            vertSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
            initShader(true);
        }
    
        void ShaderArmature::setfrozenState(){
            _fragSourceFile = "shader/FrozenShader.fsh";
            _vertSourceFile = "shader/FrozenShader.vsh";
            fragSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
    
            vertSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
            initShader(true);
        }
        void ShaderArmature::setgrayState(){
            _fragSourceFile = "shader/GrayScalingShader.fsh";
            _vertSourceFile = "shader/GrayScalingShader.vsh";
            fragSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
    
            vertSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
            initShader(true);
        }
        void ShaderArmature::setinvisState(){
            _fragSourceFile = "shader/InvisibleShader.fsh";
            _vertSourceFile = "shader/InvisibleShader.vsh";
            fragSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
    
            vertSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
            initShader(true);
        }
        void ShaderArmature::setmirrorState(){
            _fragSourceFile = "shader/MirrorShader.fsh";
            _vertSourceFile = "shader/MirrorShader.vsh";
            fragSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
    
            vertSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
            initShader(true);
        }
        void ShaderArmature::setpoisonState(){
            _fragSourceFile = "shader/PoisonShader.fsh";
            _vertSourceFile = "shader/PoisonShader.vsh";
            fragSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
    
            vertSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
            initShader(true);
        }
    
        void ShaderArmature::setstoneState(){
            _fragSourceFile = "shader/StoneShader.fsh";
            _vertSourceFile = "shader/StoneShader.vsh";
            fragSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_fragSourceFile).c_str())->getCString();
    
            vertSource = (GLchar*)String::createWithContentsOfFile(
                FileUtils::getInstance()->fullPathForFilename(_vertSourceFile).c_str())->getCString();
            initShader(true);
        }
    }
    
    #ifdef GL_ES
    precision mediump float;
    #endif
    
    varying vec4 v_fragmentColor;
    varying vec2 v_texCoord;
    uniform sampler2D u_texture;
    
    void main()
    {
        vec4 normalColor = v_fragmentColor * texture2D(u_texture, v_texCoord);
    
        //float gray = 0.299*0.5*normalColor.r + 0.587*0.5*normalColor.g + 0.114*0.5*normalColor.b;
        //gl_FragColor = vec4(gray*0.8 + normalColor.r*0.2, gray*0.8 + normalColor.g*0.2, gray*0.8 + normalColor.b*0.2, normalColor.a*0.3);
        float gray = dot(normalColor.rgb, vec3(0.299 * 0.5, 0.587 * 0.5, 0.114 * 0.5));
        gl_FragColor = vec4(gray, gray, gray, normalColor.a * 1);
    }
    
    attribute vec4 a_position;
    attribute vec2 a_texCoord;
    attribute vec4 a_color;
    
    #ifdef GL_ES
    varying lowp vec4 v_fragmentColor;
    varying mediump vec2 v_texCoord;
    #else
    varying vec4 v_fragmentColor;
    varying vec2 v_texCoord;
    #endif
    
    void main()
    {
        //gl_Position = CC_MVPMatrix * a_position;
        gl_Position = CC_PMatrix * a_position;
        v_fragmentColor = a_color;
        v_texCoord = a_texCoord;
    }