1.第一种方法针对的是整个图层的渲染 
        重写visit()函数,并且在visit()函数中直接向CommandQueue添加CustomCommand,设置好回调函数.  
        
        #ifndef __HELLOWORLD_SCENE_H__
        #define __HELLOWORLD_SCENE_H__
        
        #include "cocos2d.h"
        
        USING_NS_CC;
        
        class HelloWorld : public cocos2d::Layer
        {
        public:
            // there's no 'id' in cpp, so we recommend returning the class instance pointer
            static cocos2d::Scene* createScene();
        
            // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
            virtual bool init();  
            
            virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags) override;
        
            void onDraw();
            
            // implement the "static create()" method manually
            CREATE_FUNC(HelloWorld);
            
        private:
            CustomCommand command;
        };
        
        #endif // __HELLOWORLD_SCENE_H__
        
         
        #include "HelloWorldScene.h"
        
        USING_NS_CC;
        
        Scene* HelloWorld::createScene()
        {
            // 'scene' is an autorelease object
            auto scene = Scene::create();
            
            // 'layer' is an autorelease object
            auto layer = HelloWorld::create();
        
            // add layer as a child to scene
            scene->addChild(layer);
        
            // return the scene
            return scene;
        }
        
        // on "init" you need to initialize your instance
        bool HelloWorld::init()
        {
            //////////////////////////////
            // 1. super init first
            if ( !Layer::init() )
            {
                return false;
            }
            // 从Cocos2D-X的shader缓存中取出一个带有position和color顶点属性的shader,然后传给HelloWorld这个Layer
            this->setGLProgram(GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_COLOR));
            
            return true;
        }
        
         void HelloWorld::visit(cocos2d::Renderer *renderer, const cocos2d::Mat4 &parentTransform, uint32_t parentFlags)
        {
            Layer::visit(renderer, parentTransform, parentFlags);
            command.init(_globalZOrder);
            command.func = CC_CALLBACK_0(HelloWorld::onDraw, this);
            Director::getInstance()->getRenderer()->addCommand(&command);
        }
        
        void HelloWorld::onDraw()
        {
            // 获取当前的shader
            auto glProgram = getGLProgram();
            // 使用此shader
            glProgram->use();
            // 设置该shader的一些内置uniform,主要是MVP,即model-view-project矩阵
            glProgram->setUniformsForBuiltins();
            
            auto visiableSize = Director::getInstance()->getVisibleSize();
            
            // 指定将要绘制的三角形的三个顶点
            float vertercies[] = { 0,0,     //第一个点的坐标
                                    visiableSize.width,0,   //第二个点的坐标
                                        visiableSize.width / 2, visiableSize.height};   //第三个点的坐标
            
            // 指定每一个顶点的颜色,颜色值是RGBA格式的,取值范围是0-1
            float color[] = { 0, 1,0, 1,    //第一个点的颜色,绿色
                                1,0,0, 1,  //第二个点的颜色, 红色
                                    0, 0, 1, 1};  //第三个点的颜色, 蓝色
            
            // 激活名字为position和color的vertex attribute
            GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);
            
            //分别给position和color指定数据源
            glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertercies);
            glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, color);
            
            //绘制三角形,所谓的draw call就是指这个函数调用
            glDrawArrays(GL_TRIANGLES, 0, 3);
            //通知cocos2d-x 的renderer,让它在合适的时候调用这些OpenGL命令
            CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 3);
            
             //如果出错了,可以使用这个函数来获取出错信息
            CHECK_GL_ERROR_DEBUG();
        }
         
        2.第二种方法针对个别精灵
         
         
        有时候,我们只要对个别精灵进行特效的处理,这个精灵需要使用我们自己编写的Shader,而图层其他的元素按默认处理就行了。设置好Shader,向精灵添加Shader,最后在重写draw函数,在draw函数中进行特效的处理。代码来自捕鱼达人 第二节 波光处理  
        
        bool FishLayer::init()
        {
                 ...省略了不相关的代码。
            // 将vsh与fsh装配成一个完整的Shader文件。
            auto glprogram = GLProgram::createWithFilenames("UVAnimation.vsh", "UVAnimation.fsh");
            // 由Shader文件创建这个Shader
            auto glprogramstate = GLProgramState::getOrCreateWithGLProgram(glprogram);
            // 给精灵设置所用的Shader
            m_Sprite->setGLProgramState(glprogramstate);
         
            //创建海龟所用的贴图。
            auto textrue1 = Director::getInstance()->getTextureCache()->addImage("tortoise.png");
            //将贴图设置给Shader中的变量值u_texture1
            glprogramstate->setUniformTexture("u_texture1", textrue1);
            //创建波光贴图。
            auto textrue2 = Director::getInstance()->getTextureCache()->addImage("caustics.png");
            //将贴图设置给Shader中的变量值u_lightTexture
            glprogramstate->setUniformTexture("u_lightTexture", textrue2);
         
            //注意,对于波光贴图,我们希望它在进行UV动画时能产生四方连续效果,必须设置它的纹理UV寻址方式为GL_REPEAT。
            Texture2D::TexParams    tRepeatParams;
            tRepeatParams.magFilter = GL_LINEAR_MIPMAP_LINEAR;
            tRepeatParams.minFilter = GL_LINEAR;
            tRepeatParams.wrapS = GL_REPEAT;
            tRepeatParams.wrapT = GL_REPEAT;
            textrue2->setTexParameters(tRepeatParams);
            //在这里,我们设置一个波光的颜色,这里设置为白色。
            Vec4  tLightColor(1.0,1.0,1.0,1.0);
            glprogramstate->setUniformVec4("v_LightColor",tLightColor);
            //下面这一段,是为了将我们自定义的Shader与我们的模型顶点组织方式进行匹配。模型的顶点数据一般包括位置,法线,色彩,纹理,以及骨骼绑定信息。而Shader需要将内部相应的顶点属性通道与模型相应的顶点属性数据进行绑定才能正确显示出顶点。
            long offset = 0;
            auto attributeCount = m_Sprite->getMesh()->getMeshVertexAttribCount();
            for (auto k = 0; k < attributeCount; k++) {
                auto meshattribute = m_Sprite->getMesh()->getMeshVertexAttribute(k);
                glprogramstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttrib],
                                                     meshattribute.size,
                                                     meshattribute.type,
                                                     GL_FALSE,
                                                     m_Sprite->getMesh()->getVertexSizeInBytes(),
                                                     (GLvoid*)offset);
                offset += meshattribute.attribSizeBytes;
            }
         
            //uv滚动初始值设为0
            m_LightAni.x = m_LightAni.y = 0;
            return true;
        }
         
        void FishLayer::draw(Renderer* renderer, const Mat4 &transform, uint32_t flags)
        {
            if(m_Sprite)
            {
                //乌龟从右向左移动,移出屏幕后就回到最右边
                auto s = Director::getInstance()->getWinSize();
                m_Sprite->setPositionX(m_Sprite->getPositionX()-1);
                if(m_Sprite->getPositionX() < -100)
                {
                    m_Sprite->setPositionX(s.width + 10);
                }
                 
                auto glprogramstate = m_Sprite->getGLProgramState();
                if(glprogramstate)
                {
                    m_LightAni.x += 0.01;
                    if(m_LightAni.x > 1.0)
                    {
                        m_LightAni.x-= 1.0;
                    }
                    m_LightAni.y += 0.01;
                    if(m_LightAni.y > 1.0)
                    {
                        m_LightAni.y-= 1.0;
                    }
                    glprogramstate->setUniformVec2("v_animLight",m_LightAni);
                }
            }
            Node::draw(renderer,transform,flags);
        }

Cocos2d-x 3.x中自定义渲染功能的更多相关文章

  1. 在Jetbrain IDE中自定义TODO功能

    好的IDE能为开发以及学习源码带来效率的提升,今天要介绍的就是Jetbrain家族中IDE自带的TODO功能,我认为利用好它,能够大大的提升阅读源码的效率. 假设我现在需要去阅读源代码,看了半天我终于 ...

  2. C#在DataGridView中自定义键盘功能——光标在单元格内具体位置

    //捕捉按键 protected override bool ProcessCmdKey(ref Message msg,Keys keyData) { if (keyData == Keys.Rig ...

  3. 关于在SharePoint 2013(2010)中Javascript如何实现批量批准的自定义操作功能?

    1.概述: SharePoint 2013(包括SharePoint 2010)提供了很方便的,多选的界面,但是很多操作还是不能批量进行,比如:批准的功能.如果您要解决方案不关心代码,那么请直接联系作 ...

  4. 微信JSSDK使用步骤(用于在微信浏览器中自定义分享,分享到朋友圈,拍照,扫一扫等功能)

    一.使用JSSDK需要一个公众号(需要认证!): (1).把自己项目的服务器地址输入. (2).把MP_verify_m7Qp93BAuIGDWRVO.txt  文件下载下来,放到该服务器域名指向的根 ...

  5. WPF/Silverlight深度解决方案:(七)HLSL自定义渲染特效之完美攻略(中)

    原文:WPF/Silverlight深度解决方案:(七)HLSL自定义渲染特效之完美攻略(中) 通过上一节的解说,大家是否已经对HLSL有了较深刻的认识和理解,HLSL的渲染不仅仅局限于静态处理,通过 ...

  6. UE4里的自定义深度功能

    转自:http://www.52vr.com/article-1866-1.html 随着物理渲染系统的发布,虚幻引擎4同时引进了一个新的深度缓存功能,它叫作“自定义深度”,可以用于诸如编辑器里的选择 ...

  7. PIE SDK矢量自定义渲染

    1. 功能简介 PIE SDK中关于矢量渲染提供了多种方案,包括简单渲染.分级渲染.唯一值渲染,这几种渲染方式具有一定的通用性,可以满足用户绝大多数的需求. 当面对复杂的业务,当前渲染方案无法满足用户 ...

  8. Javascript自定义事件功能与用法实例分析

    原文地址:https://www.jb51.net/article/127776.htm 本文实例讲述了javascript自定义事件功能与用法.分享给大家供大家参考,具体如下: 概述 自定义事件很难 ...

  9. WijmoJS 中自定义 React 菜单和列表项模板

    WijmoJS 中自定义 React 菜单和列表项模板 在V2019.0 Update2 的全新版本中,React 框架下 WijmoJS 的前端UI组件功能再度增强. WijmoJS的菜单和类似列表 ...

随机推荐

  1. Silverlight ItemsControl详细解析+解惑

    Silverlight最强大的地方就在于定义控件了,Silverlight提供了非常灵活和高效的控件定义方式,几乎可以实现任何复杂的控件实现,对于快速开发应用程序有着重要的意义.在Silverligh ...

  2. 30255Java_5.5 GUI

    GUI GUI的各种元素(如:窗口,按钮,文本框等)由Java类来实现 1.AWT 使用AWT所涉及的类一般在java.awt包及其子包中 AWT(Abstract Window Toolkit)包括 ...

  3. 章节十四、8-javaScript弹框处理

    一.javaScript弹框没有id.也没有xpath,在F12开发者选项中无法直接通过鼠标去选择弹窗来确定元素在代码中的位置. 弹窗有两种,一种实只有"确定"按钮的alert类型 ...

  4. C# 设计模式,简单工厂

    C# 实现计算机功能 (封装,继承,多态) using System; using System.Collections.Generic; using System.Linq; using Syste ...

  5. [UWP]从头开始创建并发布一个番茄钟

    1. 自己用的番茄钟自己做 在PC上我一直使用"小番茄"作为我的番茄钟软件,我把它打开后放在副显示器最大化,这样不仅可以让它尽到本分,而且还可以告诉我的同事"我正在专心工 ...

  6. python基础(1)--input print if else elif while 用法说明

    1 变量名的命名规则: 由数字,字母和下划线组成,但是不能以数字开头命名变量.例如 a ,b ,c ,name ,user1 user_id 等都可作为变量名称. 1a,2b 3cd等都不行.特别注意 ...

  7. 【hadoop+spark】搭建spark过程

    部分转载,已标红源地址,本博客为本菜搭建与爬坑记录,整理版请看: https://blog.csdn.net/the_fool_/article/details/78211166 记录: ====== ...

  8. git push 时:报missing Change-Id in commit message footer的错误

    1. 一般而言,按照提示执行以下两个命令即可生成新的Change-id - gitdir=$(git rev-parse --git-dir); scp -p -P 29418 guan@192.16 ...

  9. 一道关于String的面试题,新鲜出炉,刚被坑过,趁热!!

    很多人都会答错的一道关于String的题目,究竟有什么难度? 我们一起来看一道关于String的面试题,准确说是改编的面试题! 准备好啦?在放大招之前先来一个小招式 String s1 = new S ...

  10. Java8新特性——lambda表达式.(案例:词频统计)

    需求:读入一个文本文件,确定所有单词的使用频率并从高到低排序,打印出所有单词及其频率的排序列表 先用传统方法解: package cn._1.wordfrequency; import java.ut ...