OSG和Qt结合

5 篇文章 0 订阅

简述

   想使用Qt做界面开发,OSG做三维图形开发,由于Qt支持OpenGL,而OSG也是由OpenGL作为底层库开发的,所以OSG也能嵌入到Qt中。

程序基于osg3.4和Qt5.5,并且对帧率进行了控制。

实现

QtOsgView.h

#ifndef QTOSGVIEW_H
#define QTOSGVIEW_H

#include <osgViewer/Viewer>
#include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgDB/ReadFile>
#include <QString>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QOpenGLWidget>
#include <QMainWindow>
#include <iostream>

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

QtOsgView.cpp

#include "QtOsgView.h"

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->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();
	std::cout << "帧数:" << mTimer.delta_s(mStrTime, mTime) << std::endl;

	//递归调用
	update();
}

osgqt.h

#ifndef OSGQT_H
#define OSGQT_H

#include <QtWidgets/QWidget>

class osgQt : public QWidget
{
	Q_OBJECT

public:
	osgQt(QWidget *parent = 0);
	~osgQt();

private:
	Ui::osgQtClass ui;
};

#endif // OSGQT_H

osgqt.cpp

#include "osgqt.h"

#include "QtOsgView.h"
#include <QHBoxLayout>

osgQt::osgQt(QWidget *parent)
	: QWidget(parent)
{
	QHBoxLayout *layout = new QHBoxLayout;
	this->setLayout(layout);

	QMainWindow* mw = new QMainWindow(this);
	layout->addWidget(mw);
	mw->setWindowFlags(Qt::Widget);

	osg::ref_ptr<osg::Node>  loadedModel = osgDB::readNodeFile("glider.osg");
	QtOsgView * ViewerWindow = new QtOsgView(mw);
	ViewerWindow->setCameraManipulator(new osgGA::TrackballManipulator);
	ViewerWindow->addEventHandler(new osgViewer::WindowSizeHandler);
	ViewerWindow->addEventHandler(new osgViewer::StatsHandler);
	ViewerWindow->setSceneData(loadedModel.get());
	
	mw->setCentralWidget(ViewerWindow);
}

osgQt::~osgQt()
{

}

main.cpp

#include "osgqt.h"
#include <QtWidgets/QApplication>
#include "QtOsgView.h"

#if 1
int main(int argc, char *argv[])
{
	QApplication a(argc, argv);

	osgQt w;
	w.show();

	return a.exec();
}
#endif


  • 10
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值