最近使用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,是不是太简单了。。。。。。。。。。。。。。。。。。。。。。。。。。