天天看點

VS下OSG嵌入QT指定視窗

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

VS下OSG嵌入QT指定視窗

直接複制過來運作即可,代碼:

#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();
}

           

運作結果:

VS下OSG嵌入QT指定視窗

3.osg嵌入qt指定視窗

第二部分的代碼用osgQt::GraphicWindowQt 建構視窗,我們檢視其定義,發現可以用GLWidget直接初始化GraphicWindowQt。

VS下OSG嵌入QT指定視窗

是以osg嵌入qt的原理是GLWidget為連接配接,用在qt中建立的視窗初始化viewer視窗的大小。

VS下OSG嵌入QT指定視窗

1.建立QT工程

2.添加QT視窗部件

輕按兩下ui打開qt designer從左側拖動listwidget視窗到主界面:

VS下OSG嵌入QT指定視窗

3.osg嵌入QT

參考連結:https://www.cnblogs.com/ningmouming/p/9010164.html

在頭檔案osgQT中将ui聲明由private改為public

VS下OSG嵌入QT指定視窗

主函數當中寫:

#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();
}

           

運作結果

VS下OSG嵌入QT指定視窗

繼續閱讀