游戏开发论坛

 找回密码
 立即注册
搜索
查看: 3979|回复: 3

总结今天使用 Ogre 遇到的几个Bug

[复制链接]

32

主题

1259

帖子

1351

积分

金牌会员

Rank: 6Rank: 6

积分
1351
发表于 2007-6-27 20:22:00 | 显示全部楼层 |阅读模式
如有转载, 请注明:
http://www.azure.com.cn/

今天使用Ogre, 居然接连遇到了Ogre的几个Bug, 首先我声明我使用的Ogre1.2版本, 也许这些我所谓的Bug在1.4版本中已经修正了.

1. Entity::setVisible() 无效
平常使用setVisible() 总是屡试不爽, 感觉没有什么问题, 今天突然发现 setVisible() 居然无效了, 后来又发现对于有的Entity是有效的, 有的又无效了, 郁闷了半天. 后来发现只要Entity使用了非固定管线的材质(Shader), 其setVisible就没有作用了, 汗一个, 典型是那个Fresnel反射的水面, 无法通过setVisible()隐藏掉, 后来我使用SceneNode::detachObject()代替了. 再汗一个.

2. Root::removeFrameListener() 无效
与上面那个Bug相比, 这个Bug更让人匪夷所思, 并不是说removeFrameListener不起作用, 它却是在下一桢内才真正把这个Listener删除掉, 这一桢内却是还是正常的回调.
这样对于这样一个结构的代码, 就有个致命的问题了(我自己认为我的这个代码构架很不错)
比如有这样一个对象, 需要每桢动态Update自己的数据, 于是我使用了FrameListener

class Object : public FrameListener
{
   Object();
   ~Object();
   bool frameStarted(const FrameEvent& evt);
}

当然我在构造的时候, 讲自己注册为FrameListener , 因为自己本身就是FrameListener


Object::Object()
{
  Root::getSingleton().addFrameListener(this);
}

这段代码工作的很好, 加入以后函数里面的frameStarted()每桢都会被回调了, 这没有问题.
关键是销毁的时候, 当然同理, 在我们销毁Object对象的时候, 我们要removeFrameListener, 这看似理所当然的东西,在运行的时候却出现了致命的错误.
我们的析构函数如下:

Object::~Object()
{
  Root::getSingleton().removeFrameListener(this);
}

看上去很完美吧? 其实当你销毁这个对象的时候是一定会出错的. 因为Ogre是下一桢才真正Remove掉的, 这一桢还是要照常执行这个回调的, 不信的话就去瞧SourceCode, 但是当这个析构执行完后, this的只个对象就消失了, Ogre保存的FrameListener其实是一堆垃圾, 他一调用当然就错了啊.
后来, 没有办法, 加了一行臭代码, 解决了这个问题, 但始终觉得很恶心.

Object::~Object()
{
  Root::getSingleton().removeFrameListener(this);
  Root::getSingleton().renderOneFrame();         //跳一桢真正Remove掉FrameListener
}


3. 虽然物体隐藏了, 但渲染到纹理的过程仍然在继续
比如当我渲染Rtt的水, 当我把水面的Entity隐藏了,本以为其Rtt过程会自动停止,其实不然,它仍然在默默的渲染着,一刻都不停息过,这个问题是我用NVPerfHUD检查的时候发现的.其实仔细想想,也不能算他是个Bug吧, Ogre也没有义务在你隐藏Entity时候自动关闭Rtt. 所以我建议大家使用Rtt的时候,不要使用AutoUpdate(),那样是不好控制的,
使用手动Update,在FrameListener中根据当前物体的显示和隐藏情况自动决定是否要更新RenderTexture.

感觉这几个bug都有些难以理解, 尤其最后一个, 要多加小心, 因为他很难被发现, 又白白的浪费的性能.

www.azure.com.cn

13

主题

90

帖子

96

积分

注册会员

Rank: 2

积分
96
发表于 2007-6-28 12:41:00 | 显示全部楼层

Re: 总结今天使用 Ogre 遇到的几个Bug

多谢提醒,以后使用过程中注意一下

0

主题

1

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2007-6-28 17:56:00 | 显示全部楼层

Re:总结今天使用 Ogre 遇到的几个Bug

在frameEnded函数里更新你的场景试一下
这样当你渲染完场景时,当前frame已经结束了,下个frame马上就会开始
这样应该能避开这个错误(只是猜想,没测试)

21

主题

120

帖子

129

积分

注册会员

Rank: 2

积分
129
发表于 2007-7-2 08:41:00 | 显示全部楼层

Re:总结今天使用 Ogre 遇到的几个Bug

关于第二点我完全不同意你的说法,你应该像3楼说的那样把析勾+移除放置在frameend中。
ogre保存framelistener并不是垃圾:因为framelistener是逻辑的所在,当一个framelistener自己移除自己的时候,有可能他还在执行的过程中,因此需要保留到该帧的结束
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-25 23:22

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表