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
在这里插入图片描述
直接复制过来运行即可,代码:

#include 
#include 
#include 

#include 
#include 

#include 

#include 

#include 

#include 

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指定窗口_第1张图片

3.osg嵌入qt指定窗口

第二部分的代码用osgQt::GraphicWindowQt 构建窗口,我们查看其定义,发现可以用GLWidget直接初始化GraphicWindowQt。
VS下OSG嵌入QT指定窗口_第2张图片
因此osg嵌入qt的原理是GLWidget为连接,用在qt中建立的窗口初始化viewer窗口的大小。
VS下OSG嵌入QT指定窗口_第3张图片

1.新建QT工程

2.添加QT窗口部件

双击ui打开qt designer从左侧拖动listwidget窗口到主界面:
VS下OSG嵌入QT指定窗口_第4张图片

3.osg嵌入QT

参考链接:https://www.cnblogs.com/ningmouming/p/9010164.html
在头文件osgQT中将ui声明由private改为public
VS下OSG嵌入QT指定窗口_第5张图片
主函数当中写:

#include "osgqt.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

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指定窗口_第6张图片

你可能感兴趣的:(osg,qt)