缓存机制
- Cocos2d-x纹理缓存
- Cocos2d-x精灵帧缓存
- Cocos2d-x动画缓存
纹理缓存
Sprite *grossini = Sprite::create("grossini_dance_01.png");<span style="white-space:pre"> </span>// 用图片创建精灵对象接下来,转向精灵的create()函数的实现:
Sprite* Sprite::create(const std::string& filename) { Sprite *sprite = new (std::nothrow) Sprite();<span style="white-space:pre"> </span>// 用C++的方式,创建一个精灵 if (sprite && sprite->initWithFile(filename))<span style="white-space:pre"> </span>// 检查精灵对象,并进行文件初始化 { sprite->autorelease(); return sprite; } CC_SAFE_DELETE(sprite);<span style="white-space:pre"> </span>// 安全释放精灵对象 return nullptr; }转向精灵文件初始化:
bool Sprite::initWithFile(const std::string& filename) { CCASSERT(filename.size()>0,"Invalid filename for sprite"); // 生成纹理图片 Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename); if (texture) { Rect rect = Rect::ZERO; rect.size = texture->getContentSize(); return initWithTexture(texture,rect);<span style="white-space:pre"> </span>// 初始化纹理,将纹理图片进行添加 } // don't release here. // when load texture Failed,it's better to get a "transparent" sprite then a crashed program // this->release(); return false; } bool Sprite::initWithTexture(Texture2D *texture,const Rect& rect) { return initWithTexture(texture,rect,false);<span style="white-space:pre"> </span>// 初始化纹理 }
转向初始化纹理initWithTexture(texture,rect):
<pre name="code" class="cpp">bool Sprite::initWithTexture(Texture2D *texture,const Rect& rect,bool rotated) { bool result; if (Node::init()) { ............ ............ // 这里是关键点,将纹理图片设置添加到纹理缓存 setTexture(texture); // 设置纹理矩形 setTextureRect(rect,rotated,rect.size); _polyInfo.setQuad(&_quad); // by default use "Self Render". // if the sprite is added to a batchnode,then it will automatically switch to "batchnode Render" setBatchNode(nullptr); result = true; } else { result = false; } _recursiveDirty = true; setDirty(true); return result; }继而查看将纹理图片设置添加到纹理缓存setTexture(texture);,其他的我们不需要注意,只需看如何将图片添加到纹理缓存:
<pre name="code" class="cpp">void Sprite::setTexture(Texture2D *texture) { // If batchnode,then texture id should be the same CCASSERT(! _batchNode || texture->getName() == _batchNode->getTexture()->getName(),"CCSprite: Batched sprites should use the same texture as the batchnode"); // accept texture==nil as argument CCASSERT( !texture || dynamic_cast<Texture2D*>(texture),"setTexture expects a Texture2D. Invalid argument"); if (texture == nullptr) { // 根据图片文件名,从纹理缓存中获取纹理图片 texture = Director::getInstance()->getTextureCache()->getTextureForKey(CC_2x2_WHITE_IMAGE_KEY); // 如果获取内容为NULL,说明为缓存至纹理缓存 if (texture == nullptr) { Image* image = new (std::nothrow) Image(); bool isOK = image->initWithRawData(cc_2x2_white_image,sizeof(cc_2x2_white_image),2,8); CC_UNUSED_PARAM(isOK); CCASSERT(isOK,"The 2x2 empty texture was created unsuccessfully."); // 根据图片文件名,将图片添加到纹理缓存 texture = Director::getInstance()->getTextureCache()->addImage(image,CC_2x2_WHITE_IMAGE_KEY); CC_SAFE_RELEASE(image); } } if (!_batchNode && _texture != texture) { CC_SAFE_RETAIN(texture); CC_SAFE_RELEASE(_texture); _texture = texture; updateBlendFunc(); } }至此,我们就将图片添加到纹理缓存并创建了一个精灵对象。
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
<pre name="code" class="cpp">Texture2D * TextureCache::addImage(const std::string &path) { Texture2D * texture = nullptr; Image* image = nullptr; // Split up directory and filename // MUTEX: // Needed since addImageAsync calls this method from a different thread // 通过FileUtils::getInstance()->fullPathForFilename(path);获取完整的路径 std::string fullpath = FileUtils::getInstance()->fullPathForFilename(path); if (fullpath.size() == 0) { return nullptr; } // 通过路径寻找纹理缓存中是否存在 auto it = _textures.find(fullpath); if( it != _textures.end() ) texture = it->second; // 如若不存在 if (! texture) { // all images are handled by UIImage except PVR extension that is handled by our own handler do { image = new (std::nothrow) Image(); CC_BREAK_IF(nullptr == image); bool bRet = image->initWithImageFile(fullpath); CC_BREAK_IF(!bRet); texture = new (std::nothrow) Texture2D(); // 将图片添加转换成纹理 if( texture && texture->initWithImage(image) ) { #if CC_ENABLE_CACHE_TEXTURE_DATA // 缓存纹理及文件名 VolatileTextureMgr::addImageTexture(texture,fullpath); #endif // _textures为纹理缓存字典,将纹理及路径插入到字典 _textures.insert( std::make_pair(fullpath,texture) ); //parse 9-patch info this->parseNinePatchImage(image,texture,path); } else { CCLOG("cocos2d: Couldn't create texture for file:%s in TextureCache",path.c_str()); } } while (0); } CC_SAFE_RELEASE(image); return texture; }
精灵帧缓存