VS下OSG嵌入QT指定視窗
-
- 1.編譯osgqt
- 2.osg中繪制視窗
- 3.osg嵌入qt指定視窗
-
- 1.建立QT工程
- 2.添加QT視窗部件
- 3.osg嵌入QT
1.編譯osgqt
忘記了,自己搜一下吧。記得當時是又改了cmake編譯的。之前的源碼沒有osgqt工程。
osgQT工程和osgqt庫下載下傳連結,osgqt庫為VS2013 x86 環境下編譯。
https://download.csdn.net/download/lemon_haha/12043250
2.osg中繪制視窗
在osg中用qt繪制視窗,即qt嵌入osg。
在osg源碼當中有案例Examples osgviewerQt
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL3kDNwMDMycTM5EjMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
直接複制過來運作即可,代碼:
#include <QTimer>
#include <QApplication>
#include <QGridLayout>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/MultiTouchTrackballManipulator>
#include <osgDB/ReadFile>
#include <osgQt/GraphicsWindowQt>
#include <iostream>
class ViewerWidget : public QWidget, public osgViewer::CompositeViewer
{
public:
ViewerWidget(QWidget* parent = 0, Qt::WindowFlags f = 0, osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::CompositeViewer::SingleThreaded) : QWidget(parent, f)
{
setThreadingModel(threadingModel);
// disable the default setting of viewer.done() by pressing Escape.
setKeyEventSetsDone(0);
QWidget* widget1 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readNodeFile("cow.osg"));
QWidget* widget2 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readNodeFile("glider.osg"));
QWidget* widget3 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readNodeFile("axes.osgt"));
QWidget* widget4 = addViewWidget(createGraphicsWindow(0, 0, 100, 100), osgDB::readNodeFile("fountain.osgt"));
QWidget* popupWidget = addViewWidget(createGraphicsWindow(900, 100, 320, 240, "Popup window", true), osgDB::readNodeFile("dumptruck.osgt"));
popupWidget->show();
QGridLayout* grid = new QGridLayout;
grid->addWidget(widget1, 0, 0);
grid->addWidget(widget2, 0, 1);
grid->addWidget(widget3, 1, 0);
grid->addWidget(widget4, 1, 1);
setLayout(grid);
connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
_timer.start(10);
}
QWidget* addViewWidget(osgQt::GraphicsWindowQt* gw, osg::Node* scene)
{
osgViewer::View* view = new osgViewer::View;
addView(view);
osg::Camera* camera = view->getCamera();
camera->setGraphicsContext(gw);
const osg::GraphicsContext::Traits* traits = gw->getTraits();
camera->setClearColor(osg::Vec4(0.2, 0.2, 0.6, 1.0));
camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
camera->setProjectionMatrixAsPerspective(30.0f, static_cast<double>(traits->width) / static_cast<double>(traits->height), 1.0f, 10000.0f);
view->setSceneData(scene);
view->addEventHandler(new osgViewer::StatsHandler);
view->setCameraManipulator(new osgGA::MultiTouchTrackballManipulator);
gw->setTouchEventsEnabled(true);
return gw->getGLWidget();
}
osgQt::GraphicsWindowQt* createGraphicsWindow(int x, int y, int w, int h, const std::string& name = "", bool windowDecoration = false)
{
osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->windowName = name;
traits->windowDecoration = windowDecoration;
traits->x = x;
traits->y = y;
traits->width = w;
traits->height = h;
traits->doubleBuffer = true;
traits->alpha = ds->getMinimumNumAlphaBits();
traits->stencil = ds->getMinimumNumStencilBits();
traits->sampleBuffers = ds->getMultiSamples();
traits->samples = ds->getNumMultiSamples();
return new osgQt::GraphicsWindowQt(traits.get());
}
virtual void paintEvent(QPaintEvent* event)
{
frame();
}
protected:
QTimer _timer;
};
int main(int argc, char** argv)
{
osg::ArgumentParser arguments(&argc, argv);
#if QT_VERSION >= 0x050000
// Qt5 is currently crashing and reporting "Cannot make QOpenGLContext current in a different thread" when the viewer is run multi-threaded, this is regression from Qt4
osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::SingleThreaded;
#else
osgViewer::ViewerBase::ThreadingModel threadingModel = osgViewer::ViewerBase::CullDrawThreadPerContext;
#endif
while (arguments.read("--SingleThreaded")) threadingModel = osgViewer::ViewerBase::SingleThreaded;
while (arguments.read("--CullDrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::CullDrawThreadPerContext;
while (arguments.read("--DrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::DrawThreadPerContext;
while (arguments.read("--CullThreadPerCameraDrawThreadPerContext")) threadingModel = osgViewer::ViewerBase::CullThreadPerCameraDrawThreadPerContext;
#if QT_VERSION >= 0x040800
// Required for multithreaded QGLWidget on Linux/X11, see http://blog.qt.io/blog/2011/06/03/threaded-opengl-in-4-8/
if (threadingModel != osgViewer::ViewerBase::SingleThreaded)
QApplication::setAttribute(Qt::AA_X11InitThreads);
#endif
QApplication app(argc, argv);
ViewerWidget* viewWidget = new ViewerWidget(0, Qt::Widget, threadingModel);
viewWidget->setGeometry( 100, 100, 800, 600 );
viewWidget->show();
return app.exec();
}
運作結果:
3.osg嵌入qt指定視窗
第二部分的代碼用osgQt::GraphicWindowQt 建構視窗,我們檢視其定義,發現可以用GLWidget直接初始化GraphicWindowQt。
是以osg嵌入qt的原理是GLWidget為連接配接,用在qt中建立的視窗初始化viewer視窗的大小。
1.建立QT工程
2.添加QT視窗部件
輕按兩下ui打開qt designer從左側拖動listwidget視窗到主界面:
3.osg嵌入QT
參考連結:https://www.cnblogs.com/ningmouming/p/9010164.html
在頭檔案osgQT中将ui聲明由private改為public
主函數當中寫:
#include "osgqt.h"
#include <QtWidgets/QApplication>
#include <osgQt/GraphicsWindowQt>
#include <QGridLayout>
#include <osgDB/ReadFile>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/Viewer>
#include <QGLWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
osgQT *w = new osgQT;
//============================================此處添加場景=======================================
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr<osg::Group> root = new osg::Group;
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
root->addChild(node);
viewer->setSceneData(root.get());
viewer->setCameraManipulator(new osgGA::TrackballManipulator);
viewer->addEventHandler(new osgViewer::StatsHandler);
//--------------------------------------------此處添加場景----------------------------------------||
//用GLWidget初始化viewer顯示視窗
osgQt::setViewer(viewer.get());
osgQt::GLWidget *glw = new osgQt::GLWidget;
osgQt::GraphicsWindowQt * graphicswin = new osgQt::GraphicsWindowQt(glw);
graphicswin->setCursor(osgQt::GraphicsWindowQt::MouseCursor::HandCursor); //設定滑鼠樣式
viewer->getCamera()->setViewport(new osg::Viewport(0, 0, glw->width(), glw->height()));
viewer->getCamera()->setGraphicsContext(graphicswin);
viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
//挂接到qt的指定視窗下
QGridLayout *grid = new QGridLayout;
grid->addWidget(glw);
grid->setSpacing(0);
grid->setContentsMargins(0, 0, 0, 0);
w->ui.listWidget->setLayout(grid);//要挂接的視窗
w->show();
return a.exec();
}
運作結果