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

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code bean

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值