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


相关文章
|
存储 编译器 数据库
[笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV核心类型 Mat
[笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV核心类型 Mat
115 1
|
5月前
|
算法 计算机视觉
【Qt&OpenCV 图像旋转getRotationMatrix2D】
【Qt&OpenCV 图像旋转getRotationMatrix2D】
38 0
|
6月前
|
机器学习/深度学习 API vr&ar
Qt, OpenCV与OpenGL协同作战:图像处理与三维图形界面的完美结合
Qt, OpenCV与OpenGL协同作战:图像处理与三维图形界面的完美结合
955 4
|
存储
QT+OpenGL开始3D
顶点坐标起始于局部空间,它在之后会变为世界坐标,观察坐标,裁减坐标,并最后以屏幕坐标的形式结束。
109 0
|
6月前
|
计算机视觉
[Qt&MFC] 各种方式的图像读取(OpenCv、Halcon)
[Qt&MFC] 各种方式的图像读取(OpenCv、Halcon)
118 0
|
存储 索引
QT+OpenGL模型加载 - Assimp
我们不大可能手工定义房子、汽车或者人形角色这种复杂形状所有的顶点、法线和纹理坐标。我们想要的是将这些模型导入到程序当中。
384 1
|
存储 编解码 编译器
QT+ OpenGL学习
什么是opengl open graphics library 他是一个由Khronos组织制定并且维护的规范 opengl核心是一个c库,同时也支持多种语言的派生
166 0
|
机器学习/深度学习
QT+ OpenGL 变换
我们需要改变物体的位置 现有解决办法(每一帧,改变顶点位置(所有顶点)) 每个顶点使用向量表示,使用矩阵表示对应顶点的操作。
91 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
118 0
|
小程序 图形学 开发者
OpenGL学习笔记(三):了解管线、VAO、VBO的关系,介绍Qt如何使用OpenGL
OpenGL学习笔记(三):了解管线、VAO、VBO的关系,介绍Qt如何使用OpenGL