关于 OpenGL 的渲染上下文

OpenGL 的上下文(OpenGL context)是一个 OpenGL 绘图环境的抽象概念,它包括了所有 OpenGL 状态信息和资源,以便OpenGL能够正确地渲染图形。

OpenGL 上下文

OpenGL 的上下文(OpenGL context)是一个 OpenGL 绘图环境的抽象概念,它包括了所有 OpenGL 状态信息和资源,以便OpenGL能够正确地渲染图形。

OpenGL 在渲染的时候需要一个 Context 来记录了 OpenGL 渲染需要的所有信息和状态,可以把它理解成一个大的结构体,它里面记录了当前使用 OpenGL 函数调用设置的状态和状态属性。

OpenGL 是个状态机,OpenGL采用了客户端-服务器模式,我们可以认为每一个硬件 GPU 相当于一台服务器,可对应多个客户端即上下文,一个客户端维护着一组状态机。

大部分的 OpenGL 命令都是异步的,不代表真正地执行,只是客户端向服务器发送了一些命令(同时有一些API可实现同步功能)。

申请绘制上下文,意味着系统资源的申请,每个绘制上下文还是需要不少资源的,所有的OpenGL 调用,都需要指定是在哪个上下文环境下调用的。

渲染上下文和线程

OpenGL 的绘制命令都是作用在当前的 Context 上,上下文是线程私有的,可以为同一个线程创建多个上下文,但是一次只能指定一个。

多个线程不能同时指定同一个 Context ,否则会导致崩溃。当有需要多个并行的绘制任务时,则要创建多个 Context,为并行的线程分别绑定不同的上下文。

可以通过共享上下文的方式为别的线程创建上下文,这些线程之间可以共享一部分资源。

共享上下文

一个是进程可以创建多个 Context,它们可以分别描绘出不同的图形界面,就像一个应用程序可以打开多个窗口一样。每个 OpenGL Context 是相互独立的,它们都有自己的 OpenGL 对象集。

但有时会有场景需要多个上下文使用同一份纹理资源的情况,创建 Context,意味着系统资源的占用,同一份纹理重复申请会造成资源浪费,因此 OpenGL 上下文允许共享一部分资源。

大部分 OpenGL Objects 是可以共享的,包括 Sync Object 和 GLSL Objects。

Container Objects 和 Query Objects 是不能共享的。例如纹理、shader、Buffer 等资源是可以共享的,但 Frame Buffer Object (FBO)、Vertex Array Object(VAO)等容器对象不可共享,但可将共享的纹理和 VBO 绑定到各自上下文的容器对象上。

可以共享的资源:

  • 纹理;
  • shader;
  • program 着色器程序;
  • buffer 类对象,如 VBO、 EBO、 RBO 等 。

不可以共享的资源:

  • FBO 帧缓冲区对象(不属于 buffer 类);
  • VAO 顶点数组对象(不属于 buffer 类)。

这里解释下,在不可以共享的资源中,FBO 和 VAO 属于资源管理型对象,FBO 负责管理几种缓冲区,本身不占用资源,VAO 负责管理 VBO 或 EBO ,本身也不占用资源。

参考文章


手机扫码阅读