Cocos2d-x 3.x中自定义渲染功能

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);
        }

时间: 2024-08-02 17:12:35

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

iOS开发中自定义相册功能性能改善

大多数项目中都会用到相册浏览和选择功能,如果需要使用到自定义相册浏览器,那么,性能优化将是一个很重要的课题.毕竟操作对象是图片这样相对较大写数据单位.今天就针自定义相册浏览选择器四个优化点进行剖析: 缩略图页面加载速度优化 缩略图页面滑动流畅度优化 大图浏览滑动流畅度优化 内存优化 先看看自定义相册的两个主要界面: 1.缩略图页面加载速度优化 如果本地相册有200张以上的照片,那么缩略图页面的加载速度就显得尤为重要. 首先,要保证缩略图界面的控制器在没有加载照片的时候,从viewDidLoad到

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

1.概述: SharePoint 2013(包括SharePoint 2010)提供了很方便的,多选的界面,但是很多操作还是不能批量进行,比如:批准的功能.如果您要解决方案不关心代码,那么请直接联系作者.如果您对技术感兴趣,那么下面的组合拳就是告诉你如何在2013的Ribbon的工具栏上实现这个小功能,整个实验必须要有SPD(SharePoint Designer 2013),要使用到Javascript的很多知识.作者完全从实际出发,应对了在这个过程中可能出现的各种各样的"状况",比

ASP.NET中利用DataGrid的自定义分页功能

ASP.NET中利用DataGrid的自定义分页功能和存储过程结合实现高效分页 ASP.Net中的DataGrid有内置分页功能, 但是它的默认的分页方式效率是很低的,特别是在数据量很大的时候,用它内置的分页功能几乎是不可能的事,因为它会把所有的数据从数据库读出来再进行分页, 这种只选取了一小部分而丢掉大部分的方法是不可去取的. 在最进的一个项目中因为一个管理页面要管理的数据量非常大,所以必须分页显示,并且不能用DataGrid的内置分页功能,于是自己实现分页. 下面介绍一下我在项目中用到的分页

Delphi中ListView中实现自定义删除功能的方法

Delphi中ListView中实现自定义删除功能的方法 第一种:有时删除文件会出现文件删不掉现象 if lvMain.InnerListView.ItemIndex <> -1 then begin // DoContextMenuVerb(lvMain.SelectedFolder, 'delete'); DoContextMenuVerbB(lvMain.Folders[lvMain.InnerListView.ItemIndex], 'delete'); 第二种:删除功能很强大,建议使

Android中自定义视图View之---前奏篇

前言 好长时间没写blog了,心里感觉有点空荡荡的,今天有时间就来写一个关于自定义视图的的blog吧.关于这篇blog,网上已经有很多案例了,其实没什么难度的.但是我们在开发的过程中有时候会用到一些自定义的View以达到我们所需要的效果.其实网上的很多案例我们看完之后,发现这部分没什么难度的,我总结了两点: 1.准备纸和笔,计算坐标 2.在onDraw方法中开始画图,invalidate方法刷新,onTouchEvent方法监听触摸事件 对于绘图相关的知识,之前在弄JavaSE相关的知识的时候,

Android中自定义视图View之---开发案例

自定义视图View的案例 下面我们就是开始正式的进入自定义视图View了 在讲解正式内容之前,我们先来看一下基本知识 1.我们在自定义视图View的时候正确的步骤和方法 1).必须定义有Context/Attrbuite参数的构造方法,并且调用父类的方法 public LabelView(Context context, AttributeSet attrs) 不然会报错: 2).重写onMeasure方法 @Override protected void onMeasure(int width

Asp.net管理信息系统中数据统计功能的实现

数据统计是每个系统中必备的功能,在给领导汇报统计数据,工作中需要的进展数据时非常有用. 在我看来,一个统计的模块应该实现以下功能: 能够将常用的查询的统计结果显示出来: 显示的结果可以是表格形式,也可以是图形形式,如果是图形的话能够以多种形式显示(柱状图.折线图.饼图.雷达图.堆叠柱状图等): 统计查询的结果,点击数字或者百分比能够显示详细的数据: 能够自由组合查询条件.筛选条件.分组条件.排序等: 统计结果最好有个实时预览: 查询统计能够保存,以便下次能直接调用并显示统计查询的结果: 对于保存

对NSArray中自定义的对象进行排序

本文译自How to sort NSArray with custom objects. 我们开发的每个程序都会使用到一些数据,而这些数据一般被封装在一个自定义的类中.例如一个音乐程序可能会有一个Song类,聊天程序则又一个Friend类,点菜程序会有一个Recipe类等.有时候我们希望在程序中显示的列表数据是按照一定顺序进行排列的,本文我们就来看看在iOS中有哪些方法可以对NSArray中的对象进行排序.下面是目录: 小引 使用NSComparator进行排序 使用NSDescriptor进行

KM盒子V6.2自定义模版功能教程

KM盒子从V6.2版开始将原来的自定义首页功能升级为自定义模版功能,增加{img}文档缩图.{lit}标题.{liurl}链接.{descr}描述等模版标签的调用. 1.怎样使用自定义模版功能 我们在根目录节点"内容项目"节点上右键,在弹出的菜单中选择最下面的"自定义模版设置"菜单选项. 2.设置自定义模版 首先我们需要选择index.html首页文件,然后将"是否定制首页"选项选为"是". 3.了解模版目录结构 首页模版为根