OSG嵌入QT配置

前提

已经完成osg在vs2017上的64位编译生成编译包,现在尝试把osg嵌入qt中,实现交互

配置

首先在vs下生成一个新的项目

OSG嵌入QT配置_第1张图片

勾选openGL选项

OSG嵌入QT配置_第2张图片

然后对Osg的vs项目属性进行配置(Tip:在此之前一定记得电脑的环境变量中一定要先配好,因为是基于已经完成编译了这里就不讲怎么配了网上很多大概是如下)

OSG嵌入QT配置_第3张图片

vs2017属性配置:

属性页配置

OSG嵌入QT配置_第4张图片

链接器中,附加依赖项加入osg的lib(Debug所以后面有d,Release没有)

OSG嵌入QT配置_第5张图片
里面直接粘贴:

OpenThreadsd.lib 
osgd.lib 
osgDBd.lib 
osgFXd.lib 
osgGAd.lib 
osgManipulatord.lib 
osgParticled.lib
 osgShadowd.lib 
osgSimd.lib 
osgTerraind.lib 
osgTextd.lib 
osgUtild.lib 
osgViewerd.lib

至此配置完成现在来把Osg嵌入qt中
新建一个普通视图类QtOsgView用于控制QT中OSG的渲染,和一些基本响应,代码如下
QtOsgView.cpp

#include "QtOsgView.h"
#include 

AdapterWidget::AdapterWidget(QWidget *parent, const char* name, const QGLWidget * shareWidget, Qt::WindowFlags f)
{
	mGw = new osgViewer::GraphicsWindowEmbedded(0, 0, width(), height());//创建可移植的窗口。

	setFocusPolicy(Qt::ClickFocus);
}

void AdapterWidget::resizeGL(int width, int height)
{
	//mGw->getEventQueue()->windowResize(0, 0, width, height);
	mGw->getEventQueue()->windowResize(0, 0, width, height);
	mGw->resized(0, 0, width, height);
}
void AdapterWidget::keyPressEvent(QKeyEvent* event)
{
	mGw->getEventQueue()->keyPress((osgGA::GUIEventAdapter::KeySymbol) *(event->text().toUtf8().data()));
}

void AdapterWidget::keyReleaseEvent(QKeyEvent* event)
{
	mGw->getEventQueue()->keyRelease((osgGA::GUIEventAdapter::KeySymbol)*(event->text().toUtf8().data()));
}


void AdapterWidget::mousePressEvent(QMouseEvent* event)
{
	int button = 0;
	switch (event->button())
	{
	case(Qt::LeftButton):
		button = 1;
		break;
	case (Qt::MidButton):
		button = 2;
		break;
	case (Qt::RightButton):
		button = 3;
		break;
	case (Qt::NoButton):
		button = 0;
		break;
	default:
		button = 0;
		break;
	}

	mGw->getEventQueue()->mouseButtonPress(event->x(), event->y(), button);
}

void AdapterWidget::mouseReleaseEvent(QMouseEvent* event)
{
	int button = 0;
	switch (event->button())
	{
	case(Qt::LeftButton):
		button = 1;
		break;
	case(Qt::MidButton):
		button = 2;
		break;
	case(Qt::RightButton):
		button = 3;
		break;
	case(Qt::NoButton):
		button = 0;
		break;
	default:
		button = 0;
		break;
	}
	mGw->getEventQueue()->mouseButtonRelease(event->x(), event->y(), button);
}


void  AdapterWidget::mouseMoveEvent(QMouseEvent* event)
{
	mGw->getEventQueue()->mouseMotion(event->x(), event->y());
}

void AdapterWidget::wheelEvent(QWheelEvent* event)
{
	mGw->getEventQueue()->mouseScroll(event->delta() > 0 ? osgGA::GUIEventAdapter::SCROLL_UP : osgGA::GUIEventAdapter::SCROLL_DOWN);
}


QtOsgView::QtOsgView(QWidget * parent, const char * name, const QGLWidget * shareWidget, Qt::WindowFlags f) :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);

	mStrTime = 0.0;
	mEndTime = 0.0;
	mSleepTime = 0.0;

	num = 0;
}

void QtOsgView::paintGL()
{
	mStrTime = mTimer.tick();
	frame();
	num++;
	mEndTime = mTimer.tick();

	//计算需要睡眠的时间
	mSleepTime = 1.0 / 60.0 - mTimer.delta_s(mStrTime, mEndTime);

	if (mSleepTime < 0)
	{
		mSleepTime = 0.0;
	}

	//睡眠
	OpenThreads::Thread::microSleep(mSleepTime * 1000000);		//微秒
	Sleep(mSleepTime * 1000);										//毫秒

	double mTime = mTimer.tick();
	//qDebug() << "帧数:" << mTimer.delta_s(mStrTime, mTime);

	//递归调用
	update();
}

QtOsgView.h

#ifndef QTOSGVIEW_H
#define QTOSGVIEW_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

class AdapterWidget :public QOpenGLWidget
{
public:
	AdapterWidget(QWidget *parent = 0, const char* name = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0);

	virtual ~AdapterWidget() {}

	osgViewer::GraphicsWindow* getGraphicsWindow()
	{
		return mGw.get();
	}

	const osgViewer::GraphicsWindow* getGraphicsWidow()const
	{
		return mGw.get();
	}
protected:
	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> mGw;
};

class QtOsgView : public osgViewer::Viewer, public AdapterWidget
{
public:
	QtOsgView(QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0);

	~QtOsgView() {}

	virtual void paintGL();

protected:
	osg::Timer mTimer;			//定时器,控制帧速
	double mStrTime;			//开始tick时间
	double mEndTime;			//结束tick时间

	double mSleepTime;			//需要睡眠的时间
	int num;
};
#endif // QTOSGWIDGET_H

下一步就是提升为的操作(这里我想的是把QT的窗口提升为之前我们定义的普通类窗口QtOsgView实现osg的窗口化)

OSG嵌入QT配置_第6张图片
在新建Widget上右击空白处选择提升窗口部件
手动输入类名称和头文件
OSG嵌入QT配置_第7张图片
这样我们的WIdget就能够在qt中显示出来了下面只需要在我们的osg_qt类中把自己的代码写入即可
下面贴上我自己的代码
osg_qt.h

#include 
#include 
#include "ui_osg_qt.h"

class osg_qt :public QMainWindow
{
	Q_OBJECT

public:
	osg_qt(QWidget *parent = 0);

private:
	Ui::osg_qtClass ui;
};

osg_qt.cpp

#include "osg_qt.h"

osg_qt::osg_qt(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);
	QMainWindow* mw = new QMainWindow(this);
	mw->setWindowFlags(Qt::Widget);
	osg::ref_ptr<osg::Group>  root = new osg::Group;
	osg::ref_ptr<osg::Node>car = new osg::Node();
	osgDB::Options *funa = new osgDB::Options(std::string("noTriStripPolygons"));
	car = osgDB::readNodeFile("min_stl.STL", funa);//这里需要自己加入文件
	root->addChild(car.get());
	ui.osg_widget = new QtOsgView(mw);
	ui.osg_widget->setCameraManipulator(new osgGA::TrackballManipulator);
	ui.osg_widget->addEventHandler(new osgViewer::WindowSizeHandler);
	ui.osg_widget->addEventHandler(new osgViewer::StatsHandler);
	ui.osg_widget->setSceneData(root.get());
	mw->setCentralWidget(ui.osg_widget);
	this->setCentralWidget(mw);
}

运行一下就可以啦
OSG嵌入QT配置_第8张图片
大功告成!
至此非常感谢一些大佬的博客
@某吃货敲代码和@先锋小牛大家感兴趣的话可以去他们的主页多学习下

你可能感兴趣的:(OSG,OSG,OSG入门,OSG+QT)