OSG中使用Qt做界面

最近使用OSG做三维引擎开发,在外层使用Qt做主框架,三维渲染使用OSG,但是在OSG中想快速写出UI设计师设计的界面有时就显得吃力,OSG提供了osgQt来支持Qt嵌入OSG,那么如果能在OSG中直接使用Qt做界面必定事半功倍,于是在网络一顿胡搜,结果令人沮丧,大多标题写着osg嵌入Qt却干着Qt嵌入OSG的事。于是想到OSG的例子,进去也是一顿乱搜,不知道是我没找到还是真没有,本人反正没有收到。于是在经过各种测试找到了一种方法,原来osgQt本身就支持,这个类叫:QWidgetImage.

本人使用Qt5.8测试。

下面是代码:

1.引入所需头文件

#include "osg/Texture2D"

#include "osg/Geometry"
#include "osg/CullStack"
#include "osg/AutoTransform"
#include "osg/MatrixTransform"
#include "osg/PositionAttitudeTransform"
#include "osgDB/ReadFile"
#include "osgGA/TrackballManipulator"
#include "osgViewer/ViewerEventHandlers"
#include "osgViewer/Viewer"
#include "osgQt/QWidgetImage"
#include 
#include 
#include 
#include 

2.创建一个Qt窗体

QWidget* createWidget( const QString& movieFile, const QString& title)

{
  QLabel* label = new QLabel;
  QPushButton* playBtn = new QPushButton("Play " + title );
  QPushButton* stopBtn = new QPushButton("Stop " + title );
  QWidget* demo = new QWidget;
  demo->setLayout( new QVBoxLayout );
  demo->layout()->addWidget( label );
  demo->layout()->addWidget( playBtn );
  demo->layout()->addWidget( stopBtn );
  demo->setStyleSheet("background-color:lightblue;");
  QMovie* movie = new QMovie(movieFile);
  label->setMovie( movie );
  label->setFixedHeight( 400 );
  QObject::connect( playBtn, SIGNAL(clicked()), movie, SLOT(start()) );
  QObject::connect( stopBtn, SIGNAL(clicked()), movie, SLOT(stop()) );
  return demo;
}
3. 创建一个osg节点

osg::Node* createNode(const osg::Vec3& position, const QString& title, const QString &backgroundImage)

{
  osg::ref_ptr<osgQt::QWidgetImage> widgetImage =
    new osgQt::QWidgetImage( createDemoWidget(backgroundImage, title) );

  osg::ref_ptr<osgViewer::InteractiveImageHandler> handler =
    new osgViewer::InteractiveImageHandler( widgetImage.get() );
  osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
  texture->setImage( widgetImage.get() );

  osg::ref_ptr<osg::Geometry> quad =
    osg::createTexturedQuadGeometry(osg::Vec3(),
                                    osg::Vec3(widgetImage->getQWidget()->width(),0,0),
                                    osg::Vec3(0,widgetImage->getQWidget()->height(),0));

  quad->setEventCallback( handler.get() );
  quad->setCullCallback( handler.get() );

  osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  geode->addDrawable(quad.get());
  geode->getOrCreateStateSet()->setTextureAttributeAndModes( 0, texture.get() );
  geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
  geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
  geode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

  osg::ref_ptr<osg::AutoTransform> autoNode = new osg::AutoTransform;
  autoNode->setAutoRotateMode(osg::AutoTransform::ROTATE_TO_SCREEN);
  autoNode->setAutoScaleToScreen(true);
  autoNode->addChild(geode.get());

  osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform;
  pat->setPosition(position);
  pat->addChild(geode.get());

  return pat.release();
}
4.将节点加入场景
int main( int argc, char** argv )
{
  QApplication app( argc, argv );
  osg::ref_ptr<osg::Group> root = new osg::Group;

  //root->addChild( createDemoNode(osg::Vec3(-1.0,0.0,0.0), "Widget 1", F:\\UrbanOMp\\resource\\image\\start_up_bk1.gif) );
  root->addChild( createDemoNode(osg::Vec3( 1.0,0.0,0.0), "Widget 2", F:\\UrbanOMp\\resource\\image\\start_up_bk1.gif) );

  osgViewer::Viewer viewer;
  viewer.setSceneData( root.get() );
  viewer.setCameraManipulator( new osgGA::TrackballManipulator );
  viewer.addEventHandler( new osgViewer::StatsHandler );

  while ( !viewer.done() )
  {
    QCoreApplication::processEvents( QEventLoop::AllEvents, 100 );
    viewer.frame();
  }
  return 0;
}
运行成功的在OSG中使用Qt,是不是太简单了。。。。。。。。。。。。。。。。。。。。。。。。。。


你可能感兴趣的:(C/C++,Qt;OSG;OSGEarth)