【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 小时前
在 Qt 中使用 QLabel 设置 GIF 动态背景
开发语言·qt·命令模式
只对您心动6 小时前
【QT】实现TCP服务器,客户端之间的通信
linux·服务器·c语言·开发语言·c++·qt·tcp/ip
Austim小白7 小时前
QT消息对话框学习
qt·学习
You can do more9 小时前
Qt Model/View之代理
qt
杨~friendship10 小时前
Ubuntu上使用qt和opencv显示图像
linux·开发语言·c++·qt·opencv·ubuntu
界面开发小八哥12 小时前
「Qt Widget中文示例指南」如何实现一个系统托盘图标?(二)
开发语言·c++·qt·用户界面
You can do more12 小时前
Qt Model/View之Model
qt
cat_fish_rain13 小时前
使用Qt 搭建简单雷达
开发语言·c++·qt
血不热了17 小时前
Qt:智能指针QScopedPointer 的使用(以及如何写一个QScopedPointer )
开发语言·qt
血不热了17 小时前
Qt:实现单例模式
qt·单例模式