1.解决方案

不得不说关于OSG的资料实在太零散了,搜索了很多关于OSG在QT下的解决方案,都是各有各的说法,有的说的不是很清楚,有的已经过时了。这里提供一下自己的解决方案吧。

在远古的OSG里面,应该是提供对QT的支持的;不过应该是由于QT版本变动比较大,现在的OSG版本应该已经没有了。但是在GitHub上又有了新的osgQt项目(地址:https://github.com/openscenegraph/osgQt )用来解决这个问题。

osgQt是个简单的小项目,其实没有必要额外的编译,最核心的是个名为GraphicsWindowQt的类,只需要复制GraphicsWindowQt.h和GraphicsWindowQt.cpp到QT工程里面就可以使用了。同时osgQt给出了一个名为osgviewerQt的样例,也仅仅只是个cpp文件。结合两者,一个简单的示例就出来了。

QT工程如下:



编译运行后如下:

2.存在问题

1) 警告提示

上述项目直接运行,会出现诸如“QOpenGLContext::swapBuffers() called with non-exposed window, behavior is undefined”的警告。查阅网上的英文资料,大意说是因为OpenGL环境未初始化产生的。在osgviewerQt中绑定了一个定时器,每隔10ms就调用frame()来绘制一帧,而这个定时器是在构造函数的时候就开始调用了,没有等待QT中OpenGL环境的生成。在这里我把定时器的部分给改进了一下,等待OSG的环境初始化完成在启动定时器,这个警告就没有了。osgviewerQt改进后的代码如下:

#include <QTimer>
#include <QApplication>
#include <QGridLayout> #include <osgViewer/CompositeViewer>
#include <osgViewer/ViewerEventHandlers> #include <osgGA/MultiTouchTrackballManipulator> #include <osgDB/ReadFile> #include "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::readRefNodeFile("D:/Work/OSGBuild/OpenSceneGraph-Data/cow.osgt") );
QWidget* widget2 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("D:/Work/OSGBuild/OpenSceneGraph-Data/glider.osgt") );
QWidget* widget3 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("D:/Work/OSGBuild/OpenSceneGraph-Data/axes.osgt") );
QWidget* widget4 = addViewWidget( createGraphicsWindow(0,0,100,100), osgDB::readRefNodeFile("D:/Work/OSGBuild/OpenSceneGraph-Data/fountain.osgt") );
// QWidget* popupWidget = addViewWidget( createGraphicsWindow(900,100,320,240,"Popup window",true), osgDB::readRefNodeFile("D:/Work/OSGBuild/OpenSceneGraph-Data/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::ref_ptr<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) ); // set the draw and read buffers up for a double buffered window with rendering going to back buffer
camera->setDrawBuffer(GL_BACK);
camera->setReadBuffer(GL_BACK); 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(); } //定时器事件
void timerEvent(QTimerEvent* )
{
frame();
} //启动定时器绘制
void show()
{
QWidget::show();
_timerID = startTimer(10);
} protected: //QTimer _timer;
int _timerID; //定时器ID
}; 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();
}

2) 多线程问题

在OSG中提供了诸如CullDrawThreadPerContext等多线程模式,但是在这里是没办法支持这些多线程模式的,只能支持单线程。在网上查阅了一些解决方案,但是最后都不是很完美,有空再把其解决方案写出来。

3) 其他

GraphicsWindowQt最终继承的还是QT中的QGLWidget类,提供OpenGL功能。而在新版本的QT中,这个类已经被废弃了,取而代之的是一个叫做QOpenGLWidget的类。所以这里面问题还是不少的,好在内容相对较少,以后有空可以自己改进。

OSG嵌入QT的简明总结的更多相关文章

  1. OSG嵌入QT(QT界面使用Qt Designer编辑)

    本文主要内容:使用Qt Designer编辑好QT界面后,将OSG中的ViewerWidget嵌入到QT的Widget中. 在VS中嵌入QT工具,建立QT GUIApplication后,打开自动生成 ...

  2. [原][osg][QT]osg与QT界面结合的简单例子二

    //main.cpp #include "VREObliqueEditorQTWindow.h" #include <QtWidgets/QApplication> # ...

  3. 基于osgQt将OSG嵌入到Qt窗口中(有错误)

    1, 编译OSG 由于重装了win10的系统,Qt也安装了最新版5.13,把之前OSG重新编译了一遍,过程与之前的一模一样. Windows7 + OSG3.6 + VS2017 + Qt5.11 2 ...

  4. OpenGL学习笔记5——嵌入Qt框架

    学习OpenGL也有段时间了,前几篇将GL最基本的画图过程解析了一下,后面进阶的就随项目需要再学.因为之前一直是用glut这个实用工具包来开发很方便,但是会附带一个控制台的窗口,实在觉得有些low,因 ...

  5. [转][osg][QT]osg与QT界面结合的简单例子

    //QT += core gui opengl //LIBS += -losgViewer -losgDB -losgUtil -losg -lOpenThreads -losgGA -losgQt ...

  6. 2018.8.23几日重新编译OSG+OE+Qt遇到的问题

    Qt安装多个版本的时候,注意屏蔽掉不使用的Qt,例如OE中的CMakeLists.txt中的# FIND_PACKAGE(Qt4) 使用以前编译好的libcurl.dll现在出现"无法定位序 ...

  7. 将Unreal4打包后的工程嵌入到Qt或者桌面中

    #include "widget.h" #include "ui_widget.h" #include "windows.h" #inclu ...

  8. 对《将Unreal4打包后的工程嵌入到Qt或者桌面中》一文的补充

    在上一文中本人尝试将Ue4嵌入到Qt中,但依然有一些问题没有去尝试解决.今天因为帮助知乎专栏作者@大钊的关系,顺便进行补完. 2018.7.18更新: 正好在参加杭州UnrealCircle的时候见到 ...

  9. 单独编译osgQt模块 Qt moc

    从alphapixel网站下载了OSG3.0.1VS2010x64版本的库,但是里面不包括osgQt模块,于是得自己编译 *************osgQtx64.zip工程文件可以去本博客园的“文 ...

随机推荐

  1. Python中的Tcp协议应用之TCP服务端-协程版(推荐)

    利用gevent第三方库,实现协程. 通过协程实现一个服务端服务多个客户端需求. 使用协程的好处是协程比线程更加节省内存资源. gevent安装命令: pip3 install gevent 注意:在 ...

  2. 学习ThinkPHP的第23天---门面、钩子与行为

    一.门面(facade) 门面在ThinkPHP中可以理解为一个代理商,有了它可以灵活的去使用其中的类. 二.钩子和行为 钩子也可以说是插件,就是程序运行到某个位置,我们用钩子把这个程序截住,去执行所 ...

  3. Xcode10.0: NO BUNDLE URL PRESENT

    目录 解决方案 1.删除build, 重新运行, 没有work 2.删除node_modules, npm i, 重新运行, 没有work 3.删除端口占用 4.代理设置, 可能work了 解决方案 ...

  4. openlayers4 入门开发系列结合 echarts4 实现散点图(附源码下载)

    前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...

  5. UVA-11995

    There is a bag-like data structure, supporting two operations:1 x Throw an element x into the bag.2 ...

  6. 【CSS】343- CSS Grid 网格布局入门

    CSS Grid(网格) 布局使我们能够比以往任何时候都可以更灵活构建和控制自定义网格.Grid(网格) 布局使我们能够将网页分成具有简单属性的行和列. 它还能使我们在不改变任何HTML的情况下,使用 ...

  7. python笔记03

    day03 一.今日内容: 1.整型 2.字符串 3.布尔类型 二.内容回顾和补充 脑图--xmind软件,processon 1.运算符补充(in.not in) value = "我是中 ...

  8. CSS之position属性

    层级的话可以用z-inde进行设置

  9. xshell6和xftp6运行提示缺少mfc110u.dll文件的解决办法

    xshell6和xftp6运行提示缺少mfc110u.dll文件的解决办法 下载地址 http://www.microsoft.com/zh-CN/download/details.aspx?id=3 ...

  10. salt python msgpack.exceptions.

    msgpack.exceptions.UnpackValueError: 'utf-8' codec can't decode byte 0x82 in position 22: invalid st ...