加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos-js,内存管理3---查看器

发布时间:2020-12-14 17:07:10 所属栏目:百科 来源:网络整理
导读:一、纹理缓存(TextureCache) 纹理缓存是将纹理缓存起来方便之后的绘制工作。每一个缓存的图像的大小,颜色和区域范围都是可以被修改的。这些信息都是存储在内存中的,不用在每一次绘制的时候都发送给GPU。 首先,我们创建一个精灵 Sprite* Sprite::create(

一、纹理缓存(TextureCache)

纹理缓存是将纹理缓存起来方便之后的绘制工作。每一个缓存的图像的大小,颜色和区域范围都是可以被修改的。这些信息都是存储在内存中的,不用在每一次绘制的时候都发送给GPU。

首先,我们创建一个精灵

Sprite* Sprite::create(const std::string& filename)
{
    Sprite *sprite = new (std::nothrow) Sprite();
    if (sprite && sprite->initWithFile(filename))
    {
        sprite->autorelease();
        sprite->setName(filename.c_str());
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

然后,继续深入,initWithFile的方法

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

    // don't release here.
    // when load texture failed,it's better to get a "transparent" sprite then a crashed program
    // this->release();
    return false;
}

最后在TextureCache 的 addImage方法里,我们会先去集合里查找是否之前加载过,如果没有找到,那么我们就会新生成一张纹理,并且添加到集合里。


二、精灵帧缓存(CCSpriteFrameCache)

CCSpriteFrameCache单例是所有精灵帧的缓存。使用spritesheet和与之相关的xml文件,我们可以加载很多的精灵帧到缓存中,那么之后我们就可以从这个缓存中创建精灵对象了。


三、创建内存查看器

在TextureCache中有个getCachedTextureInfo的方法

这个方法可以输出每一张纹理所占用的内存,但是log日志输出查看的话,难免不够直观,查看起来不太方便,所以这里我就想到把所有的这些纹理封装到一个Node里,然后显示在屏幕上。

Node* TextureCache::getCachedTextureNode() const
{
    std::string buffer;
    char buftmp[4096];
    unsigned int count = 0;
    unsigned int totalBytes = 0;

    //    wade
    Node* node = Node::create();

    int _height = 0;
    for( auto it = _textures.begin(); it != _textures.end(); ++it ) {

        memset(buftmp,sizeof(buftmp));
        Texture2D* tex = it->second;
        Sprite* _sprite = Sprite::createWithTexture(tex);
        if (_sprite) {
            _sprite->setAnchorPoint(Point(0,1));
            _sprite->setPositionY(-_height);
            node->addChild(_sprite);
            _height = _height+_sprite->getContentSize().height;

        }

        unsigned int bpp = tex->getBitsPerPixelForFormat();
        // Each texture takes up width * height * bytesPerPixel bytes.
        auto bytes = tex->getPixelsWide() * tex->getPixelsHigh() * bpp / 8;
        totalBytes += bytes;
        count++;
        snprintf(buftmp,sizeof(buftmp)-1,""%s" rc=%lu id=%lu %lu x %lu @ %ld bpp => %lu KBn",it->first.c_str(),(long)tex->getReferenceCount(),(long)tex->getName(),(long)tex->getPixelsWide(),(long)tex->getPixelsHigh(),(long)bpp,(long)bytes / 1024);

        buffer += buftmp;
    }

    snprintf(buftmp,"TextureCache dumpDebugInfo: %ld textures,for %lu KB (%.2f MB)n",(long)count,(long)totalBytes / 1024,totalBytes / (1024.0f*1024.0f));
    buffer += buftmp;

    return node;
}

接下来就是JS的工作了,至于怎么导出C++接口到JS中,这里就不作介绍了,在JS中我们创建了一个叫MemoryLayer的类,专门用来负责显示缓存。

var MemoryLayer = cc.LayerColor.extend({

    node:null,startPosition:null,distance:0,ctor:function(){
        this._super(cc.color(0,200));

        this.initTouchEvent();
        this.initView();
    },initView:function(){
        var _info = cc.TextureCache.getInstance().getCachedTextureInfo()
        cc.log("wade MemoryLayer info:"+_info)

        node = cc.TextureCache.getInstance().getCachedTextureNode();
        node.setPositionY(cc.winSize.height);
        node.setScale(0.5);
        this.addChild(node);

        var closeBtn = new ccui.Button("res/Default/Button_Normal.png");
        this.addChild(closeBtn);
        var size = cc.director.getWinSize();
        closeBtn.setPosition(cc.p(size.width-100,size.height-100));
        closeBtn.addTouchEventListener(this.closeBtnListener,this);

        cc.log(" MemoryLayer initView success");
    },closeBtnListener:function(_sender,_type){
        switch(_type){
            case ccui.Widget.TOUCH_ENDED:
                this.removeFromParent();
                break;
        }
    },initTouchEvent : function(){
        //对layer添加触摸事件;
        var listener = cc.EventListener.create({
            event: cc.EventListener.TOUCH_ONE_BY_ONE,swallowTouches:true,onTouchBegan:this.onTouchBegan.bind(this),onTouchMoved:this.onTouchMoved.bind(this),onTouchEnded:this.onTouchEnded.bind(this)
        });
        cc.eventManager.addListener(listener,this);
    },onTouchBegan : function(touch,event){
        startPosition = touch.getLocation().y;
        return true;
    },onTouchMoved : function(touch,event){
        var curPosition = touch.getLocation().y;

        var dis = (curPosition - startPosition);
        startPosition = curPosition;

        this.distance = this.distance + dis;
        if(this.distance<0){
            this.distance = 0;
            return;
        }
        node.setPositionY(node.getPositionY()+dis);
    },onTouchEnded : function(touch,event){
        return true;
    },})

最后以一张效果图作为本期节目的结束:

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读