查看: 2411|回复: 5

不能显示从osg文件中读取的Node可能是什么原因?

[复制链接]

该用户从未签到

发表于 2009-3-12 16:58:32 | 显示全部楼层 |阅读模式
平台:OSG2.8+MinGW+Qt +Windows2008

症状:
1.使用控制台程序用osgDB::readNodeFile("lz.osg") 可以显示数据
2.Qt和OSG结合的代码,如果Node是用代码构建的 可以显示
  如果Node是通过osgDB::readNodeFile读出来的 系统崩溃

代码如下:
1.控制台程序的代码:
  1. #include <iostream>
  2. #include <osg/Node>
  3. #include <osgViewer/Viewer>
  4. #include <osgDB/ReadFile>
  5. using namespace std;
  6. using namespace osg;
  7. using namespace osgViewer;
  8. int main() {
  9.         Viewer viewer;
  10.         Node* node=osgDB::readNodeFile(string("lz.osg"));
  11.         viewer.setSceneData(node);
  12.         viewer.realize();
  13.     viewer.run();
  14.         return 0;

  15. }
复制代码
2.和Qt结合代码 SceneCanvas.h
  1. #ifndef QSCENECANVAS_H
  2. #define QSCENECANVAS_H
  3. #include <osg/ref_ptr>
  4. #include <osgViewer/Viewer>
  5. #include <osgViewer/CompositeViewer>
  6. #include <osgViewer/ViewerEventHandlers>
  7. #include <osgGA/TrackballManipulator>
  8. #include <osgDB/ReadFile>

  9. #include <QtGui/QWidget>
  10. #include <QtCore/QString>
  11. #include <QtCore/QTimer>
  12. #include <QtGui/QKeyEvent>
  13. #include <QtGui/QApplication>
  14. #include <QtOpenGL/QGLWidget>
  15. #include <QtGui/QMainWindow>
  16. #include <QtGui/QMdiSubWindow>
  17. #include <QtGui/QMdiArea>

  18. using Qt::WindowFlags;
  19. #include "ui_QSceneCanvas.h"
  20. using namespace osg;
  21. using namespace osgViewer;
  22. using namespace osgGA;
  23. class QSceneCanvas: public QGLWidget, public osgViewer::Viewer {
  24. Q_OBJECT

  25. public:
  26.         QSceneCanvas(QWidget *parent = 0);
  27.         ~QSceneCanvas();

  28.         GraphicsWindowEmbedded* getGraphicsWindow() {
  29.                 return _gw.get();
  30.         }
  31.         const GraphicsWindowEmbedded* getGraphicsWindow() const {
  32.                 return _gw.get();
  33.         }

  34. public:
  35.         virtual void paintGL();
  36. protected:
  37.         //void init();
  38.         virtual void resizeGL(int width, int height);
  39.         virtual void keyPressEvent(QKeyEvent* event);
  40.         virtual void keyReleaseEvent(QKeyEvent* event);
  41.         virtual void mousePressEvent(QMouseEvent* event);
  42.         virtual void mouseReleaseEvent(QMouseEvent* event);
  43.         virtual void mouseMoveEvent(QMouseEvent* event);
  44.         ref_ptr<GraphicsWindowEmbedded> _gw;
  45. private:
  46.         QTimer _timer;
  47.         GUIEventAdapter::KeySymbol getSceneKeyCode(const QKeyEvent& event);
  48. private:
  49.         Ui::QSceneCanvasClass ui;
  50. };

  51. #endif // QSCENECANVAS_H
复制代码
3.和Qt结合的代码 SceneCanvas.cpp
  1. #include "QSceneCanvas.h"

  2. QSceneCanvas::QSceneCanvas(QWidget *parent) :
  3.         QGLWidget(parent) {
  4.         ui.setupUi(this);

  5.         _gw = new GraphicsWindowEmbedded(0, 0, width(), height());
  6.         getCamera()->setGraphicsContext(_gw);

  7.         getCamera()->setProjectionMatrixAsPerspective(45.0f,
  8.                         static_cast<double> (width()) / static_cast<double> (height()),
  9.                         1.0, 1000.0);
  10.         getCamera()->setViewport(new osg::Viewport(0, 0, width(), height()));
  11.         setCameraManipulator(new osgGA::TrackballManipulator);
  12.         setThreadingModel(osgViewer::Viewer::SingleThreaded);
  13.         setFocusPolicy(Qt::ClickFocus);
  14. }

  15. QSceneCanvas::~QSceneCanvas() {

  16. }

  17. void QSceneCanvas::paintGL() {
  18.         frame();
  19. }
  20. void QSceneCanvas::resizeGL(int width, int height) {
  21.         _gw->getEventQueue()->windowResize(0, 0, width, height);
  22.         _gw->resized(0, 0, width, height);
  23. }
  24. void QSceneCanvas::keyPressEvent(QKeyEvent* event) {

  25.         _gw->getEventQueue()->keyPress(getSceneKeyCode(*event));
  26. }
  27. void QSceneCanvas::keyReleaseEvent(QKeyEvent* event) {
  28.         _gw->getEventQueue()->keyRelease(getSceneKeyCode(*event));
  29. }
  30. void QSceneCanvas::mousePressEvent(QMouseEvent* event) {
  31.         int button = 0;
  32.         switch (event->button()) {
  33.         case (Qt::LeftButton):
  34.                 button = 1;
  35.                 break;
  36.         case (Qt::MidButton):
  37.                 button = 2;
  38.                 break;
  39.         case (Qt::RightButton):
  40.                 button = 3;
  41.                 break;
  42.         case (Qt::NoButton):
  43.                 button = 0;
  44.                 break;
  45.         default:
  46.                 button = 0;
  47.                 break;
  48.         }
  49.         _gw->getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
  50. }
  51. void QSceneCanvas::mouseReleaseEvent(QMouseEvent* event) {
  52.         int button = 0;
  53.         switch (event->button()) {
  54.         case (Qt::LeftButton):
  55.                 button = 1;
  56.                 break;
  57.         case (Qt::MidButton):
  58.                 button = 2;
  59.                 break;
  60.         case (Qt::RightButton):
  61.                 button = 3;
  62.                 break;
  63.         case (Qt::NoButton):
  64.                 button = 0;
  65.                 break;
  66.         default:
  67.                 button = 0;
  68.                 break;
  69.         }
  70.         _gw->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
  71. }
  72. void QSceneCanvas::mouseMoveEvent(QMouseEvent* event) {
  73.         _gw->getEventQueue()->mouseMotion(event->x(), event->y());
  74. }
  75. GUIEventAdapter::KeySymbol QSceneCanvas::getSceneKeyCode(const QKeyEvent& event) {
  76.         return (GUIEventAdapter::KeySymbol) *(event.text().toAscii().data());
  77. }
复制代码
4.我是如何使用的:
  1. void QMainFrame::onLoadData(){
  2.   QFileDialog fd(this);
  3.   fd.setFilter(QString::fromUtf8("osg File(*.osg)"));
  4.   if(fd.exec()==QDialog::Accepted)
  5.   {
  6.           QString file=fd.selectedFiles().at(0);

  7.           Node* dataNode=osgDB::readNodeFile(string("lz.osg"));
  8.           //SceneNodeFactory fact;
  9.           //Node* dataNode=fact.createSceneNode();
  10.           _masterCanvas.setSceneData(dataNode);
  11.   }
  12. }
复制代码
本来是要根据选择的文件读取的 我在这里直接写死了。
_masterCanvas就是SceneCanvas的一个对象,是顶层窗口的成员。
如果dataNode使用从文件读取的 程序直接就崩溃了 如果是用createSceneNode函数构造的 是可以运行
createSceneNode的内容是一本交做osgTutorial.chm的书上的第一个例子.

感觉有点郁闷了...
另外:自带的osgViewerQt好像也不能读取文件


高手们都出来救救我吧!
这里是我的整个工程
QGIS.zip (212.66 KB, 下载次数: 146)

该用户从未签到

 楼主| 发表于 2009-3-12 17:18:53 | 显示全部楼层
DEBUG_INFO 级别下的输出 :
Opened DynamicLibrary osgPlugins-2.8.0/mingw_osgdb_osg.dll
FindFileInPath(C:\MinGW\OpenSceneGraph-Data\lz.osg): returning C:\MinGW\OpenSceneGraph-Data\lz.osg

可以看到找到文件了

该用户从未签到

发表于 2009-3-12 19:35:35 | 显示全部楼层
经过测试,您的代码在VS2008,OpenSceneGraph 2.9.0,Qt-4.4.0环境下可以正常运行并加载模型;您也许需要检查mingw的osg库是否编译正确。部分功能可用并不代表链接库的其他功能全都正确

该用户从未签到

 楼主| 发表于 2009-3-17 16:30:32 | 显示全部楼层
同样的代码 在WinXP下可以用 在Win2008不能用。
Osg和Qt都是用一份 双系统都是引用的同一份。

看起来和OS有关系 不过也不一定... 水平太菜

该用户从未签到

发表于 2009-3-17 16:34:19 | 显示全部楼层
Win2008是什么……Vista?Windows7?
这样的话,必须在那个系统上重新编译OSG和Qt,否则它们必定不可能正常运行。

该用户从未签到

 楼主| 发表于 2009-3-17 16:44:19 | 显示全部楼层
Windows Server 2008
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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