首页 > 其他分享 >OSG嵌入QT的简明总结2

OSG嵌入QT的简明总结2

时间:2023-10-17 21:45:40浏览次数:44  
标签:QSurfaceFormat widget 嵌入 QT format new include OSG getOsgViewer

正文

我之前在这篇博文《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();
}

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

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

参考

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

标签:QSurfaceFormat,widget,嵌入,QT,format,new,include,OSG,getOsgViewer
From: https://www.cnblogs.com/charlee44/p/17770785.html

相关文章

  • qt如何隐藏布局
    布局本身无法被隐藏,但是控件可以被隐藏;可以通过将整个布局放入控件中,通过隐藏控件来隐藏整个布局;下面以软键盘为例: 这样设计↑; 运行这样的代码↑; 运行效果↑:......
  • C# M2Mqtt组件连接失败后占用大量cpu不释放以及重复用一个client进行重连会出现假连接
    M2Mqtt是C#的一个mqtt客户端库,这个库很好用,但是它有严重的Bug当我们调用Connect建立连接时,如果身份认证失败,它会返回状态码3,即"连接已拒绝,不合格的客户端标识符",但是其内部的异步线程并不会终止,依然会占用大量的cpu资源,即使Disconnect且把client置为null也没用,除非彻底关闭程序......
  • Qt/C++开源作品45-CPU内存显示控件/和任务管理器一致
    一、前言在很多软件上,会在某个部位显示一个部件,专门显示当前的CPU使用率以及内存占用,方便用户判断当前程序或者当前环境中是否还有剩余的CPU和内存留给程序使用,在不用打开任务管理器或者资源查看器的时候直接得知当前系统的运行情况。尤其是视频监控系统,如果64路全开,肯定很占用CP......
  • QT 常用快捷键
    QT快捷键1、Esc切换到代码编辑状态2、F1查看帮助(选中某一类或函数,按下F1,出现帮助文档)3、F2在光标选中对象的声明和定义之间切换(和Ctrl+鼠标左键一样的效果,选中某一类或函数,按下F2,迅速定位到该类或函数声明的地方或被调用的地方)、4、F3查找下一个5、F4头文件和源文......
  • QT_Creator格式化工具使用
    参考:https://blog.csdn.net/weixin_50183638/article/details/131699478设置Linux风格--style=linux-N-S-M-p-H-U-j-k3设置switch整体缩进indent-switches设置namespace整体缩进indent-namespaces设置预处理模块缩进indent-preproc-block操作符前后填充空......
  • 手机直播源码,关于pyqt5弹出提示框
    手机直播源码,关于pyqt5弹出提示框1.软件关闭弹框这类的弹框一般是在整个软件关闭的时候提醒用户是否需要退出整个软件 (构建成函数的方法)    defcloseEvent(self,event):    #关闭窗口触发以下事件      a=QMessageBox.question(self,'退出'......
  • pytorch(9.7) keras-Embedding 嵌入层
    https://www.tensorflow.org/text/guide/word_embeddings将文本表示为数字机器学习模型将向量(数字数组)作为输入。处理文本时,您必须做的第一件事是想出一种策略,将字符串转换为数字(或“矢量化”文本),然后再将其输入模型。1独热编码作为第一个想法,您可能会对词汇表中的每个单词进......
  • Qt ObjectARX实现获取AutoCAD的实体的DXF数据
    ObjectARX为AutoCAD的二次开发工具。准备工作:1)Visualstudio20172)QT4.12.23)AutoCAD20204)ObjectArx2020SDK5)ObjectArxWizard2020向导以上是需要用到的软件和环境,本文对环境搭建不做阐述,重在记录实现功能。实现的功能介绍:AutoCAD命令行中有自带获取实体数......
  • Qt ObjectARX 2022
    QT中的ARX配置LoadQtDlls.pro1TARGET=QTARXLoadQtDlls2#thesdkincludepath3INCLUDEPATH+="D:\ObjectARX2022\inc"4INCLUDEPATH+="D:\ObjectARX2022\inc-x64"56#rxapi.lib;acdb21.lib;acge21.lib;acad.lib;ac1st21.li......
  • Qt OpenGL textures详解
    1.初始化opengl资源 Q_INIT_RESOURCE:textures(资源名称)QSurfaceFormat:定义3d面显示方式如果在vs+qtvstools中无法正常显示3d图形,则需加入以下代码:format.setStenciBufferSize(8);format.setVersion(1,1);版本号根据用户安装的Qt版本来更改2.继承QOpenGLWidget和QOpen......