cocos2dx 3.3 切场景时RenderTexture crash

在cocos2dx 3.3中下面myScene在切出时会存在概率性崩溃(代码作了最大程度简化,仅为说明问题):

class CmyLayer:public Layer{

public:

  CmyLayer(){

    m_sprite=NULL;

    m_renderTex=NULL;

  }

  virtual~CmyLayer(){

  }

  bool init(){

    m_sprite=Sprite::create("a.png");

    this->addChild(m_sprite);

    m_renderTex=RenderTexture::create(w,h);

    this->addChild(m_renderTex);

    

    return true;

  }

  void udpate(float dt){

    m_renderTex->begin();

    m_sprite->visit();

    m_renderTex->end();  

  }

private:

  RenderTexture* m_renderTex;

  Sprite* m_sprite;

};

class CmyScene:public Scene{

public:

  CmyScene(){

  }

  virtual~CmyScene(){

  }

  bool init(){

    CmyLayer*myLayer=new CmyLayer();

    myLayer->autorelease();

    myLayer->init();

    addChild(myLayer);

    return true;

  }

};

在myScene场景切出时概率性地崩溃在两个位置:

(1)RenderTexture的onBegin函数里,在RenderTexture的实现中onBegin是作为customCommand发出去的。

(2)崩溃在RenderTexture的GroupCommand里。

其中第一个崩溃位置出现频率占大多数。

崩溃在command里是最坑爹的,因为其执行是异步的,所以当崩溃时很难调查对象在发出此command时的当时状态,甚至连发出command的对象是谁都很难知道!数据/状态一致性问题和debug困难是我讨厌command机制的主要原因。

先停止吐槽,猜测崩溃原因,认为很可能是在场景切出时由于m_renderTex随myLayer一起销毁,但m_renderTex发出的customCommand已加入到command队列且尚未执行,这样当等到此customCommand执行时,它会调用m_renderTex的onBegin函数,但m_renderTex已销毁,所以产生不可预料的结果。

为了避免“对象已销毁但其customCommand已发出却尚未执行”而导致的“调用对象不存在”的情况出现,我尝试采取了下面两个措施:

1,在场景切出时尽早停止CmyLayer::update。(因为崩溃的customCommand是在CmyLayer::update的m_renderTex->begin()中发出的)

2,在场景切出时推迟销毁m_renderTex。

具体地,CmyLayer代码改成:

class CmyLayer:public Layer{

public:

  CmyLayer(){

    m_sprite=NULL;

    m_renderTex=NULL;

  }

  virtual~CmyLayer(){

    if(m_renderTex)m_renderTex->autorelease();//add, inorder to achieve delay release, use autorelease instead of release

  }

  bool init(){

    m_sprite=Sprite::create("a.png");

    this->addChild(m_sprite);

    m_renderTex=RenderTexture::create(w,h);

    this->addChild(m_renderTex);

    m_renderTex->retain();//add

    

    return true;

  }

  void udpate(float dt){

    m_renderTex->begin();

    m_sprite->visit();

    m_renderTex->end();  

  }

  void onExit(){

   CCLayer::onExit();

this->unscheduleUpdate();//add, stop update as soon as possible

}

private:

  RenderTexture* m_renderTex;

  Sprite* m_sprite;

};

我不知道这两处改动是否都是必须的,由于是概率性崩溃,验证和重现比较耗时,所以在没有更清晰的分析之前暂时两处改动都保留。如此改之后目前为止还没有再发生崩溃。但这种修补显然是不自然的,不知道有没有更好的办法。

补充:

本例中由于m_sprite是普通Sprite,不包含customCommand,所以m_sprite不会存在“调用对象不存在”的问题,但假如m_sprite是一个自定义sprite或者是一个更复杂的子树结构且其中也含有customCommand的话,则m_sprite也需要像m_renderTex一样处理,使其推迟释放。

时间: 2024-10-15 00:18:54

cocos2dx 3.3 切场景时RenderTexture crash的相关文章

unity,生成的mac版游戏切场景时卡死解法

unity版本为5.1.1,在编辑器里运行没问题,build出的windows版运行也没问题,但build出的mac版在个别场景切换时会卡死,通过查看log(查看build版本log的方法参考:http://blog.theknightsofunity.com/accessing-unity-game-logs/),看到最后报出的错误是: Receiving unhandled NULL exception 如果改成development build,则不会卡死,运行正常. 搜到这个帖子:htt

cocos2dx基础篇(26)——场景切换CCTransitionScene

[唠叨] 游戏中两个场景的切换时经常要被用到的,cocos2dx引擎为我们提供了许多场景切换的动画,我感觉有些和PPT的切换很类似,所以感觉很熟悉.如:淡入淡出.翻页.跳入跳出等等. 本节要讲的场景切换方式十分丰富,不过内容比较简单,很容易掌握. [致谢] http://gl.paea.cn/contents/d4d676f371519df4.html [场景管理] 在讲场景切换CCTransitionScene之前,先来复习一下场景CCScene的管理. 游戏运行的过程中,每次只能运行一个场景

Cocos2dx打包成apk包时在手机上闪退

在项目运行过程中,在手机上运行会出现闪退的现象, 报告错误代码如下: 06-30 10:45:19.921: E/cocos2d-x assert(28033): E:/workspace/cocos2d-x-2.2.2/projects/****/proj.android/../../../cocos2dx/platform/android/CCApplication.cpp function:sharedApplication line:60 06-30 10:45:19.921: A/li

Cocos2dx 学习笔记整理----场景切换

据说Cocos2dx场景切换的方法有32种:cocos2dx 常见的32种切换场景的动画 无需一一求证,只需要知道切换场景需要怎么做就行了. 作为导演CCDirector,切换场景的事情当然归它管了. 切换场景的接口如下: ? 1 CCDirector::sharedDirector()->replaceScene(cocos2d:CCScene * pScene); 所以,我们只要把需要切换的场景实例传进去就可以了. ? 1 2 CCScene * pScene = GameMain::sce

【Cocos2d-x】编译Android工程时提示error: 'GL_LINE_SMOOTH' was not declared in this scope

在Cocos2d-x项目中用到了OpenGL,使用GL_LINE_SMOOTH开启线条抗锯齿.代码如下: ccDrawColor4B(50, 26, 12, 255); // 设置线宽 glLineWidth(2.0f); // 启用线段反锯齿 glEnable(GL_LINE_SMOOTH); // 画第一条线 ccDrawLine(startPoint1,endPoint); // 画第二条线 ccDrawLine(startPoint2,endPoint); // 关闭线段反锯齿 glDi

unity在切换场景时,场景灯光变暗的问题

当你有多个场景使,需要切换场景,当你切换到下一个场景时出现了场景灯光变暗的效果.然后操作是 window--lighting--取消auto后点击build就可以了 主要出现这个问题的原因是:当前你的灯光是实时光照 在当前场景时已经渲染完成.但重新加载的时候没有渲染.先把渲染灯光烘培一下.保存起来就没事了.

LoadRunner中运行场景时提示"You do not have a license for this Vuser type."

LoadRunner中运行场景时提示"You do not have a license for this Vuser type." 2012-06-15 17:09:07|  分类: Software Testing |举报 |字号 订阅 问题: 使用Java Vuser协议调用Java应用程序,脚本执行通过后,在Controller中运行场景时,均为Errors不通过,报错如下: 解决: 百度"You do not have a license for this Vuse

Innodb parent table open时导致crash

case描述: innodb中,父表和子表通过foreign constraint进行关联, 因为在更新数据时需要check 外键constraint,如果父表被大量的子表reference, 那么在open的时候,需要open所有的child table和所有的foreign constraint,导致时间过长,产生long semaphore wait . 分析过程: case 用例: CREATE TABLE `t1` ( `f1` int(11) NOT NULL, PRIMARY KE

cocos2d-x android 添加新场景报错: undefined reference to `vtable for XXX'

转载自 居家懒人 http://www.cnblogs.com/JD85/archive/2012/09/17/2688128.html 加入写了新场景SecondScene,结果在cpp文件里类名地方报错说undefined reference to `vtable for SecondScene', 很简单,貌似是每个新场景都要先注册一下,找到jni-->Classes目录下的Android.mk文件,在 LOCAL_SRC_FILES := AppDelegate.cpp HelloWor