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. mysql远程表链接

    FEDERATED简介 FEDERATED存储引擎是访问远程数据库中的表,在平时开发中可以用此特性来访问远程库中的参数表之类的,还是非常方便的.使用时直接在本地构建一个federated表来链接远程数 ...

  2. Windows下搭建go语言开发环境 以及 开发IDE (附下载链接)

    1.下载 并且 安装 Go安装包   =========================================================== 在CSDN上传了我的版本,供大家下载: = ...

  3. TextBox的Enable和ReadOnly属性的限制

    在以前的ASP.NET 1.x版本中,设置为ReadOnly的TextBox控件在客户端更改了值后,在服务器端仍然可以得到修改后的值,但在ASP.NET 2.0中,这种做法已经限制.这是为了提高应用程 ...

  4. python连接数据库(1)——mysql

    mysql是世界上应用最广的免费数据库,python当然也提供了对它的调用. 首先pip install pymysql,当然自己要知道数据库的用户名和密码,本地数据库的host就是localhost ...

  5. Ansible常用模块介绍

    ansible < HOST-PATTERN > [ -f FORKS ] [ -m MOUDULE ] [ -a "ARGS" ] [ -o ] MOUDULE: p ...

  6. Spring 注解编程之模式注解

    Spring 框架中有很多可用的注解,其中有一类注解称模式注解(Stereotype Annotations),包括 @Component, @Service,@Controller,@Reposit ...

  7. 长春理工大学第十四届程序设计竞赛(重现赛)B

    B Bowling Game 题目链接:https://ac.nowcoder.com/acm/contest/912/B 题目 CUST的队员打完省赛后,小r带着大家去打保龄球. 保龄球是一项难度非 ...

  8. shell脚本开发基本规范

    当你的才华还撑不起你的野心的时候,你就应该静下心来学习.当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练.问问自己,想要怎样的人生. 欢迎加入 基础架构自动化运维:598432640,大数据S ...

  9. Spring Boot 打包成的可执行 jar ,为什么不能被其他项目依赖?

    前两天被人问到这样一个问题: "松哥,为什么我的 Spring Boot 项目打包成的 jar ,被其他项目依赖之后,总是报找不到类的错误?" 大伙有这样的疑问,就是因为还没搞清楚 ...

  10. java虚拟机-GC-调优

    1. 年轻代大小选择 * 响应时间优先的应用:尽可能设大,直到接近系统的最低响应时间限制(根据实际情况选择).在此种情况下,年轻代收集发生的频率也是最小的.同时,减少到达年老代的对象. * 吞吐量优先 ...