博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
我的Cocos2d-x学习笔记(八)利用CCSpriteBatchNode进行优化
阅读量:4467 次
发布时间:2019-06-08

本文共 4155 字,大约阅读时间需要 13 分钟。

OpenGL是一个基于C语言的三维图形API,是一个开放的、跨平台的图形接口。

OpenGL ES是OpenGL在移动设备上的版本。

Cocos2d-x是一个基于OpenGL的游戏引擎,渲染功能由OpenGL实现。

游戏中会用到许多图片资源,对图片资源渲染进行优化能明显提高效率。

OpenGL中纹理的长和宽像素是2的幂,大小不足的纹理补充到2的幂大小;可以通过把多张小图片合成一张大图加载到游戏中,减少纹理加载次数,减少补齐2的幂大小的空白。

之前学习的纹理缓存、精灵帧缓冲可以把纹理等预先加载到内存中,访问时候节省访问时间;除此之外还可以通过CCSpriteBatchNode节省渲染次数来达到优化的目的。

CCSpriteBatchNode(精灵批处理类):

原理借鉴一下权威指南内容:

    当你需要显示两个或两个以上相同的精灵时,如果逐个渲染精灵,每一次渲染都会调用OpenGL的函数;

    因为当系统在屏幕上渲染一张贴图的时候,图形处理硬件必须首先准备渲染,然后渲染图形,最后完成渲染以后的清理工作。

    以上是每次渲染固定的开销,这样帧率就会下降15%左右或者更多。

    如果将所有需要渲染的同一张贴图只进行一次准备,一次渲染,一次清理就可以解决这个问题了。

    这时可以使用CCSpriteBatchNode类来批处理这些精灵。

CCSpriteBatchNode:

先来看看它的创建相关代码:

class CC_DLL CCSpriteBatchNode : public CCNode, public CCTextureProtocol{public:	static CCSpriteBatchNode* create(const char* fileImage, unsigned int capacity);	static CCSpriteBatchNode* create(const char* fileImage)	{		return CCSpriteBatchNode::create(fileImage, kDefaultSpriteBatchCapacity);	}	static CCSpriteBatchNode* createWithTexture(CCTexture2D* tex, unsigned int capacity);	static CCSpriteBatchNode* createWithTexture(CCTexture2D* tex) 	{		return CCSpriteBatchNode::createWithTexture(tex, kDefaultSpriteBatchCapacity);	}}
    由上述代码可以看到CCSpriteBatchNode可以通过图片文件直接创建,也可以通过纹理来创建。

    CCSpriteBatchNode

(一)、通过图片文件创建CCSpriteBatchNode并且使用它

static CCSpriteBatchNode* create(const char* fileImage, unsigned int capacity);	static CCSpriteBatchNode* create(const char* fileImage)	{		return CCSpriteBatchNode::create(fileImage, kDefaultSpriteBatchCapacity);	}
通过纹理图片直接创建精灵批处理我们可以使用两个创建函数,不过由上述代码可以看出其实只有一个创建函数;

只指定纹理图片路径名称时候,其第二个参数capacity(表示纹理图像容量)为一个系统默认值,并且此函数调用的为两个参数的create函数。

实例:

CCSpriteBatchNode* batchNode = CCSpriteBatchNode::create("HelloWorld.png");	for (int i = 0; i < 50; i++)	{		CCSprite* sprite = CCSprite::create("HelloWorld.png");		batchNode->addChild(sprite);	}	addChild(batchNode);
首先,通过纹理图片创建一个精灵批处理;

之后,通过循环创建50个精灵,把这50个精灵添加到批处理当中;

最后把批处理加入到父节点。

(二)通过CCTexture2D创建CCSpriteBatchNode并且使用它

实例一:通过纹理缓存中取得纹理创建精灵批处理,此后创建精灵时候可以使用纹理图片名字创建。

CCTexture2D * texture = CCTextureCache::sharedTextureCache()->addImage("HelloWorld.png");	CCSpriteBatchNode* batchNode = CCSpriteBatchNode::createWithTexture(texture);	for (int i = 0; i < 29; i++)	{		CCSprite* sprite = CCSprite::create("HelloWorld.png");		batchNode->addChild(sprite);	}	addChild(batchNode);

CCTexture2D * texture = CCTextureCache::sharedTextureCache()->addImage("HelloWorld.png");	CCSpriteBatchNode* batchNode = CCSpriteBatchNode::createWithTexture(texture);	for (int i = 0; i < 50; i++)	{		CCSprite* sprite = CCSprite::createWithTexture(texture);		batchNode->addChild(sprite);	}	addChild(batchNode);

上诉两种方式实际上使用起来同样效果,解释如下:

首先,通过纹理缓存获取一个纹理;

之后,通过循环创建50个精灵,把这50个精灵添加到批处理当中,此时创建精灵的时候可以使用纹理图片名称,也可以使用之前从纹理缓冲中获取的纹理;

最后把批处理加入到父节点。

实例二:通过直接创建一个纹理(CCTexture2D)来创建精灵批处理,此后精灵创建时候必须使用之前创建的纹理来创建精灵。

CCImage* image = new CCImage();	image->initWithImageFile("HelloWorld.png");	image->autorelease();	CCTexture2D* texture = new CCTexture2D();	texture->initWithImage(image);	texture->autorelease();	CCSpriteBatchNode* batchNode = CCSpriteBatchNode::createWithTexture(texture);	for (int i = 0; i < 50; i++)	{		CCSprite* sprite = CCSprite::createWithTexture(texture);		batchNode->addChild(sprite);	}	addChild(batchNode);
首先,通过new的方式获取一个纹理;

之后,通过循环创建50个精灵,把这50个精灵添加到批处理当中,此时的精灵需要用到之前创建的纹理来创建;

最后把批处理加入到父节点。

实例三:加载多张图片使用

CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("batch.plist");	CCSpriteBatchNode* batchNode = CCSpriteBatchNode::create("bach.png");	addChild(batchNode);
上诉代码在精灵帧缓冲中加入一个plist文件;

利用plist对应的图片创建CCSpriteBatchNode;

之后

static bool flag = true;	CCSprite * sprite;	for (int i = 0; i < 1000; i++)	{		if (flag)		{			sprite = CCSprite::createWithSpriteFrameName("one.png");		}		else{			sprite = CCSprite::createWithSpriteFrameName("two.png");		}		flag = !flag;		sprite->setPosition(ccp(CCRANDOM_0_1() * 480, CCRANDOM_0_1() * 320));		batchNode->addChild(sprite);	}
之前把纹理图片添加到精灵帧缓冲中后使用CCSpriteBatchNode创建同一张图片;

此后通过精灵帧缓冲中的精灵帧创建精灵同样为优化后的。

总结:

    当我们需要多次使用同一张纹理创建的精灵时候使用它。

     因为所有CCSprite节点都添加到同一个CCSpriteBatchNode中,所以所有CCSprite的zOrder相同。

     添加到同一个CCSpriteBatchNode中的CCSprite必须使用同一个纹理图片。

     精灵帧缓冲(CCSpriteFrameCache)与精灵批处理(CCSpriteBatchNode)结合使用效果更好!

    

转载于:https://www.cnblogs.com/gongyan/p/4539405.html

你可能感兴趣的文章
Redis消息队列
查看>>
电商网站架构设计
查看>>
http://jingyan.baidu.com/article/4dc40848e7b69bc8d946f127.html
查看>>
WCF netTcp配置
查看>>
数据类型转换
查看>>
Nodejs学习笔记(2) 阻塞/非阻塞实例 与 Nodejs事件
查看>>
什么是FreeMaker
查看>>
设计模式学习笔记(总结篇:模式分类)
查看>>
TCP的三次握手/建立连接
查看>>
Python 教程阅读笔记(一):使用解释器
查看>>
运算符重载
查看>>
SDWebImage 新版接口使用方法
查看>>
DataTable导出为word,excel,html,csv,pdf,.txt
查看>>
android ListView详解
查看>>
软件工程 第一次作业
查看>>
Content Server HA搭建
查看>>
(2)数据结构——线性表(链表)实现
查看>>
[leetCode]Linked List Cycle I+II
查看>>
leetcode中的python学习
查看>>
Zookeeper zkui-zookeeper图形化管理工具
查看>>