查看: 1566|回复: 2

“如何在已有的OPENGL代码中使用osgViewer显示一三维物体”中的问题

[复制链接]

该用户从未签到

发表于 2010-4-27 01:50:37 | 显示全部楼层 |阅读模式
  1. //第二种方法,学习第一种方法,并从osgviewerGLUT例子中蒙了一个函数setUpViewerAsEmbeddedInWindow();
  2. osg::ref_ptr< osgViewer::Viewer > osgviewer;
  3. osg:bserver_ptr<osgViewer::GraphicsWindow> osgwindow;
  4. void UserOSGInit(void)
  5. {
  6. // load the scene.
  7. osg::ref_ptr<osg::Group> root = new osg::Group;
  8. osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile("lz.osg");
  9. // create the view of the scene.
  10. if(false) //如果用户发现调入的模型不可见,可能是位置不对;本段可实现将模型摆在坐标原点附近
  11. {
  12. const osg::BoundingSphere &bbox = loadedModel->getBound();
  13. osg::ref_ptr<osg::MatrixTransform> mtf = new osg::MatrixTransform();
  14. osg::Matrix mtx;
  15. mtx.makeTranslate(-bbox.center());
  16. mtf->setMatrix(mtx);
  17. mtf->addChild(loadedModel.get());
  18. root->addChild(mtf.get());
  19. }
  20. else
  21. root->addChild(loadedModel.get());

  22. osgviewer = new osgViewer::Viewer();

  23. //----------------------------------------------------------------
  24. GLint viewParams[4];
  25. glGetIntegerv( GL_VIEWPORT, viewParams );
  26. osgwindow = osgviewer->setUpViewerAsEmbeddedInWindow(viewParams[0], viewParams[1], viewParams[2], viewParams[2]);
  27. // Set the Scene Data
  28. osgviewer->setSceneData(root.get());
  29. // Realize the Viewer
  30. osgviewer->realize();
  31. osgviewer->setLightingMode( osgViewer::Viewer::NO_LIGHT );
  32. //osgviewer->setLightingMode( osgViewer::Viewer::SKY_LIGHT );
  33. //osgviewer->setLightingMode( osgViewer::Viewer::HEADLIGHT );
  34. }
  35. void UserOSGUpdate(void)
  36. {
  37. //保存opengl状态----------------------------------------------------------------
  38. glPushAttrib( GL_ALL_ATTRIB_BITS );
  39. glMatrixMode( GL_PROJECTION );
  40. glPushMatrix();
  41. glMatrixMode( GL_TEXTURE );
  42. glPushMatrix();
  43. glMatrixMode( GL_MODELVIEW );
  44. glPushMatrix();
  45. glDisable(GL_LIGHTING);
  46. //从opengl照搬各种矩阵------------------------------------------------------------
  47. GLint viewParams[4];
  48. glGetIntegerv( GL_VIEWPORT, viewParams );
  49. osgviewer->getCamera()->setViewport( viewParams[0], viewParams[1], viewParams[2], viewParams[3]);
  50. GLfloat glMat[16];
  51. osg::Matrix osgMat;
  52. glGetFloatv( GL_PROJECTION_MATRIX, glMat);
  53. osgMat.set( glMat );
  54. osgviewer->getCamera()->getProjectionMatrix().set( osgMat );
  55. glGetFloatv( GL_MODELVIEW_MATRIX, glMat );
  56. osgMat.set( glMat );
  57. osgviewer->getCamera()->getViewMatrix().set( osgMat );
  58. //
  59. //调用单帧
  60. osgviewer->frame();
  61. //恢复opengl状态--------------------------------------------------------------
  62. glMatrixMode( GL_TEXTURE );
  63. glPopMatrix();
  64. glMatrixMode( GL_PROJECTION );
  65. glPopMatrix();
  66. glMatrixMode( GL_MODELVIEW );
  67. glPopMatrix();
  68. glPopAttrib();
  69. }
复制代码

这种方式下能用设置漫游器的方式来实现场景的移动吗?

该用户从未签到

发表于 2010-4-27 08:19:45 | 显示全部楼层
漫游器是Viewer内部使用的;如果您不使用Viewer来进行场景漫游的话,那么它不会被自动调用;并且osgGA库也无法检测到用户交互事件(PUSH,RELEASE等),只能自己写代码去控制。

该用户从未签到

发表于 2010-4-27 08:26:03 | 显示全部楼层
。。。。。。。。。。。。。。。。。。。。。。抱歉,,您的这种方式无法实现~~~引用一下官方FAQ:

Q 34: 可以在一个已有的渲染系统中使用OSG吗? &para;
A: 这有一定的难度,不过在一个已有的渲染系统中使用OSG是完全可能的。
首先,OSG的核心部件是osgUtil::SceneView。这个类负责管理OSG特有的渲染任务。如果你希望用到OSG的动画特性,那么还需要构建自己的FrameStamp对象。
这两个对象的设置如下所示:
unsigned int frameNumber = 0;
osg::Timer timer;
osg::Timer_t start_tick = timer.tick();
osg::ref_ptr<osgUtil::SceneView> sceneViewer = new osgUtil::SceneView();
osg::ref_ptr<osg::FrameStamp> frameStamp = new osg::FrameStamp();

sceneViewer->setDefaults();
sceneViewer->setComputeNearFarMode( osgUtil::CullVisitor:O_NOT_COMPUTE_NEAR_FAR );
sceneViewer->setSceneData( rootNode );
注意,这里需要把rootNode替换为实际的OSG模型节点。
注意,上面的代码调用了setComputeNearFarMode函数,这一点非常重要。否则的话,OSG可能会在渲染对象时使用不同的远/近平面,因而对象在深度缓存中的数值也可能与其它场景不同,因而产生一些古怪的错误。
如果你希望使用与渲染器其它部分不同的光照,在这里可以调用:
sceneViewer->setLightingMode( osgUtil::SceneView::SKY_LIGHT );
或者
sceneViewer->setLightingMode( osgUtil::SceneView::HEADLIGHT );
基本的设置过程就是这样。
现在我们需要调用SceneView以进行渲染,这还需要下面所述的一些工作。
第一,建议用户在OpenGL代码执行之前,对所有的模型观察矩阵(modelview),投影矩阵(projection)和纹理矩阵(texture)都调用glPushAttribs( GL_ALL_ATTRIB_BITS )和glPushMatrix,并在用户代码执行完毕之后调用相应的glPopAttribs和glPopMatrix函数,对OSG代码也作同样处理。这样可以避免OSG与其它OpenGL代码产生冲突,示例如下:
glPushAttrib( GL_ALL_ATTRIB_BITS );
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();

用户或者OSG的执行代码...

glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopAttrib();
此外,在使用SceneView时,用户需要将已有的视口、投影和模型观察矩阵传递给该对象。示例代码如下:
GLint viewParams[4];
glGetIntegerv( GL_VIEWPORT, viewParams );
sceneViewer->setViewport(viewParams[0], viewParams[1], viewParams[2], viewParams[3]);

GLfloat glMat[16];
osg::Matrix osgMat;

glGetFloatv( GL_PROJECTION_MATRIX, glMat );
osgMat.set( glMat );
sceneViewer->getProjectionMatrix().set( osgMat );

glGetFloatv( GL_MODELVIEW_MATRIX, glMat );
osgMat.set( glMat );
sceneViewer->getViewMatrix().set( osgMat );
下一步是更新FrameStamp对象(如果你使用自己编写的类):
double time_since_start = timer.delta_s( start_tick, timer.tick() );
frameStamp->setReferenceTime( time_since_start );
frameStamp->setFrameNumber( frameNumber++ );
sceneViewer->setFrameStamp( frameStamp.get() );
最后,你可以调用SceneView对象的方法了:
sceneViewer->update ();
sceneViewer->cull ();
sceneViewer->draw ();
如果上述的过程都正确,应当可以成功地在另外的渲染系统中使用OSG了,这样可以利用OSG的诸多优势,而不必担心出现系统之间的冲突
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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