OSG+QGIS在QT Creator下環境配置
本週在一位大佬的指引下,成功將OSG和QGIS的環境從VS遷移到QT creator下,其中主要是pro檔案中include路徑和lib的包含以及lib檔案的載入。
其中主要的配置程式碼如下:
QGIS_RootDir = $$PWD/.. QGIS_3rdParty = $${QGIS_RootDir}/3rdParty INCLUDEPATH += $${QGIS_3rdParty} INCLUDEPATH += $${QGIS_3rdParty}/qgis289vs2010/include QGISLibPath = $${QGIS_3rdParty}/qgis289vs2010/lib Osg_RootDir = $$PWD/.. Osg_3rdParty = $${Osg_RootDir}/3rdParty INCLUDEPATH += $${Osg_3rdParty} INCLUDEPATH += $${Osg_3rdParty}/osg-3.4.0/include OsgLibPath = $${Osg_3rdParty}/osg-3.4.0/lib CONFIG(debug, debug|release){ BIN_DIR = $${QGIS_RootDir}/BinD LIBS += $${QGISLibPath}/qgis_core.lib LIBS += $${QGISLibPath}/qgis_gui.lib LIBS += $${QGISLibPath}/qgis_analysis.lib LIBS += $${OsgLibPath}/osgViewerd.lib LIBS += $${OsgLibPath}/osgDBd.lib LIBS += $${OsgLibPath}/OpenThreadsd.lib LIBS += $${OsgLibPath}/osgd.lib LIBS += $${OsgLibPath}/osgManipulatord.lib LIBS += $${OsgLibPath}/osgTextd.lib LIBS += $${OsgLibPath}/osgGAd.lib LIBS += $${OsgLibPath}/osgUtild.lib LIBS += $${OsgLibPath}/osgUId.lib LIBS += $${OsgLibPath}/osgQTd.lib } else{ BIN_DIR = $${QGIS_RootDir}/Bin LIBS += $${QGISLibPath}/qgis_core.lib LIBS += $${QGISLibPath}/qgis_gui.lib LIBS += $${QGISLibPath}/qgis_analysis.lib LIBS += $${OsgLibPath}/osgViewer.lib LIBS += $${OsgLibPath}/osgDB.lib LIBS += $${OsgLibPath}/OpenThreads.lib LIBS += $${OsgLibPath}/osg.lib LIBS += $${OsgLibPath}/osgManipulator.lib LIBS += $${OsgLibPath}/osgText.lib LIBS += $${OsgLibPath}/osgGA.lib LIBS += $${OsgLibPath}/osgUtil.lib LIBS += $${OsgLibPath}/osgUI.lib LIBS += $${OsgLibPath}/osgQT.lib } DESTDIR = $${BIN_DIR} unix{ DEFINES += CORE_EXPORT= DEFINES += GUI_EXPORT= DEFINES += ANALYSIS_EXPORT= } !unix{ DEFINES += CORE_EXPORT=__declspec(dllimport) DEFINES += GUI_EXPORT=__declspec(dllimport) DEFINES += ANALYSIS_EXPORT=__declspec(dllimport) }
其中
QGIS_RootDir=$$PWD/..
Osg_RootDir=$$PWD/..
是設定qgis和osg的根目錄為此專案的上級目錄,我的qgis和osg的庫檔案都放在這個根目錄的3rdParty下
QGIS_3rdParty = $${QGIS_RootDir}/3rdParty INCLUDEPATH += $${QGIS_3rdParty} INCLUDEPATH += $${QGIS_3rdParty}/qgis289vs2010/include QGISLibPath = $${QGIS_3rdParty}/qgis289vs2010/lib Osg_3rdParty = $${Osg_RootDir}/3rdParty INCLUDEPATH += $${Osg_3rdParty} INCLUDEPATH += $${Osg_3rdParty}/osg-3.4.0/include OsgLibPath = $${Osg_3rdParty}/osg-3.4.0/lib
以上這些程式碼是設定開發庫的標頭檔案和lib檔案目錄。
CONFIG(debug, debug|release){ BIN_DIR = $${QGIS_RootDir}/BinD LIBS += $${QGISLibPath}/qgis_core.lib LIBS += $${QGISLibPath}/qgis_gui.lib LIBS += $${QGISLibPath}/qgis_analysis.lib LIBS += $${OsgLibPath}/osgViewerd.lib LIBS += $${OsgLibPath}/osgDBd.lib LIBS += $${OsgLibPath}/OpenThreadsd.lib LIBS += $${OsgLibPath}/osgd.lib LIBS += $${OsgLibPath}/osgManipulatord.lib LIBS += $${OsgLibPath}/osgTextd.lib LIBS += $${OsgLibPath}/osgGAd.lib LIBS += $${OsgLibPath}/osgUtild.lib LIBS += $${OsgLibPath}/osgUId.lib LIBS += $${OsgLibPath}/osgQTd.lib } else{ BIN_DIR = $${QGIS_RootDir}/Bin LIBS += $${QGISLibPath}/qgis_core.lib LIBS += $${QGISLibPath}/qgis_gui.lib LIBS += $${QGISLibPath}/qgis_analysis.lib LIBS += $${OsgLibPath}/osgViewer.lib LIBS += $${OsgLibPath}/osgDB.lib LIBS += $${OsgLibPath}/OpenThreads.lib LIBS += $${OsgLibPath}/osg.lib LIBS += $${OsgLibPath}/osgManipulator.lib LIBS += $${OsgLibPath}/osgText.lib LIBS += $${OsgLibPath}/osgGA.lib LIBS += $${OsgLibPath}/osgUtil.lib LIBS += $${OsgLibPath}/osgUI.lib LIBS += $${OsgLibPath}/osgQT.lib } DESTDIR = $${BIN_DIR}
以上程式碼是依據QT的不同編譯模式(debug、release),debug模式下載入相應的debug版庫檔案,release模式下載入release版庫檔案,且將專案exe檔案生成到BIN_DIR目錄下,debug模式下生成到BinD目錄,release模式下生成到Bin目錄。
unix{
DEFINES += CORE_EXPORT=
DEFINES += GUI_EXPORT=
DEFINES += ANALYSIS_EXPORT=
}
!unix{
DEFINES += CORE_EXPORT=__declspec(dllimport)
DEFINES += GUI_EXPORT=__declspec(dllimport)
DEFINES += ANALYSIS_EXPORT=__declspec(dllimport)
}
以上程式碼為QGIS的預定義命令。
經過以上Pro檔案的定義,即可完成QT creator下的環境配置,注意應該新建一個構建套件(kits)設定編譯器版本為編譯qgis和osg原始碼的版本,qmake的版本要和編譯osg是使用的版本相同,否則構建將失敗。
本週又學習了一些osg和osgearth的知識,學會了使用osg構建地球模型,同時自己研究了將osg視口嵌入qt widget內的方法
構建兩個類通過繼承QGLWidget 和 osgViewer 從而實現osg視口在widget中的顯示:
class AdapterWidget:public QGLWidget
{
public:
AdapterWidget(QWidget *parent=0,const char* name=0,const QGLWidget * shareWidget=0,WindowFlags f=0);
virtual ~AdapterWidget()
{
}
osgViewer::GraphicsWindow* getGraphicsWindow()
{
return _gw.get();
}
const osgViewer::GraphicsWindow* getGraphicsWidow()const
{
return _gw.get();
}
protected:
void init();
virtual void resizeGL(int width,int height);
virtual void keyPressEvent(QKeyEvent* event);
virtual void keyReleaseEvent(QKeyEvent* event);
virtual void mousePressEvent(QMouseEvent* event);
virtual void mouseReleaseEvent(QMouseEvent* event);//
virtual void mouseMoveEvent(QMouseEvent* event);
virtual void wheelEvent(QWheelEvent* event);
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
};
class ViewerQT : public osgViewer::Viewer, public AdapterWidget
{
public:
ViewerQT(QWidget * parent=0,const char * name=0,const QGLWidget * shareWidget=0,WindowFlags f=0):AdapterWidget(parent ,name,shareWidget ,f)
{
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()來開始
}
virtual void paintGL()
{
frame();
}
protected:
QTimer _timer;
};
下面是osg中構建地球模型的程式碼,其中球半徑為WGS84橢球半徑:
osg::ref_ptr<osg::Group> root = new osg::Group;
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
hints->setDetailRatio(10);
osg::ref_ptr<osg::ShapeDrawable> sphere = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0,0,0),osg::WGS_84_RADIUS_POLAR),hints);
osg::ref_ptr<osg::Image> img1 = osgDB::readImageFile("land_shallow_topo_2048.jpg");
osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D;
tex->setImage(img1);
//邊界擷取方案-->忽略邊界-->消除裂縫(S、T、R對應X、Y、Z)
tex->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
tex->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
tex->setWrap(osg::Texture::WRAP_R,osg::Texture::CLAMP_TO_EDGE);
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
stateset->setTextureAttributeAndModes(0,tex,osg::StateAttribute::ON);
sphere->setStateSet(stateset);
geode->addDrawable(sphere);
osg::CoordinateSystemNode* csn = new osg::CoordinateSystemNode;
csn->setEllipsoidModel(new osg::EllipsoidModel());
csn->addChild(geode);
root->addChild(csn);
ViewerQT * ViewerWindow=new ViewerQT;
ViewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
ViewerWindow->setSceneData(root.get());
將osg地球模型和之前完成的qgis系統結合:
目前還存在的問題有:1、沒弄清qgis的標頭檔案中間接包含了windows.h就會報錯的解決方法,經確定為標頭檔案重新define了min和max,還在尋求解決方法。
待完成:將二三維視口的座標建立聯絡,實現兩個視口座標的聯動即二三維的聯動。