最近也是因爲項目需求,需要在Centos7.2系統下用Qt5.0(現在最新版本已經到達Qt5.10.1),然後進行二三維場景的開發。對一個Linux系統和Qt的小白來講,這是一件很痛苦的事,網上在Linux系統下用Qt的資源太少了,後來靜下來通過讀取網上的示例代碼,最後有了一點點效果,現在先來寫個總結,以後用着也方便。
一、數據獲取
先給那個Qt的下載鏈接:http://download.qt.io/archive/qt/
OSG下載鏈接:https://pan.baidu.com/s/1WqN9tjdSpiIJnwIUlxS3wQ 密碼:i9nv
二、Linux系統下OSG編譯及環境變量配置
OSG下載好以後需要對其進行編譯。在Windows系統下使用編譯比較簡單,直接用CMake就行,網上教程很多,之前也編譯過,現在主要給出Centos7.2系統下的編譯,先安裝CMake,然後從命令窗口直接進入到OpenSceneGraph下:
cd OpenSceneGraph
./configure
make
sudo make install
接着環境變量配置:
# vim ~/.bashrc
在打開的文件最後添加如下內容,具體地址要根據你的osg放置的地方和osg數據放置的位置來確定
export PATH = “${PATH}:/home/vge/OSG/OpenSceneGraph-3.0.1/bin”
export LD_LIBRARY_PATH = “${LD_LIBRARY_PATH}:/home/vge/OSG/OpenSceneGraph-3.0.1/lib”
export OSG_FILE_PATH = “/home/vge/OSG/OpenSceneGraph-Data-3.0.0:/home/vge/OSG/OpenSceneGraph-Data-3.0.0/Images”
檢驗OSG是否可以在Linux系統下正常使用
cd /home/vge/OSG/OpenSceneGraph-3.0.1/bin
./osgviewer /home/vge/OSG/OpenSceneGraph-Data-3.0.0/cow.osg
此時就行出現OSG中提供的3D模型了
三、在Qt5.0中嵌入OSG
在進行這部分操作的時候最後對OpenGL或者OSG有一定的熟悉,不然很難調出一個最簡單的代碼,網上給的示例中,代碼比較多,在初調試階段有些完全用不上。
(1) 新建工程這塊選擇基類爲QWidget
(2) 在.pro文件中加上
QT +=opengl
(3) 右擊項目,通過“添加庫->外部庫”將需要用到的OSG模塊引入到項目中,
(4) 然後就可以寫代碼了
【AdapterWidget.h】將原來繼承的QWIDget改爲QGLWidget
【AdapterWidget.h】
#ifndef ADAPTERWIDGET_H
#define ADAPTERWIDGET_H
#include <QWidget>
#include <QtOpenGL/QGLWidget>
#include <QApplication>
#include <osgViewer/Viewer>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>
#include <QtCore/QString>
#include <QtCore/QTimer>
#include <QtGui/QKeyEvent>
#include <QtOpenGL/QGLWidget>
#include <QMainWindow>
#include <QMdiSubWindow>
#include <QMdiArea>
#include <iostream>
using Qt::WindowFlags;
class AdapterWidget : public QGLWidget
{
Q_OBJECT
public:
AdapterWidget(QWidget *parent = 0);
// AdapterWidget(QWidget *parent = 0,const char*name=0,const QGLWidget*shareWidget=0,Qt::WindowFlags f=0 );
~AdapterWidget();
osgViewer::GraphicsWindow* getGraphicsWindow()
{
return _gw.get();
}
const osgViewer::GraphicsWindow* getGraphicsWindow() const
{
return _gw.get();
}
protected:
void initializeGL();
virtual void resizeGL(int width,int height);
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
};
#endif // ADAPTERWIDGET_H
【adapterwidget.cpp】
#include "adapterwidget.h"
AdapterWidget::AdapterWidget(QWidget *parent)
: QGLWidget(parent)
{
_gw=new osgViewer::GraphicsWindowEmbedded(0,0,width(),height());
setFocusPolicy(Qt::ClickFocus);
}
AdapterWidget::~AdapterWidget()
{
}
void AdapterWidget::initializeGL()
{
}
void AdapterWidget::resizeGL(int width, int height)
{
_gw->getEventQueue()->windowResize(0,0,width,height);
_gw->resized(0,0,width,height);
}
//AdapterWidget::AdapterWidget(QWidget *parent, const char *name, const QGLWidget *shareWidget, Qt::WindowFlags f)
//{
//}
然後在新建一個類ViewerQt繼承前面的AdapterWidget用來控制視角,鼠標鍵盤交互操作等,這裏沒有寫交互功能的代碼
【ViewerQt.h】
#ifndef VIEWERQT_H
#define VIEWERQT_H
#include "adapterwidget.h"
#include <osgViewer/Viewer>
class ViewerQT:public osgViewer::Viewer,public AdapterWidget
{
public:
// ViewerQT();
ViewerQT(QWidget *parent = 0);
virtual void paintGL()
{
frame();
}
protected:
QTimer _timer;
};
#endif // VIEWERQT_H
【ViewerQt.cpp】
#include "viewerqt.h"
//ViewerQT::ViewerQT()
//{
//}
ViewerQT::ViewerQT(QWidget *parent):AdapterWidget(parent)
{
getCamera()->setViewport(new osg::Viewport(0,0,width(),height()));
getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(width())/static_cast<double>(height()), 1.0f, 10000.0f);
getCamera()->setGraphicsContext(getGraphicsWindow());
setThreadingModel(osgViewer::Viewer::SingleThreaded);
connect(&_timer,SIGNAL(timeout()),this,SLOT(updateGL()));//並且把它的timeout()連接到適當的槽。當這段時間過去了,它將會發射timeout()信號。
_timer.start(10);//使用start()來開始
}
接着就是在main函數中創建一個窗口,並獲取一個OSG提供的3D模型在窗口中顯示出來,這塊需要提前將數據放在工程的根目錄下。
【main.cpp】
#include "adapterwidget.h"
#include <QApplication>
#include "viewerqt.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
osg::ref_ptr<osg::Node> loadedModel=osgDB::readNodeFile("cow.osg");
ViewerQT * ViewerWindow=new ViewerQT;
ViewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
ViewerWindow->setSceneData(loadedModel.get());
QMainWindow* mw=new QMainWindow();
mw->showMaximized();
mw->setCentralWidget(ViewerWindow);
mw->show();
a.connect(&a,SIGNAL(lastWindowClosed()),&a,SLOT(quit()));
// AdapterWidget w;
// w.show();
return a.exec();
}
最後運行即可得到效果,
此刻大功告成,已經在Qt5.0中成功嵌入了OSG,後面就可以根據需要加載自己的三維場景進行自己的三維開發了!!!