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. 国人Web前端开发必备干货,一个完美支持IE6在内所有浏览器的CSS框架

    摘要: 企户动CSS框架是一个能够完美支持IE6~7在内的所有浏览器的 HTML&CSS 前端框架!给Web开发提供了自适应宽度的百分比多列网格,以及已语义化和结构化的标题.段落.列表.表格. ...

  2. Qt+VS编译器:默认库“library”与其他库的使用冲突;使用 /NODEFAULTLIB:library(我曾经碰到过,修改qmake.conf,但我修改的是VS的IDE配置)good

    找到qt安装目录下的mkspecs文件夹,在里面找到你使用的对应版本编译器,打开qmake.conf.稍等: /MD:动态链接多线程库(msvcrt.lib).使用该选项时,需要用/NODEFAULT ...

  3. 敏捷开发中如何做好Sprint规划?

    什么是Sprint规划? Sprint规划是scrum中用来启动Sprint的事件.迭代规划的目标是定义Sprint可以交付的内容,以及如何完成各项工作.迭代规划需要整个scrum团队合作完成. 与体 ...

  4. 读书笔记——《谁说菜鸟不会数据分析—Python篇》

    最近刚读完一本新书,关注的公众号作者出的“谁说菜鸟不会数据分析—Python篇”,话说现在很多微信公众号大牛都在出书,这貌似是一个趋势.. 说说这本书吧,我之前看过一些网文,对于数据分析这一块也有过一 ...

  5. Prometheus 与 Grafana 集成

    简介 Grafana 是一个可视化仪表盘,它拥有美观的图标和布局展示,功能齐全的仪表盘和图形编辑器,默认支持 CloudWatch.Graphite.Elasticsearch.InfluxDB.My ...

  6. 你需要了解的HTTP协议

    了解HTTP协议 HTTP (超文本传输协议,HyperText Transfer Protocol),是一种用于分布式.协作式和超媒体信息系统的应用层协议.HTTP 是万维网的数据通信基础. 通常, ...

  7. 曹工说Tomcat3:深入理解 Tomcat Digester

    一.前言 我写博客主要靠自己实战,理论知识不是很强,要全面介绍Tomcat Digester,还是需要一定的理论功底.翻阅了一些介绍 Digester 的书籍.博客,发现不是很系统,最后发现还是官方文 ...

  8. Linux系统中sysctl命令详解

    sysctl命令用于运行时配置内核参数,这些参数位于/proc/sys目录下.sysctl配置与显示在/proc/sys目录中的内核参数.可以用sysctl来设置或重新设置联网功能,如IP转发.IP碎 ...

  9. client-go中的golang技巧

    client-go中有很多比较有意思的实现,如定时器,同步机制等,可以作为移植使用.下面就遇到的一些技术讲解,首先看第一个: sets.String(k8s.io/apimachinery/pkg/u ...

  10. C++ 洛谷 P2657 [SCOI2009]windy数 题解

    P2657 [SCOI2009]windy数 同步数位DP 这题还是很简单的啦(差点没做出来 个位打表大佬请离开(包括记搜),我这里讲的是DP!!! 首先Cal(b+1)-Cal(a),大家都懂吧(算 ...