为什么着色器和程序在 OpenGL 中存储为整数?

Why are shaders and programs stored as integers in OpenGL?

我正在关注 "OpenGL Superbible" 这本书,但我不禁注意到,当我们创建着色器并创建将着色器附加到的程序时,我们将它们存储为 GLuint,它们是无符号整数.

为什么它们存储为数字?数字的值是什么意思?

示例:

GLuint vertex_shader;
GLuint fragment_shader;
GLuint program;

// Create and compile vertex shader
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
glCompileShader(vertex_shader);

// Create program, attach shaders to it, and link it
program = glCreateProgram();
glAttachShader(program, vertex_shader);
glLinkProgram(program);

这些整数是 句柄。这是许多 API 常用的习惯用法,用于通过不透明的间接级别隐藏资源访问。 OpenGL 有效地阻止您在不使用 API 调用的情况下访问句柄后面的内容。

From Wikipedia:

In computer programming, a handle is an abstract reference to a resource. [...] Resource handles can be opaque identifiers, in which case they are often integer numbers, or they can be pointers that allow access to further information.

数字的值没有任何意义,除了 0,它表示 "no object"。

这些值是在您进行 glGen*()glCreate*() 类型调用时由驱动程序生成的。它们是对对象的不透明引用。你可以想象驱动程序在这些数字和相应的内部对象之间维护一个映射。每次将数字作为参数传递给 API 调用时,例如glBind*(),驱动程序会查找这个数字,并将其映射回相应的内部对象。

从语义上讲,这很像 C/C++ 中的指针。当你分配内存时,你会得到一个指针。你可以使用这个指针来引用你分配的内存。除了在 OpenGL 的情况下,您不会获得原始内存地址,而是引用对象的不透明表示。

其他 API 中使用了相同的概念。例如,Windows (Win32) 广泛使用不透明对象引用,他们称之为 "handles".

现在您可能想知道为什么 OpenGL 不简单地使用指针而不是这些对象 ID。这只是我个人的看法,但我相信主要动机是 OpenGL 被设计为 client/server API,其中渲染可以发生在与应用程序 运行 不同的机器上。如果 API 流必须打包并通过网络发送,使用指向引用对象的指针并不容易。在这种情况下,使用不透明的 ID 会干净得多。

顺便说一句,在 OpenGL 官方术语中,这些值大多称为 "names"。我总是觉得这有点误导,因为大多数人在听到 "name" 时都会想到字符串。我自己大多称他们为 "ids"。