OSG嵌入QT的简明总结2

简介: OSG嵌入QT的简明总结2

OSG嵌入QT的简明总结2

正文

我之前在这篇博文《OSG嵌入QT的简明总结》中论述了OSG在QT中显示的可视化问题。其中提到官方提供的osgQt项目(地址:https://github.com/openscenegraph/osgQt )很久前已经更新了。但是我一直没有时间同步更新,最近重新尝试了一下,还是有一些问题。

原先的osgQt版本是兼容Qt4的QGLWidget,这个类Qt官方准备废弃了,现在使用的OpenGL支持组件是QOpenGLWidget,新的osgQt项目就是基于这个类来进行扩展的。在项目中提供了一个例子osgviewerQt,我稍微试用了一下,将其修改成自己的代码时发现了问题,就是渲染的场景宽高比不正确,尤其是将窗体设置成很长或者很窄的时候。我还特意在这个项目中提交了issue:I tried the demo in the project, and the correct aspect ratio cannot be displayed

后续也有人回答了这个问题,一个解决方案就是需要在初始化响应函数中设置相机投影矩阵的宽高比。我改写的例子如下:

#include <QApplication>
#include <QSurfaceFormat>
#include <iostream>
#include <osgDB/ReadFile>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/TrackballManipulator>
#include <osgQOpenGL/osgQOpenGLWidget>
#include <osgUtil/Optimizer>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
int main(int argc, char* argv[]) {
  QSurfaceFormat format = QSurfaceFormat::defaultFormat();
#ifdef OSG_GL3_AVAILABLE
  format.setVersion(3, 2);
  format.setProfile(QSurfaceFormat::CoreProfile);
  format.setRenderableType(QSurfaceFormat::OpenGL);
  format.setOption(QSurfaceFormat::DebugContext);
#else
  format.setVersion(2, 0);
  format.setProfile(QSurfaceFormat::CompatibilityProfile);
  format.setRenderableType(QSurfaceFormat::OpenGL);
  format.setOption(QSurfaceFormat::DebugContext);
#endif
  format.setDepthBufferSize(24);
  // format.setAlphaBufferSize(8);
  format.setSamples(8);
  format.setStencilBufferSize(8);
  format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
  QSurfaceFormat::setDefaultFormat(format);
  QApplication app(argc, argv);
  osgQOpenGLWidget widget;
  QObject::connect(&widget, &osgQOpenGLWidget::initialized, [&widget] {
    // set up the camera manipulators.
    widget.getOsgViewer()->setCameraManipulator(
        new osgGA::TrackballManipulator());
    // add the state manipulator
    widget.getOsgViewer()->addEventHandler(new osgGA::StateSetManipulator(
        widget.getOsgViewer()->getCamera()->getOrCreateStateSet()));
    // add the thread model handler
    widget.getOsgViewer()->addEventHandler(new osgViewer::ThreadingHandler);
    // add the window size toggle handler
    widget.getOsgViewer()->addEventHandler(new osgViewer::WindowSizeHandler);
    // add the stats handler
    widget.getOsgViewer()->addEventHandler(new osgViewer::StatsHandler);
    // add the record camera path handler
    widget.getOsgViewer()->addEventHandler(
        new osgViewer::RecordCameraPathHandler);
    // add the LOD Scale handler
    widget.getOsgViewer()->addEventHandler(new osgViewer::LODScaleHandler);
    // add the screen capture handler
    widget.getOsgViewer()->addEventHandler(new osgViewer::ScreenCaptureHandler);
    // load the data
    std::string filename = "C:/Data/001/010137001.obj";
    osg::ref_ptr<osg::Node> loadedModel = osgDB::readRefNodeFile(filename);
    // optimize the scene graph, remove redundant nodes and state etc.
    osgUtil::Optimizer optimizer;
    optimizer.optimize(loadedModel);
    widget.getOsgViewer()->setSceneData(loadedModel);
    //增加宽高比设置
    QSize size = widget.size();    
    float aspectRatio =
        static_cast<float>(size.width()) / static_cast<float>(size.height());
    widget.getOsgViewer()->getCamera()->setProjectionMatrixAsPerspective(
        60.f, aspectRatio, 1.f, 1000.f);
    return 0;
  });
  widget.resize(200, 600);
  widget.show();
  return app.exec();
}
CPP 折叠 复制 全屏

上述例子确实可以让场景显示正常,即使窗体宽设置为200,高设置为600。不过我发现了另外一个问题,按S显示帧数的时候帧数比之前的解决方案低很多。之前的解决方案帧数可以达到200帧,但是这个解决方案帧数大概在90帧左右。

具体看了一下其封装的osgQOpenGLWidget的实现,我觉得可能有两个原因,第一个是渲染的帧函数中有同步锁,不知道会不会有所影响。第二个是这个解决方案获取的帧数好像是自己计算的,与OSG内部计算的帧数不同似乎也正常。不过我这里是不太敢用这个解决方案了,目前还是使用之前的解决方案,以后有机会还是自己研究一下其中的实现。

参考

  1. OpenSceneGraph + QOpenGLWidget - minimal example
  2. OSG 使用Qt的QOpenGLWidget

分类: OSG

标签: OSG , QT


相关文章
|
8月前
QT4.7版本的OPENGL的3D旋转模型例子
QT4.7版本的OPENGL的3D旋转模型例子
142 0
|
8月前
|
机器学习/深度学习 API vr&ar
Qt, OpenCV与OpenGL协同作战:图像处理与三维图形界面的完美结合
Qt, OpenCV与OpenGL协同作战:图像处理与三维图形界面的完美结合
1107 4
|
存储 索引
QT+OpenGL模型加载 - Assimp
我们不大可能手工定义房子、汽车或者人形角色这种复杂形状所有的顶点、法线和纹理坐标。我们想要的是将这些模型导入到程序当中。
442 1
|
C语言 C++
为什么要学习easyx图形库,他是做什么的?值得吗?
首先,easyx仅支持C语言和C++,这对于学习C语言的新生来说很友好,在熟悉C语言的同时还可以提高写代码的能力,在熟悉C语言以后,就可以尝试写一写小游戏了,比如说扫雷,三子棋,魔塔,贪吃蛇,飞机大战等等,但是当我们写出来运行的时候可以发现,游戏的逻辑写的没有问题,也的确可以玩,但是界面和人物怪兽什么的都很丑,全是符号不好看,同时控制台一闪一闪的,对玩家来说体验感极差,这也就是我们为什么要学习easyx图形库。
266 1
|
机器学习/深度学习
QT+ OpenGL 变换
我们需要改变物体的位置 现有解决办法(每一帧,改变顶点位置(所有顶点)) 每个顶点使用向量表示,使用矩阵表示对应顶点的操作。
95 0
|
存储 编解码 编译器
QT+ OpenGL学习
什么是opengl open graphics library 他是一个由Khronos组织制定并且维护的规范 opengl核心是一个c库,同时也支持多种语言的派生
178 0
|
数据可视化
QT+OpenGL几何着色器
输入布局限定符可以从顶点着色器接收下列任何一个图元值: ● points:绘制GL_POINTS图元时 ● lines:绘制GL_LINES或GL_LINE_STRIP时 ● lines_adjacency:GL_ADJACENCY或GL_LINESTRIP_ADJACENCY ● triangles:GL_TRIANGLES、GL_TRIANGLE_STRIP或GL_TRIANGLE_FAN ● triangles_adjacency:GL_TRIANGLES_ADJACENCY或GL_TRIANGLE_STRIP_ADJACENCY
129 0
|
存储 前端开发 C++
Qt模型/视图框架(一)
Qt模型/视图框架(一)
|
存储 C++ 索引
Qt模型视图框架(二)
Qt模型视图框架(二)