查看: 2320|回复: 8

如何让osg::Texture仅仅作为RTT的结果输出?

[复制链接]

该用户从未签到

发表于 2009-7-17 09:09:28 | 显示全部楼层 |阅读模式
有个2D的Texture需要动态创建,但是并不是每一帧都需要改变其内容。
在没有指令让它改变的情况下,可以一直保持之前的内容。

所以并不想将Camera加入Group节点,想在需要改变内容的时候,将新建的Texture传入某函数,使用RTT进行指定渲染,然后将texture返回,请问这样的函数该怎么实现?

(试过在局部创建Viewer,camera渲染传入的Texture,结果屏幕闪的厉害,渲染结果也不对~~)

该用户从未签到

发表于 2009-7-17 20:39:59 | 显示全部楼层
可以参考OverlayNode的做法,在traverse()函数中执行camera->apply(),不过千万注意维护好状态堆栈。如果不熟悉OSG内部实现机制,可以先看看《最长的一帧》以及源代码

该用户从未签到

 楼主| 发表于 2009-7-21 18:54:54 | 显示全部楼层
camera->apply()??
我就是想让相机在当前的函数范围内“按下快门”,将当前的场景留到Texture上。OverlayNode可能没有研究透彻,还是有点疑问。
这是我原来的函数(闪,应该是viewer的原因,却为什么连结果都不对??)。
  1. void RenderToTexture(osg::Texture2D *texture2D, osg::Node *subGraph)
  2. {

  3.         osg::Camera* camera = new osg::Camera;

  4.         camera->setClearColor(osg::Vec4(0.0f,0.0f,0.0f,0.0f));
  5.         camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  6.         osg::BoundingBox box = subGraph->getBound();

  7.         camera->setProjectionMatrixAsOrtho(box.xMin(), box.xMax(), box.yMin(), box.yMax(), 0.5, 0.0);

  8.         camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
  9.         camera->setViewMatrixAsLookAt(osg::Vec3(_centerX, _centerY, 1.0f),osg::Vec3(_centerX, _centerY, -1.0f),osg::Vec3(0.0f,1.0f,0.0f));

  10.         camera->setViewport(0,0,256,256);

  11.         camera->setRenderOrder(osg::Camera::PRE_RENDER);

  12.         // tell the camera to use OpenGL frame buffer object where supported.
  13.         camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);

  14.         camera->attach(osg::Camera::COLOR_BUFFER, texture2D);

  15.         camera->addChild(subGraph);


  16.         //预想运行一帧来获得渲染后的Texture。
  17.         osgViewer::Viewer* viewer = new osgViewer::Viewer();

  18.         osg::Group* root = new osg::Group();

  19.         root->addChild(camera);

  20.         osgUtil::Optimizer optimizer ;
  21.         optimizer.optimize(root) ;

  22.         viewer->setSceneData(root);

  23.         viewer->realize();

  24.         if (!viewer->getCameraManipulator() && viewer->getCamera()->getAllowEventFocus())
  25.         {
  26.                 viewer->setCameraManipulator(new osgGA::TrackballManipulator());
  27.         }

  28.         viewer->setReleaseContextAtEndOfFrameHint(false);

  29.         if (!viewer->done())
  30.         {
  31.                 viewer->frame();

  32.                 viewer->frame();
  33.         }

  34.         viewer->setDone(true);

  35.         camera->detach(osg::Camera::COLOR_BUFFER);

  36.         delete viewer;
  37. }
复制代码

该用户从未签到

发表于 2009-7-22 08:40:48 | 显示全部楼层
您的做法,我不知道texture属性设置的是否正确,代码中无体现;还有如果此时有仿真循环在运行的话,那么再次执行frame()无疑是一种疯狂的行为。
我说的做法是可以在仿真循环运行过程中实现的,不过要自己派生一个新的节点,在重构的traverse()函数中完成这些操作

该用户从未签到

 楼主| 发表于 2009-7-22 09:07:47 | 显示全部楼层
Texture应该没什么问题,新的~
  1. osg::Texture2D* texture2D = new osg::Texture2D;
  2. texture2D->setTextureSize(256, 256);
  3. texture2D->setInternalFormat(GL_RGBA);
  4. texture2D->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
  5. texture2D->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
复制代码
还是再继续学习OverlayNode吧。
还有,camera好像没有apply()这个成员函数啊。不知道您说的camera->apply()是什么意思?

该用户从未签到

发表于 2009-7-22 10:01:59 | 显示全部楼层
基本代码应该差不多了,这样至少能把图像渲染出来。不过注意渲染到Texture是得不到getImage对象的,因为数据不是保存在用户内存中

我的意思是camera->accept(*cv),笔误而已
不过还需要把传入CullVisitor的数据入栈出栈,不然肯定会崩溃

该用户从未签到

 楼主| 发表于 2009-7-22 13:25:01 | 显示全部楼层
好像能理解您的意思。
我在做这个的时候有其他的仿真循环再进行
我的意思是将Texture,subGraph传入一个独立的函数。函数结束的时候就已经渲染了Texture。
如果类似Overlay的写法创建一个节点,在这个函数中怎么才能使得运行到这个节点的traverse呢?

该用户从未签到

发表于 2009-7-22 13:42:22 | 显示全部楼层
节点的traverse总是由访问器调用的!而系统内部的裁减访问器CullVisitor必定会每帧运行各个节点的traverse()函数。因此我们只需要派生一个新的节点,重构traverse()函数的内容,那它必然会被每帧执行。这也是OSG中进行节点功能扩展的最正确方法

您说的写个函数,一开始就渲染,结束就完成的做法,我个人认为很难实现,因为OSG的系统结构上不允许。除了重写功能节点之外(譬如我就自己写了一个OverlayCamera类),用Camera:: PreDrawCallback也是可行的,不过要控制准确才可以。

该用户从未签到

 楼主| 发表于 2009-7-22 14:44:13 | 显示全部楼层
这么快就回复啦~

因为之前类似于只想得到一张有内容的Texture,内容也不需要变,所以异想天开的想这么实现。
看了OverlayNode以及OSG一向的做法,慢慢也感觉这种方法的不可取,现在很认同您说的这个说法--“OSG中进行节点功能扩展的最正确方法”。
目前学习了OverlayNode的实现方法,功能也已经实现,非常感谢,非常感谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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