【OpenGL】 理解makeCurrent函数

背景

用QT学校OpenGL绝对可以事半功倍,QT提供了一系列对OpenGL的支持,包括OPenGL窗口类,对OpenGL函数的面向对象的封装等。

总体说明

在Qt框架中,makeCurrentQOpenGLContext类的一个方法,它封装了这些平台特定的调用,提供了一个跨平台的接口来管理OpenGL上下文。makeCurrent函数的作用是将一个特定的OpenGL上下文(context)设置为当前线程的渲染上下文。这意味着,当你调用OpenGL函数进行绘制时,这些函数将操作这个指定的上下文。每个OpenGL上下文包含了一整套OpenGL的状态信息,比如纹理绑定、帧缓冲对象(FBO)的配置等。

当你创建一个OpenGL窗口或帧缓冲对象时,通常会与一个上下文对象关联。在进行绘制之前,你需要通过makeCurrent函数来激活这个上下文,这样OpenGL的命令就会作用于这个上下文。在Qt中,如果你继承了QOpenGLWidget并重写了initializeGLresizeGLpaintGL函数,那么在这些函数中你不需要手动调用makeCurrent,因为这些函数被调用时,Qt会自动将你的QOpenGLWidget的上下文设置为当前上下文。

在某些情况下,如果你需要在这些虚函数之外的地方进行OpenGL绘制,那么你需要手动调用makeCurrent来激活上下文。例如,在QOpenGLWidget的构造函数或析构函数中,如果你需要创建或销毁OpenGL资源,你应该首先调用makeCurrent,然后进行资源的创建或销毁,最后调用doneCurrent来释放当前的上下文。

在多线程环境中,每个线程可以有自己的当前上下文,但是一个上下文在同一时间只能被一个线程设置为当前。如果你尝试在不同的线程中使用同一个上下文,可能会导致不可预测的行为或程序崩溃。

总结来说,makeCurrent函数是OpenGL编程中用于管理上下文状态的关键函数,它确保了OpenGL命令能够正确地应用于你想要操作的特定上下文。

makeCurrent 如何实上下文现切换?

这个上下文应该指的就是线程中,声明的一些变量。QT的 QOpenGLWidget并重写了initializeGLresizeGLpaintGL函数,本身就是在当前的创建的OpenGL线程里面, 所以,不存在切换。

但是,如果你在其他地方调用OpenGL的函数。就是在其他线程里面,

上下文就不一样(不是同一个线程)。你需要将QOpenGLWidget的上下文通过moveToThread转移到该线程,并手动调用makeCurrent()和doneCurrent()来管理上下文的当前状态。

我觉得理解到这里,就可以了,就不会觉得调用这个函数奇怪了。


当然你还想继续探究,可以看看下面这段总结:

makeCurrent 函数的实现细节依赖于操作系统和OpenGL的实现,但通常它涉及到以下几个步骤:

  1. 激活上下文makeCurrent 函数首先会激活(或"使当前")一个特定的OpenGL上下文。这通常涉及到与操作系统的API调用,以确保所有后续的OpenGL命令都指向这个上下文。

  2. 线程局部存储 :OpenGL上下文通常与一个线程关联。makeCurrent 可能会使用线程局部存储(Thread Local Storage, TLS)来存储当前线程的OpenGL上下文指针。这样,当OpenGL命令被调用时,它们可以查找TLS来找到当前激活的上下文。

  3. 资源绑定:在上下文被激活后,所有与之前上下文相关的资源绑定(如纹理、缓冲区、帧缓冲等)都会被解绑,以便新的上下文可以绑定它自己的资源。

  4. 状态切换:操作系统或OpenGL的实现会负责更新内部状态,以确保OpenGL的状态机反映了新上下文的状态。这可能包括切换GPU的渲染目标、更新GPU的管线状态等。

  5. 错误处理 :如果尝试激活的上下文无效或与当前线程不兼容,makeCurrent 函数会返回错误。在某些实现中,这可能涉及到检查上下文是否已经与另一个线程绑定,或者是否与当前的设备上下文(如Windows中的HDC)不匹配。

在不同的平台上,makeCurrent 函数的具体实现可能会有所不同:

  • Windows :在Windows平台上,makeCurrent 可能会调用Win32 API wglMakeCurrent,它接受一个设备上下文(HDC)和一个渲染上下文(HGLRC)作为参数。

  • macOS :在macOS上,makeCurrent 可能会使用NSOpenGL API,如[NSOpenGLContext makeCurrentContext:]

  • Linux/X11 :在Linux上,可能会使用GLX API,如glXMakeCurrent

  • EGL :对于使用EGL的嵌入式系统或某些现代OpenGL ES实现,makeCurrent 可能会调用eglMakeCurrent,它接受显示(EGLDisplay)、绘制表面(EGLSurface)和上下文(EGLContext)作为参数。

在Qt框架中,makeCurrentQOpenGLContext类的一个方法,它封装了这些平台特定的调用,提供了一个跨平台的接口来管理OpenGL上下文。当你调用makeCurrent时,Qt会负责处理所有底层的切换逻辑。

相关推荐
闲暇部落3 小时前
Android OpenGL ES详解——绘制圆角矩形
opengl·圆形·矩形·圆角矩形
----云烟----8 小时前
QT中QString类的各种使用
开发语言·qt
「QT(C++)开发工程师」14 小时前
【qt版本概述】
开发语言·qt
一路冰雨17 小时前
Qt打开文件对话框选择文件之后弹出两次
开发语言·qt
老赵的博客18 小时前
QT 自定义界面布局要诀
开发语言·qt
码码哈哈0.019 小时前
VSCode 2022 离线安装插件QT VSTOOl报错此扩展不能安装在任何当前安装的产品上。
ide·vscode·qt
feiyangqingyun1 天前
Qt/C++离线地图的加载和交互/可以离线使用/百度和天地图离线/支持手机上运行
c++·qt·qt天地图·qt离线地图·qt地图导航
凌云行者1 天前
OpenGL入门008——环境光在片段着色器中的应用
c++·cmake·opengl
gz94562 天前
windows下,用CMake编译qt项目,出现错误By not providing “FindQt5.cmake“...
开发语言·qt
「QT(C++)开发工程师」2 天前
Ubuntu 26.04 LTS 大升级:Qt 6 成为未来新引擎
qt