QOpenGLContext Class

QOpenGLContext 类表示本地 OpenGL上下文,可在QSurface 上进行 OpenGL 渲染。

头文件: #include <QOpenGLContext>
CMake: find_package(Qt6 REQUIRED COMPONENTS Gui)
target_link_libraries(mytarget PRIVATE Qt6::Gui)
qmake: QT += gui
继承: QObject

公共类型

enum OpenGLModuleType { LibGL, LibGLES }

公共函数

QOpenGLContext(QObject *parent = nullptr)
virtual ~QOpenGLContext()
bool create()
GLuint defaultFramebufferObject() const
void doneCurrent()
QSet<QByteArray> extensions() const
QOpenGLExtraFunctions *extraFunctions() const
QSurfaceFormat format() const
QOpenGLFunctions *functions() const
QFunctionPointer getProcAddress(const QByteArray &procName) const
QFunctionPointer getProcAddress(const char *procName) const
bool hasExtension(const QByteArray &extension) const
bool isOpenGLES() const
bool isValid() const
bool makeCurrent(QSurface *surface)
QNativeInterface *nativeInterface() const
QScreen *screen() const
void setFormat(const QSurfaceFormat &format)
void setScreen(QScreen *screen)
void setShareContext(QOpenGLContext *shareContext)
QOpenGLContext *shareContext() const
QOpenGLContextGroup *shareGroup() const
QSurface *surface() const
void swapBuffers(QSurface *surface)

信号

静态公共成员

bool areSharing(QOpenGLContext *first, QOpenGLContext *second)
QOpenGLContext *currentContext()
QOpenGLContext *globalShareContext()
QOpenGLContext::OpenGLModuleType openGLModuleType()
bool supportsThreadedOpenGL()

详细说明

QOpenGLContext 表示底层 OpenGL 上下文的 OpenGL 状态。要设置一个上下文,需要设置其屏幕和格式,使其与要使用该上下文的曲面相匹配,必要时使用setShareContext() 使其与其他上下文共享资源,最后调用create() 。使用返回值或isValid() 检查上下文是否已成功初始化。

可以通过调用makeCurrent() 使上下文针对给定曲面生效。OpenGL 渲染完成后,调用swapBuffers() 交换曲面的前后缓冲区,这样新渲染的内容就会显示出来。为了支持某些平台,QOpenGLContext 要求在调用swapBuffers() 后,再次调用makeCurrent() 才开始渲染新的帧。

如果暂时不需要上下文,例如应用程序不进行渲染时,删除上下文可以释放资源。您可以连接到aboutToBeDestroyed() 信号来清理任何以不同于 QOpenGLContext 本身的所有权分配的资源。

一旦 QOpenGLContext 成为当前资源,您就可以通过使用 Qt 的 OpenGL 开启程序(如QOpenGLFunctionsQOpenGLBufferQOpenGLShaderProgramQOpenGLFramebufferObject ),以独立于平台的方式对其进行渲染。您也可以不使用 Qt 开启程序,直接使用平台的 OpenGL API,但这可能会影响可移植性。要使用 OpenGL 1.x 或 OpenGL ES 1.x 时,后者是必要的。

有关 OpenGL API 的更多信息,请参阅OpenGL 官方文档

有关如何使用 QOpenGLContext 的示例,请参阅OpenGL 窗口示例。

线程亲和性

可以使用moveToThread() 将 QOpenGLContext 移至不同的线程。请勿从与 QOpenGLContext 对象所属线程不同的线程调用makeCurrent() 。一个上下文只能在一个线程中同时对一个表面生效,一个线程一次只能对一个上下文生效。

上下文资源共享

纹理和顶点缓冲对象等资源可在上下文之间共享。在调用create() 之前,请使用setShareContext() 指定上下文应共享这些资源。QOpenGLContext 内部会跟踪一个QOpenGLContextGroup 对象,该对象可通过shareGroup() 访问,并可用于查找给定共享组中的所有上下文。共享组由已成功初始化并与共享组中现有上下文共享的所有上下文组成。非共享上下文的共享组由单个上下文组成。

默认帧缓冲区

在某些平台上,默认帧缓冲区可能不是 0,这取决于当前曲面。建议不要调用 glBindFramebuffer(0),而是使用 glBindFramebuffer(ctx->defaultFramebufferObject()) 来确保应用程序在不同平台之间的可移植性。不过,如果您使用QOpenGLFunctions::glBindFramebuffer() ,系统会自动为您完成这一操作。

警告: WebAssembly

QSurface我们建议在QSurface 的整个生命周期内只使用一个 QOpenGLContext。如果使用多个上下文,请务必了解多个 QOpenGLContext 实例可能由 WebAssembly 平台下的相同本地上下文支持。因此,在两个 QOpenGLContext 对象上使用相同的QSurface 调用makeCurrent() 可能无法在第二次调用中切换到不同的本地上下文。因此,在第二次makeCurrent() 之后进行的任何 OpenGL 状态更改都可能会改变第一个 QOpenGLContext 的状态,因为它们都由相同的本地上下文支持。

注: 这意味着在使用现有基于 OpenGL 的 Qt 代码针对 WebAssembly 时,可能需要进行一些移植以适应这些限制。

另请参阅 QOpenGLFunctions,QOpenGLBuffer,QOpenGLShaderProgram, 和QOpenGLFramebufferObject

成员类型文档

enum QOpenGLContext::OpenGLModuleType

该枚举定义了底层 OpenGL 实现的类型。

常量描述
QOpenGLContext::LibGL0OpenGL
QOpenGLContext::LibGLES1OpenGL ES 2.0 或更高版本

成员函数文档

[explicit] QOpenGLContext::QOpenGLContext(QObject *parent = nullptr)

创建一个新的 OpenGL 上下文实例,其父对象为parent

在使用之前,您需要设置适当的格式并调用create().

另请参阅 create() 和makeCurrent()。

[virtual noexcept] QOpenGLContext::~QOpenGLContext()

销毁QOpenGLContext 对象。

如果这是线程的当前上下文,doneCurrent() 也会被调用。

[signal] void QOpenGLContext::aboutToBeDestroyed()

该信号在底层本地 OpenGL 上下文销毁之前发出,这样用户就可以清理 OpenGL 资源,否则在共享 OpenGL 上下文的情况下,这些资源可能会被闲置。

如果您希望使上下文处于当前状态以便进行清理,请确保只使用直接连接来连接该信号。

注意: Qt for Python 中,由于 Python 实例已被销毁,因此从QOpenGLWidgetQOpenGLWindow 的析构函数发出的信号将不会被接收。我们建议在QWidget::hideEvent() 中进行清理。

[static] bool QOpenGLContext::areSharing(QOpenGLContext *first, QOpenGLContext *second)

如果firstsecond 上下文共享 OpenGL 资源,则返回true

bool QOpenGLContext::create()

尝试使用当前配置创建 OpenGL 上下文。

当前配置包括格式、共享上下文和屏幕。

如果系统上的 OpenGL 实现不支持所请求的 OpenGL 上下文版本,那么QOpenGLContext 将尝试创建最匹配的版本。实际创建的上下文属性可使用format() 函数返回的QSurfaceFormat 进行查询。例如,如果您请求的上下文支持 OpenGL 4.3 核心配置文件,但驱动程序和/或硬件只支持 3.2 版本的核心配置文件上下文,那么您将得到一个 3.2 核心配置文件上下文。

如果本机上下文已成功创建,并可与makeCurrent(),swapBuffers() 等一起使用,则返回true

注意: 如果上下文已经存在,该函数将首先销毁现有上下文,然后创建新的上下文。

另请参阅 makeCurrent() 和format()。

[static] QOpenGLContext *QOpenGLContext::currentContext()

返回当前线程中最后一次调用makeCurrent 的上下文;如果当前没有上下文,则返回nullptr

GLuint QOpenGLContext::defaultFramebufferObject() const

调用该命令可获取当前表面的默认帧缓冲对象。

在某些平台(如 iOS)上,默认帧缓冲对象取决于渲染的表面,可能与 0 不同。因此,如果您希望应用程序在不同的 Qt 平台上运行,则应调用 glBindFramebuffer(ctx->defaultFramebufferObject()),而不是调用 glBindFramebuffer(0)。

如果在QOpenGLFunctions 中使用 glBindFramebuffer(),则不必担心这个问题,因为当传递 0 时,它会自动绑定当前上下文的 defaultFramebufferObject()。

注意: 通过帧缓冲对象进行渲染的部件(如QOpenGLWidgetQQuickWidget )将在绘制激活时覆盖此函数返回的值,因为此时正确的 "默认 "帧缓冲是部件的关联后备帧缓冲,而不是属于顶层窗口表面的平台特定帧缓冲。这确保了该函数和其他依赖该函数的类(例如QOpenGLFramebufferObject::bindDefault() 或QOpenGLFramebufferObject::release() )的预期行为。

另请参见 QOpenGLFramebufferObject

void QOpenGLContext::doneCurrent()

方便函数,用于调用表面值为 0 的makeCurrent

这将导致当前线程中没有上下文。

另请参阅 makeCurrent() 和currentContext() 。

QSet<QByteArray> QOpenGLContext::extensions() const

返回此上下文支持的 OpenGL 扩展集。

上下文或共享上下文必须是当前的。

另请参阅 hasExtension()。

QOpenGLExtraFunctions *QOpenGLContext::extraFunctions() const

获取此上下文的QOpenGLExtraFunctions 实例。

QOpenGLContext 这是访问 的便捷方法,无需手动管理。QOpenGLExtraFunctions

上下文或共享上下文必须是当前的。

返回的QOpenGLExtraFunctions 实例可随时使用,无需调用 initializeOpenGLFunctions()。

注意: QOpenGLExtraFunctions 包含的功能不能保证在运行时可用。运行时的可用性取决于平台、图形驱动程序和应用程序要求的 OpenGL 版本。

另请参见 QOpenGLFunctionsQOpenGLExtraFunctions

QSurfaceFormat QOpenGLContext::format() const

如果调用了create() ,则返回底层平台上下文的格式。

否则,返回请求的格式。

请求的格式和实际格式可能不同。请求给定的 OpenGL 版本并不意味着生成的上下文将完全以请求的版本为目标。只要驱动程序能够提供这样的上下文,就只能保证创建的上下文的版本/配置文件/选项组合与请求兼容。

例如,请求一个 OpenGL 3.x 版本的核心配置文件上下文,可能会得到一个 OpenGL 4.x 核心配置文件上下文。同样,请求 OpenGL 2.1 可能会得到启用了过时功能的 OpenGL 3.0 上下文。最后,根据驱动程序的不同,不支持的版本可能会导致上下文创建失败,或导致最高支持版本的上下文。

缓冲区大小也可能存在类似差异,例如,生成的上下文可能比请求的深度缓冲区更大。这完全正常。

另请参见 setFormat().

QOpenGLFunctions *QOpenGLContext::functions() const

获取此上下文的QOpenGLFunctions 实例。

QOpenGLContext 这是访问 的便捷方法,无需手动管理。QOpenGLFunctions

上下文或共享上下文必须是当前的。

返回的QOpenGLFunctions 实例可随时使用,无需调用 initializeOpenGLFunctions()。

QFunctionPointer QOpenGLContext::getProcAddress(const QByteArray &procName) const

解析指向 OpenGL 扩展函数的函数指针,该函数由procName

如果找不到该函数,则返回nullptr

QFunctionPointer QOpenGLContext::getProcAddress(const char *procName) const

这是一个重载函数。

[static] QOpenGLContext *QOpenGLContext::globalShareContext()

如果存在,则返回整个应用程序的 OpenGL 共享上下文。否则将返回nullptr

如果您需要在创建或显示QOpenGLWidgetQQuickWidget 之前上传 OpenGL 对象(缓冲区、纹理等),这将非常有用。

注意: 在创建QGuiApplication 对象之前,必须在QGuiApplication 上设置Qt::AA_ShareOpenGLContexts 标志,否则 Qt XML 可能无法创建全局共享上下文。

警告: 请勿尝试将此函数返回的上下文设置为任何表面上的当前上下文。相反,您可以创建一个与全局共享的新上下文,然后使新上下文成为当前上下文。

另请参阅 Qt::AA_ShareOpenGLContextssetShareContext() 和makeCurrent()。

bool QOpenGLContext::hasExtension(const QByteArray &extension) const

如果此 OpenGL 上下文支持指定的 OpenGLextension ,则返回true ,否则返回false

上下文或共享上下文必须是当前的。

另请参阅 extensions().

bool QOpenGLContext::isOpenGLES() const

如果上下文是 OpenGL ES 上下文,则返回 true。

如果上下文尚未创建,结果将基于通过setFormat() 设置的请求格式。

另请参阅 create(),format() 和setFormat().

bool QOpenGLContext::isValid() const

返回该上下文是否有效,即是否已成功创建。

在某些平台上,如果先前成功创建的上下文返回值为false ,则表示 OpenGL 上下文已丢失。

在应用程序中处理上下文丢失情况的典型方法是,每当makeCurrent() 失败并返回false 时,通过此函数进行检查。如果该函数返回false ,则通过调用create() 重新创建底层本地 OpenGL 上下文,然后再次调用makeCurrent() 并重新初始化所有 OpenGL 资源。

在某些平台上,上下文丢失的情况是无法避免的。但在其他平台上,可能需要选择加入。这可以通过在QSurfaceFormat 中启用ResetNotification 来实现。这将导致在底层本地 OpenGL 上下文中将RESET_NOTIFICATION_STRATEGY_EXT 设置为LOSE_CONTEXT_ON_RESET_EXT 。然后,QOpenGLContext 将通过glGetGraphicsResetStatusEXT() 在每个makeCurrent() 中监控状态。

另请参阅 create() 。

bool QOpenGLContext::makeCurrent(QSurface *surface)

使当前线程中的上下文与给定的surface 一致。如果成功,则返回true ;否则返回false 。如果曲面未暴露,或由于应用程序暂停等原因导致图形硬件不可用,则可能出现后一种情况。

如果surfacenullptr ,则相当于调用doneCurrent() 。

请避免在与QOpenGLContext 实例所在线程不同的线程中调用此函数。如果希望在不同的线程中使用QOpenGLContext ,应首先确保它不在当前线程中,必要时可调用doneCurrent() 。然后调用 moveToThread(otherThread) 才能在其他线程中使用。

默认情况下,Qt 会对线程亲和性进行检查,以执行上述条件。仍可通过设置Qt::AA_DontCheckOpenGLContextThreadAffinity 应用程序属性来禁用该检查。请务必了解从所处线程之外使用 QObjects 的后果,如QObject thread affinity 文档中所述。

另请参阅 functions(),doneCurrent() 和Qt::AA_DontCheckOpenGLContextThreadAffinity

template <typename QNativeInterface> QNativeInterface *QOpenGLContext::nativeInterface() const

返回上下文中给定类型的本地接口。

该函数提供了对QOpenGLContext 平台特定功能的访问,这些功能在QNativeInterface 命名空间中定义:

QNativeInterface::QCocoaGLContext

macOS 上 NSOpenGLContext 的本地接口

QNativeInterface::QEGLContext

EGL 上下文的本地接口

QNativeInterface::QGLXContext

GLX 上下文的本地接口

QNativeInterface::QWGLContext

Windows 上 WGL 上下文的本地接口

如果请求的接口不可用,将返回nullptr

[static] QOpenGLContext::OpenGLModuleType QOpenGLContext::openGLModuleType()

返回底层 OpenGL 实现类型。

在未动态加载 OpenGL 实现的平台上,返回值在编译时确定,不会更改。

注意: 桌面 OpenGL 实现可能也能创建 ES 兼容上下文。因此,在大多数情况下,检查QSurfaceFormat::renderableType() 或使用便捷函数isOpenGLES() 更为合适。

注意: 该函数要求QGuiApplication 实例已经创建。

QScreen *QOpenGLContext::screen() const

返回创建上下文的屏幕。

另请参阅 setScreen()。

void QOpenGLContext::setFormat(const QSurfaceFormat &format)

设置 OpenGL 上下文应兼容的format 。需要调用create() 才能生效。

如果未通过此函数明确设置格式,则将使用QSurfaceFormat::defaultFormat() 返回的格式。这就意味着,当有多个上下文时,可以在创建第一个上下文之前调用一次QSurfaceFormat::setDefaultFormat() 来代替对该函数的单独调用。

另请参见 format()。

void QOpenGLContext::setScreen(QScreen *screen)

设置 OpenGL 上下文的有效期screen 。需要调用create() 才能生效。

另请参阅 screen().

void QOpenGLContext::setShareContext(QOpenGLContext *shareContext)

使该上下文与shareContext 共享纹理、着色器和其他 OpenGL 资源。需要调用create() 才能生效。

另请参阅 shareContext() 。

QOpenGLContext *QOpenGLContext::shareContext() const

返回此上下文创建时的共享上下文。

如果底层平台不支持所请求的共享,则返回 0。

另请参阅 setShareContext()。

QOpenGLContextGroup *QOpenGLContext::shareGroup() const

返回此上下文所属的共享组。

[static] bool QOpenGLContext::supportsThreadedOpenGL()

如果平台支持主(gui)线程外的 OpenGL 渲染,则返回true

该值由所使用的平台插件控制,也可能取决于图形驱动程序。

QSurface *QOpenGLContext::surface() const

返回上下文当前使用的曲面。

这是作为makeCurrent() 的参数传递的曲面。

void QOpenGLContext::swapBuffers(QSurface *surface)

交换surface 的前后缓冲区。

调用该命令完成一帧 OpenGL 渲染,并确保在发出任何其他 OpenGL 命令(例如作为新帧的一部分)之前再次调用makeCurrent() 。

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.