查看: 1375|回复: 5

请问有什么方法能高效率地保存画面

[复制链接]

该用户从未签到

发表于 2012-4-17 17:20:52 | 显示全部楼层 |阅读模式
大家好。OSG目前的机制是:处理一帧,显示一帧。如果偶尔有一帧需要花好几帧的时间才能处理完成,那看起来就会“卡”。
我想修改成:在缓冲区中存有好几帧已经处理好的画面,当偶尔有一帧需要花好几帧的时间才能处理完成时,显示线程不受影响,依然能取出缓冲区中的画面显示,画面就不会卡住。
现在的问题是:如何把生成好的每一帧画面存起来?
我用osgautocapture例子中类似的方法,camera->setFinalDrawCallback(new WindowCaptureCallback())),然后在Callback中用readPixels把画面读出来,虽然能保存,但效率很低,每一帧所花的时间长了很多。
请问有什么方法能高效率地保存画面吗?

该用户从未签到

发表于 2012-4-18 13:29:12 | 显示全部楼层
您说的这种方案我早就实现过了,简单来说就是维护一个准备保存的图像列表,然后在另一个线程中将它们输出。不会有任何停顿

该用户从未签到

 楼主| 发表于 2012-4-18 14:08:28 | 显示全部楼层
array 发表于 2012-4-18 13:29
您说的这种方案我早就实现过了,简单来说就是维护一个准备保存的图像列表,然后在另一个线程中将它们输出。 ...

谢谢array。很高兴知道这样的方案是可行的。
只是,怎么样才能更快地将每一帧处理好的画面存到图像列表中呢?
我此前用readPixels太慢了。

该用户从未签到

发表于 2012-4-23 19:02:34 | 显示全部楼层
readPixels虽然比较慢,但是每帧只有一次的话,似乎也不是您能够感受出来的。我不知道您判断它影响效率的根据是什么

该用户从未签到

 楼主| 发表于 2012-4-24 10:09:09 | 显示全部楼层
本帖最后由 blue.high 于 2012-4-24 10:10 编辑
array 发表于 2012-4-23 19:02
readPixels虽然比较慢,但是每帧只有一次的话,似乎也不是您能够感受出来的。我不知道您判断它影响效率的根 ...


谢谢。我的工程,当前处理每一帧所花的时间大概10~12毫秒。所要求的帧率是60帧/秒,即每帧16.7毫秒。也就是说当前处理一帧所用的时间还有5~7毫秒的盈余。所以我想把每一帧的画面保存后,不必等待显示(因为显卡打开了垂直同步,所以要等屏幕刷新时间点),让处理线程接着处理下一帧,充分利用5~7毫秒的盈余。
但程序稍做修改,只是加一个WindowCaptureCallback,用readPixels读出数据,每帧所花的时间就长了6毫秒左右,使得一帧处理时间经常超过16.7毫秒,这样原来的设计方案就没意义了。

RTT到一个纹理之后,显示出来是正常的,但这个纹理好象没有Image,想把这个纹理拷贝到另一个纹理,能实现吗?我用了下面的方法:
new osg::Texture2D(*texture2D, osg::CopyOp::DEEP_COPY_ALL);
或者 texture2D->clone(osg::CopyOp::DEEP_COPY_ALL)
都能得到非空的指针tex,但如下设置后根本没图像出来,
node->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex,osg::StateAttribute::ON);
不知哪里出错了?
注:这样设置是能显示的。node->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture2D,osg::StateAttribute::ON);

换个说法,不做shader编程,想在显存中的两个纹理对象间进行数据拷贝,能实现吗?
我看到有人在其他论坛说用DirectX是能实现的。

该用户从未签到

发表于 2012-5-4 10:42:36 | 显示全部楼层
copySubTexture到纹理也只是在显存空间,要进入CPU空间还得readPixel;您也许可以考虑FBO的方案,它能够直接把显存映射到一处内存区域,然后直接取用
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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