已经完成osg在vs2017上的64位编译生成编译包,现在尝试把osg嵌入qt中,实现交互
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
在新建Widget上右击空白处选择提升窗口部件
手动输入类名称和头文件
这样我们的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);
}
运行一下就可以啦
大功告成!
至此非常感谢一些大佬的博客
@某吃货敲代码和@先锋小牛大家感兴趣的话可以去他们的主页多学习下