最近关于Qt3D模块去留的问题,社区讨论的火热。官方有意去掉这个由KDAB公司开发和维护的采用LGPL授权的Qt3D模块,并建议用户使用非LGPL授权的QtQuick3D模块。感觉Qt越来越不友好了...
简单捋一捋OpenGL的东西,尽管之前没用过,以后也不一定用...
Qt 与 OpenGL
Qt 的早期版本就开始提供对 OpenGL 的支持。
Qt2.x/Qt3.x
在 Qt 2.x和Qt3.x中,OpenGL的支持类QGLWidget
就已经存在,允许开发者将 OpenGL 渲染集成到 Qt 应用程序中。
Qt4.x
在Qt4中,对 OpenGL 的支持上做了大量的改进。QGLWidget
依然是 OpenGL 集成的核心,但 Qt 提供了更多的工具和 API,以便更好地管理 OpenGL 资源和执行更复杂的渲染任务。比如
- Qt4.2 引入 QGLFramebufferObject 允许离屏渲染
- Qt4.6 引入 QGLShader 着色器支持
- Qt4.8 引入 QGLFunctions 来封装OPenGL/ES2.0 API
Qt5.x
Qt 5 带来了对现代 OpenGL 的更好支持,并且重构了存在于旧版本中的许多 OpenGL 类和方法。
Qt5中,OpenGL作为核心功能包含在QtGui中,作为QtQuick的基础。源自Qt4的Qt OpenGL模块被边缘化,官方不再建议在新代码中使用。
- QtGui中包含一堆QOpenGL开头的类,如
QOpenGLWidget
、QOpenGLContext
、QOpenGLBuffer
和QOpenGLShaderProgram
等,这些类提供了对底层 OpenGL API 的更直接访问
- QtWidgets中包含 QOpenGLWidget。
OpenGL看起来很美好,用起来,还挺复杂...
OpenGL后端选择???
为解决Windows平台下OpenGL支持不佳的问题,Qt引入 ANGLE,将Direct3D转换为OpenGL ES接口。
编译Qt源码时,可以选择OpenGL
configure -opengl desktop
configure -opengl es2
configure -opengl es2 -no-angle
configure -opengl dynamic
用于控制使用系统自带的opengl驱动,使用angle转换的opengl/es2,使用系统自带的opengl的es2,动态选择。
对于dynamic,Qt程序先尝试系统opengl32.dll是否满足要求,复合要求就使用,不符合要求就尝试用Angle,当Qt程序所在环境不能提供合适的OpenGL2.0实现时,它会自动使用软件实现版本opengl32sw.dll。
用户程序使用的OpenGL,可以通过环境变量QT_OPENGL
指定
desktop
angle
software
使用系统自带,angle转换的,还是软件实现的OpenGL接口。
还可以通过代码指定
Qt::AA_UseDesktopOpenGL
Qt::AA_UseOpenGLES
Qt::AA_UseSoftwareOpenGL
另外,通过json文件还可以根据运行时显卡进一步配置:
disable_desktopgl
disable_angle
disable_d3d11
disable_d3d9
反正,OpenGL要用好,足够烧脑。
- https://phabricator.kde.org/T6728
Qt6.x
随着Vulkan出现,OpenGL的高光地位不在。
在 Qt 6 中,QOpenGLWidget
和相关的 OpenGL 类仍然可用,但已经不再位于QtGui中,在Qt中也不再具有核心地位。
Qt 开始引入一个名为 RHI (Rendering Hardware Interface) 的新抽象层。RHI 旨在提供一个统一的 API,它可以映射到 OpenGL、Direct3D、Metal 或 Vulkan 等不同的底层图形 API,使得 Qt 应用程序可以更好地在不同平台上运行,同时利用各平台的本地图形接口。
QRhi
QRhi是Qt Rendering Hardware Interface缩写,它是Qt内部3D接口的抽象层,提供对OpenGL、Vulkan、Metal、Direct3D等抽象。
Qt6使用QRhi取代了Qt5中OpenGL的核心地位。
QtQuick、QtQuick3D 默认都使用QRhi
私有、半公开
- 在Qt6.6之前,QRhi都是私有的。
- Qt6.6中,类似qpa,变成半公开的API
- Qt6.7中,增加公开类 QRhiWidget(注意QRhi其他位于gui模块的类仍然是半公开的)
- 在Qt6.7之前,使用QWindow进行绘制
Qt6.6之前,官方手册不包含qrhi,有人使用qdoc从qt源码生成对应的qrhi对应的Qt手册
- https://alpqr.github.io/
- https://github.com/alpqr/qrhibasis
QRhi后端
通过环境变量QSG_RHI_BACKEND
选择:
- vlukan
- metal
- opengl
- d3d11
- d3d12
也可以通过代码QSGRendererInterface::GraphicsApi配置:
- QSGRendererInterface::Software
- QSGRendererInterface::OpenVG
- QSGRendererInterface::OpenGL
- QSGRendererInterface::Direct3D11
- QSGRendererInterface::Direct3D12
- QSGRendererInterface::Vulkan
- QSGRendererInterface::Metal
补遗
Qt官方封装 Widget,能正常处理Widget叠加问题。
以QQuickWindow和QQuickWidget,后者之上可以叠加半透明的Widget,而前者不行。
Qt3D
Qt3D的开发始于Qt在Nokia时期,初始版本使用Qt4.8进行开发,当时由demo可以运行于三大桌面系统和Nokia的N9手机。
Qt5.0 alpha版本发布时,Qt3D是作为essential模块包含在内的,开发团队似乎在澳大利亚的布里斯班。但是随着Nokia突然转舵,这个团队似乎被就地解散了。所以Qt5.0正式发布时是已经没有这个模块了。
Qt5.5 中出现的 Qt3D是KDAB 公司开发的,和一开始的Qt3D已经没有多大关系了。
但是,现在,Qt6.8还没有发布。Qt官方已经计划要干掉 Qt3D了(KDAB和官方都没兴趣再维护它)....
- https://www.qt.io/blog/2012/04/11/qt-3d-and-qt5-qt4-news-and-releases
- https://www.kdab.com/qt3d-technology-preview-released-qt-5-5-0/
QtQuick3D
不同于Qt3D支持LGPL协议,QtQuick3D和其他后出现的模块一样,不支持LGPL!!!
- 2017年?,Qt 吸收了 NVIDIA DRIVE Design Studio 这一个3D设计工具
- 2017年,Qt发布了基于NVIDIA的 Qt 3D Studio 1.0
- 2018年,Qt 3D Studio 2.0。使用Qt引擎,取代 NVIDIA 渲染引擎。
- 2019年,Qt Quick 3D 引入到 Qt5.14 中,进而 Qt Design Studio 中
- 2020年,Qt 3D Studio 2.6。后面还有过2.8版本。最终融入Qt Quick 3D 和 Qt Design Studio 中
API
既然OpenGL相关,不妨放一个API表格:
年份 | OpenGL | OpenGL ES | WebGL | Direct3D | Direct3D 12 | Vulkan | Metal |
---|---|---|---|---|---|---|---|
1992 | OpenGL 1.0 | ||||||
1995 | OpenGL 1.1 | ||||||
1995 | DirectX 1.0 | ||||||
1996 | DirectX 2.0 | ||||||
1997 | DirectX 3.0 | ||||||
1997 | DirectX 5.0 | ||||||
1998 | OpenGL 1.2 | ||||||
1998 | DirectX 6.0 | ||||||
1999 | DirectX 7.0 | ||||||
2000 | DirectX 8.0 | ||||||
2001 | OpenGL 1.3 | ||||||
2002 | OpenGL 1.4 | ||||||
2003 | OpenGL 1.5 | OpenGL ES 1.0 | |||||
2004 | OpenGL 2.0 | DirectX 9.0 | |||||
2006 | OpenGL 2.1 | DirectX 10 | |||||
2007 | OpenGL ES 2.0 | ||||||
2008 | OpenGL 3.0 | ||||||
2009 | OpenGL 3.1/3.2 | DirectX 11 | |||||
2010 | OpenGL 4.0/3.3 | ||||||
2010 | OpenGL 4.1 | MacOS和iOS最后支持版本 | |||||
2011 | WebGL 1.0 | ||||||
2012 | OpenGL 4.2 | OpenGL ES 3.0 | DirectX 11.1 | ||||
2012 | OpenGL 4.3 | ||||||
2013 | OpenGL 4.4 | DirectX 11.2 | |||||
2014 | OpenGL ES 3.1 | ||||||
2015 | OpenGL 4.5 | Vulkan 1.0 | Metal | ||||
2016 | WebGL 2.0 | DirectX 12 | |||||
2017 | OpenGL ES 3.2 | ||||||
2018 | Vulkan 1.1 | ||||||
2019 | Metal 2 | ||||||
2020 | Vulkan 1.2 | ||||||
2021 | Metal 3 | ||||||
2022 | Vulkan 1.3 | ||||||
2023 |