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

Why are shaders and programs stored as integers in OpenGL?

本文关键字:OpenGL 存储 整数 程序 为什么      更新时间:2023-10-16

我正在阅读"OpenGL Superbible"一书,我忍不住注意到,当我们创建着色器并创建将着色器附加到的程序时,我们将它们存储为GLuint,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调用的情况下访问句柄后面的内容。

来自维基百科:

在计算机程序设计中,句柄是对资源的抽象引用。[…]资源句柄可以是不透明的标识符,在这种情况下,它们通常是整数,也可以是允许访问进一步信息的指针。

数字的值没有任何意义,0除外,它的意思是"没有对象"。

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

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

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

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

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