【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会负责处理所有底层的切换逻辑。

相关推荐
徒步僧4 小时前
ThingsBoard规则链节点:RPC Call Reply节点详解
qt·microsoft·rpc
可峰科技5 小时前
斗破QT编程入门系列之一:认识Qt:初步使用(四星斗师)
开发语言·qt
我喜欢就喜欢5 小时前
基于qt vs下的视频播放
开发语言·qt·音视频
CP-DD6 小时前
Qt的架构设计
qt
阿_旭6 小时前
基于YOLO11/v10/v8/v5深度学习的维修工具检测识别系统设计与实现【python源码+Pyqt5界面+数据集+训练代码】
人工智能·python·深度学习·qt·ai
Bruce小鬼11 小时前
QT创建按钮篇
开发语言·qt
martian66512 小时前
QT开发:掌握现代UI动画技术:深入解析QML和Qt Quick中的动画效果
开发语言·c++·qt·ui
墨染新瑞14 小时前
两个有趣的小东西(qt和类型转换)
开发语言·网络·qt
Bruce小鬼15 小时前
解决MAC安装QT启动项目不显示窗口问题
开发语言·qt·macos
云雨歇18 小时前
Qt学习笔记(三)网络编程
笔记·qt·学习