查看: 3241|回复: 5

DriveManipulator类在哪重绘的啊?

[复制链接]

该用户从未签到

发表于 2008-8-29 10:46:52 | 显示全部楼层 |阅读模式
我想继承DriveManipulator自己写一个功能更强大的漫游器,把这个类的源代码研究了3天了,一直没找到它是在哪更新重绘的。以前一直以为这里面显示是靠handle里面的:
  1.         case(GUIEventAdapter::FRAME):
  2.                 {
  3.                         bool ch = IsEyePositionChanged();
  4.                         addMouseEvent(ea);
  5.                         if (calcMovement())
  6.                         {
  7.                                 if (ch)
  8.                                 {
  9.                                         _eye += up*10;
  10.                                 }
  11.                                 us.requestRedraw();
  12.                         }
  13.                         return false;
  14.                 }
复制代码
结果试着把us.requestRedraw();删了,它还是能进行重绘。怀疑重绘的函数不是在这个类里面。但如果不是在这个类里面,也应该需要获取这个类的数据来进行绘制,所以我在getMatrix()这个函数里面设了个断点。但我遗憾的发现,这个函数从来没被调用过。
DriveManipulator类里面照相机的位置保存在_eye这个成员变量里面,更改它可以直接更改照相机的位置。所以我继承的类都是直接对_eye变量进行操作。但由于不能自己控制重绘,_eye变量还没改动完就进行重绘了,所以画面抖动很厉害。望各位帮忙啊,先谢谢了~~~

MyDriveManipulator.rar

1.76 KB, 下载次数: 154, 下载积分: 威望 1

继承DriveManipulator写的类

该用户从未签到

发表于 2008-8-29 11:53:52 | 显示全部楼层
漫游器的唯一工作就是改变摄像机的观察矩阵,除此之外它什么都不作。场景重绘之类的工作是由渲染器Renderer+图形设备GC完成的

该用户从未签到

 楼主| 发表于 2008-8-29 12:16:16 | 显示全部楼层
观察矩阵(_eye,_rotation,_pitch)还没设置完就被渲染器Renderer调用了怎么办?怎样可以等设置完成了之后再让渲染器调用?

该用户从未签到

发表于 2008-8-29 13:47:13 | 显示全部楼层
原帖由 Sailent 于 2008-8-29 12:16 发表
观察矩阵(_eye,_rotation,_pitch)还没设置完就被渲染器Renderer调用了怎么办?怎样可以等设置完成了之后再让渲染器调用?


每一帧都会将事件队列传递给handle函数(Viewer::eventTraversal),然后设置当前摄像机的Matrix为漫游器的InverseMatrix(Viewer::updateTraversal),然后才是渲染操作;就算是多线程渲染,由于有栅栏(Barrier)同步的关系,也不会影响到观察矩阵的设置。所以应该不会出现您所说的“还没设置完就被渲染器Renderer调用”的情况。

您说“把这个类的源代码研究了3天了,一直没找到它是在哪更新重绘的”。事实上不必考虑什么重绘的问题,最重要的函数是DriveManipulator::getInverseMatrix,只要这个函数的内容设置正确,那么摄像机的观察矩阵就不会有误

该用户从未签到

 楼主| 发表于 2008-8-29 14:59:43 | 显示全部楼层
DriveManipulator::getInverseMatrix会在什么时候调用呢?举个例子吧,假如在handle函数中有如下代码:
_eye += osg::vec(0.0f,0.0f,10.0f);  //将摄像机抬高10个单位
。。。。。。。。
这期间要做很多别的事情,我很不希望它在这个时候调用DriveManipulator::getInverseMatrix,但不巧的是它偏偏就在这个时候调用了,结果摄像机停在了一个非预期的位置
。。。。。。。。
_eye += osg::vec(0.0f,0.0f,10.0f);  //我希望它这时候再调用DriveManipulator::getInverseMatrix获取数据进行重绘。

另外说一下,DriveManipulator::getInverseMatrix是虚函数,我在继承的子类中将其重写了,运行的时候应该调用子类的getInverseMatrix。所以我在子类的getInverseMatrix函数中设置了一个断点,想看它什么时候会被调用。可惜调试的时候那个断点从来没被跟进去过,不知道为什么

该用户从未签到

发表于 2008-8-29 16:36:11 | 显示全部楼层
原帖由 Sailent 于 2008-8-29 14:59 发表
DriveManipulator::getInverseMatrix会在什么时候调用呢?举个例子吧,假如在handle函数中有如下代码:
_eye += osg::vec(0.0f,0.0f,10.0f);  //将摄像机抬高10个单位
。。。。。。。。
这期间要做很多别的事情, ...


“DriveManipulator::getInverseMatrix是虚函数”,是的,您的话没错,不过这不代表它不会被调用,请参看DriveManipulator.cpp,417行(OSG 2.6源代码)。漫游器的基类中有一个纯虚函数MatrixTransform::getInverseMatrix,每个派生类都会重写它以实现自己的功能。

如果您重写了DriveManipulator::getInverseMatrix,那么请确保您的函数同样是
osg::Matrixd getInverseMatrix () const
格式,注意要有const修饰字。
如果您的getInverseMatrix 还是没有被调用,请检查是否设置了正确的场景漫游器。

“但不巧的是它偏偏就在这个时候调用了”,我个人认为不会出现这种“不巧”,因为获取漫游器矩阵不是渲染线程的工作,而是用户更新遍历函数的工作,它必然在handle函数之后顺序被执行。请检查您的代码有没有处理不妥当的地方
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表