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. 利用POi3.8导出excel产生大量xml临时文件怎么办?

    在实际项目中,经常会用到POI3.8来导出excel.而导出excel的时候,会因为残留大量以.xml结尾的文件而导致服务器存储空间急剧增长,最后导致系统挂了.为此,该怎么办呢? .xml后缀残留文件 ...

  2. Hibernate注解(二):关联关系映射注解

    关联关系映射注解以下项目均在之前相应代码的基础上进行的修改.这些项目均需要做的是: 删除映射文件 在hibernate.cfg.xml中注册实体类 注解的重要位置在实体类中关联属性上.这里是关联 ...

  3. 设置windows服务依赖项

    场景还原:python2.7开发的项目,制作成了windows服务,随系统启动.系统重启后发现服务未能自动启动,检查事件查看器日志发现服务先于Mysql数据库服务启动,由于服务中必须对MySQL进行访 ...

  4. ZooKeeper学习第五期--ZooKeeper管理分布式环境中的数据(转)

    转载来源:https://www.cnblogs.com/sunddenly/p/4092654.html 引言 本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它 ...

  5. 解决npm install卡住不动的小尴尬

    npm install卡顿问题记录 遇到的问题 npm install -g @angular/cli 安装angular cli工具时,发现进度条一直卡住不动,相信很多朋友也遇到过.原因应该是国内的 ...

  6. 在 Windows 中编译 Github 中的 GO 项目

    1.相关软件与环境准备 1.1 GO 安装 下载地址,https://studygolang.com/dl,选择 Windows 版,本文安装到 D:\Go 1.2 LiteIDE 安装 下载地址,h ...

  7. java源码解析之String类(二)

    上一节主要介绍了String类的一些构造方法,主要分为四类 无参构造器:String(),创建一个空字符串"",区别于null字符串,""已经初始化,null并 ...

  8. 以实现MongoDB副本集状态的监控为例,看Telegraf系统中Exec输入插件如何编写部署

    既有的Telegraf 关于MongoDB的输入插件很难实现对副本集节点状态的监控,副本集节点状态有 PRIMARY.SECONDARY.RECOVERYING.ARBITER 等.现在我们尝试通过  ...

  9. 【设计模式】行为型03观察者模式(Observer Pattern)

    记得16年初第一次学习了23种设计模式,但是除了少数几个简单的外,其他的很多都是学了个似懂非懂,以至于有人问起甚至说不上来,现在想想,其实就是没看懂而已.例如观察者模式,其实原理很简单,但是当时并没有 ...

  10. maven导入jar包于本地库中

    在使用Maven的过程中,经常碰到有些jar包在中央仓库没有的情况.如果公司有私服,那么就把jar包安装到私服上.如果没有私服,那就把jar包安装到本地Maven仓库. 默认情况下,Maven本地库被 ...