cocos2dx_texture_cache
如何移除不需要的纹理?
cocos2d::Director::getInstance()->getTextureCache()->removeUnusedTextures();
假设我们把这句话叫做XXX。
何时需要移除不需要的纹理?
切换场景的时候(假设是A场景切换到B场景,那就是A场景的析构函数,或者B场景的构造函数)。
这两个地方我都写了XXX,结果不生效。
SceneA::~SceneA() { cocos2d::Director::getInstance()->getTextureCache()->removeUnusedTextures(); }
SceneB::SceneB() { cocos2d::Director::getInstance()->getTextureCache()->removeUnusedTextures(); }
为啥不生效呢?
不知道。
我们可以用 cocos2d::Director::getInstance()->getTextureCache()->getCachedTextureInfo() 来打印纹理缓存信息。
我打印过后发现,我想要移除的纹理的引用计数是等于1的,可没有移除成功。
怎么解决呢?
我测试过后发现,如果在切换场景前,把A场景里把对应的节点移除掉,再去调用XXX。就可以了。
bool SceneA::init() { if (!cocos2d::Scene::init()) { return false; } cocos2d::Director::getInstance()->getTextureCache()->removeUnusedTextures(); auto vorigin = cocos2d::Director::getInstance()->getVisibleOrigin(); auto vsize = cocos2d::Director::getInstance()->getVisibleSize(); auto sprite = cocos2d::Sprite::create("HelloWorld.png"); sprite->setPosition(cocos2d::Vec2(vsize.width / 2 + vorigin.x, vsize.height / 2 + vorigin.y)); this->addChild(sprite, 0, "spr"); auto replace_scene_item = cocos2d::MenuItemImage::create("res/a_1.png", "res/a_1.png", CC_CALLBACK_1(SceneA::OnClickReplaceScene, this)); replace_scene_item->setPosition(cocos2d::Vec2(vorigin.x + vsize.width - replace_scene_item->getContentSize().width / 2, vorigin.y + replace_scene_item->getContentSize().height / 2)); auto menu_node = cocos2d::Menu::create(replace_scene_item, nullptr); menu_node->setPosition(cocos2d::Vec2::ZERO); this->addChild(menu_node, 1, "menu"); auto s = cocos2d::Director::getInstance()->getTextureCache()->getCachedTextureInfo(); cocos2d::log("Scene A:\n%s", s.c_str()); return true; } void SceneA::OnClickReplaceScene(cocos2d::Ref * sender) { this->removeChildByName("spr", true); dynamic_cast<cocos2d::MenuItemImage*>(sender)->removeFromParentAndCleanup(true);//this->removeChildByName("menu", true);这样写不行,我也不知道为啥 cocos2d::Director::getInstance()->getTextureCache()->removeUnusedTextures(); auto scene = SceneB::create(); cocos2d::Director::getInstance()->replaceScene(scene); }
完整代码
class SceneA : public cocos2d::Scene
{
public:
static SceneA * create();
private:
virtual ~SceneA();
bool init();
void OnClickReplaceScene(cocos2d::Ref * sender);
};
SceneA()
{
//cocos2d::Director::getInstance()->getTextureCache()->removeUnusedTextures();
}
SceneA * SceneA::create()
{
auto p = new (std::nothrow) SceneA();
if (p && p->init())
{
p->autorelease();
return p;
}
delete p;
p = nullptr;
return nullptr;
}
bool SceneA::init()
{
if (!cocos2d::Scene::init())
{
return false;
}
cocos2d::Director::getInstance()->getTextureCache()->removeUnusedTextures();
auto vorigin = cocos2d::Director::getInstance()->getVisibleOrigin();
auto vsize = cocos2d::Director::getInstance()->getVisibleSize();
auto sprite = cocos2d::Sprite::create("HelloWorld.png");
sprite->setPosition(cocos2d::Vec2(vsize.width / 2 + vorigin.x, vsize.height / 2 + vorigin.y));
this->addChild(sprite, 0, "spr");
auto replace_scene_item = cocos2d::MenuItemImage::create("res/a_1.png", "res/a_2.png", CC_CALLBACK_1(SceneA::OnClickReplaceScene, this));
replace_scene_item->setPosition(cocos2d::Vec2(vorigin.x + vsize.width - replace_scene_item->getContentSize().width / 2, vorigin.y + replace_scene_item->getContentSize().height / 2));
auto menu_node = cocos2d::Menu::create(replace_scene_item, nullptr);
menu_node->setPosition(cocos2d::Vec2::ZERO);
this->addChild(menu_node, 1, "menu");
auto s = cocos2d::Director::getInstance()->getTextureCache()->getCachedTextureInfo();
cocos2d::log("Scene A:\n%s", s.c_str());
return true;
}
void SceneA::OnClickReplaceScene(cocos2d::Ref * sender)
{
this->removeChildByName("spr", true);
dynamic_cast<cocos2d::MenuItemImage*>(sender)->removeFromParentAndCleanup(true);//this->removeChildByName("menu", true);这样写不行,我也不知道为啥
cocos2d::Director::getInstance()->getTextureCache()->removeUnusedTextures();
auto scene = SceneB::create();
cocos2d::Director::getInstance()->replaceScene(scene);
}
SceneA::~
class SceneB : public cocos2d::Scene
{
public:
static SceneB * create();
private:
SceneB();
virtual bool init();
void menuCloseCallback(cocos2d::Ref* pSender);
};
SceneB()
{
//cocos2d::Director::getInstance()->getTextureCache()->removeUnusedTextures();
}
SceneB * SceneB::create()
{
auto p = new (std::nothrow) SceneB();
if (p && p->init())
{
p->autorelease();
return p;
}
delete p;
p = nullptr;
return nullptr;
}
bool SceneB::init()
{
if ( !cocos2d::Scene::init() )
{
return false;
}
auto visibleSize = cocos2d::Director::getInstance()->getVisibleSize();
auto origin = cocos2d::Director::getInstance()->getVisibleOrigin();
auto closeItem = cocos2d::MenuItemImage::create("CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(SceneB::menuCloseCallback, this));
closeItem->setPosition(cocos2d::Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width / 2, origin.y + closeItem->getContentSize().height / 2));
auto menu = cocos2d::Menu::create(closeItem, NULL);
menu->setPosition(cocos2d::Vec2::ZERO);
this->addChild(menu, 1);
return true;
}
void SceneB::menuCloseCallback(cocos2d::Ref* pSender)
{
auto s = cocos2d::Director::getInstance()->getTextureCache()->getCachedTextureInfo();
cocos2d::log("Scene B:\n%s", s.c_str());
}
SceneB::
输出结果
Scene A:
"G:/ZZZ/ccTestTexturecache/proj.win32/Debug.win32/Resources/HelloWorld.png" rc=2 id=1 195 x 270 @ 32 bpp => 205 KB
"G:/ZZZ/ccTestTexturecache/proj.win32/Debug.win32/Resources/res/a_1.png" rc=2 id=2 60 x 60 @ 32 bpp => 14 KB
"G:/ZZZ/ccTestTexturecache/proj.win32/Debug.win32/Resources/res/a_2.png" rc=2 id=3 60 x 60 @ 32 bpp => 14 KB
TextureCache dumpDebugInfo: 3 textures, for 233 KB (0.23 MB)
cocos2d: QuadCommand: resizing index size from [-1] to [2560]
cocos2d: TextureCache: removing unused texture: G:/ZZZ/ccTestTexturecache/proj.win32/Debug.win32/Resources/HelloWorld.png
cocos2d: TextureCache: removing unused texture: G:/ZZZ/ccTestTexturecache/proj.win32/Debug.win32/Resources/res/a_1.png
cocos2d: TextureCache: removing unused texture: G:/ZZZ/ccTestTexturecache/proj.win32/Debug.win32/Resources/res/a_2.png
Scene B:
"/cc_fps_images" rc=4 id=4 999 x 54 @ 16 bpp => 105 KB
"G:/ZZZ/ccTestTexturecache/proj.win32/Debug.win32/Resources/CloseNormal.png" rc=2 id=1 40 x 40 @ 32 bpp => 6 KB
"G:/ZZZ/ccTestTexturecache/proj.win32/Debug.win32/Resources/CloseSelected.png" rc=2 id=2 40 x 40 @ 32 bpp => 6 KB
TextureCache dumpDebugInfo: 3 textures, for 117 KB (0.12 MB)