opengl - 为什么有多种方法可以将 VAO 传递给 GLSL 程序?

标签 opengl glsl

示例代码:

1. glGenBuffers(1, &VboId);
2. glBindBuffer(GL_ARRAY_BUFFER, VboId);
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
5. glEnableVertexAttribArray(0);

所以第 4 行(第一个参数)和第 5 行的“0”指的是我们选择的任意标识符/位置。在 GLSL 中,如果我们想引用这些数据,我们只需要引用同一个 ID:
layout(location=0) in vec4 in_Position;

但是,在另一个示例程序中,我看到它的做法有所不同,没有提及“布局位置”。相反,我们这样做:
1. glGenBuffers(1, &VboId);
2. glBindBuffer(GL_ARRAY_BUFFER, VboId);
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
5. glBindAttribLocation(shaderProgramHandle, 0, "in_position");
6. glEnableVertexAttribArray(0);

我们添加了一个额外的步骤 (5),我们似乎将此属性指针绑定(bind)到特定程序中的特定变量。然后在我们的 GLSL 中,我们只是这样写:
in vec3 in_position;

没有引用位置。

如果我没记错的话,这两个程序本质上做的是完全相同的事情……那为什么会有区别呢?每种方法的优缺点是什么?

(我刚开始学习 OpenGL 3.x)

最佳答案

没有将 VAO 传递给着色器这样的事情。 VAO 只是建立了如何从缓冲区对象中提取顶点属性以进行渲染。

第二个例子什么也不做,除非shaderProgramHandle尚未链接。 glBindAttribLocation位置仅在程序链接之前有效。链接程序后,您无法更改它从何处获取属性。

无论如何,你真正的问题是为什么有些人使用 glBindAttribLocation(..., 0)而不是把 layout(location = X)在他们的着色器中。原因很简单:layout(location)语法是(相对)新的。 glBindAttribLocation可以追溯到 GLSL 的 OpenGL 接口(interface)的第一个版本,可以追溯到 2003 年左右的 ARB_vertex_shader 扩展。 layout(location)来自更新的 ARB_explicit_attrib_location,它只是 GL 3.3 及更高版本的核心。 3.3是2010年才出来的。所以自然更多的 Material 会讲老路。

每个人的“优点和缺点”都很明显。从纯粹实用的角度来看,layout(location)是新的,需要更新的驱动程序(尽管它不需要 GL 3.3。NVIDIA 的 6xxx+ 硬件支持 ARB_explicit_attrib_location 尽管只有 2.1)。 glBindAttribLocation在源代码中工作,而 layout(location)内置于 GLSL 着色器本身。因此,如果您需要决定哪些属性在运行时使用哪些索引,使用 layout(location) 会更难做到。比没有它。但是,如果像大多数人一样,您想从着色器中控制它们,那么 layout(location)是你需要的。

关于opengl - 为什么有多种方法可以将 VAO 传递给 GLSL 程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8691697/

相关文章:

opengl - 重用顶点属性缓冲区作为索引缓冲区?

c++ - 如何在 OpenGL 中旋转 gluCynlinder?

c++ - ffmpeg转OpenGL纹理黑屏

image-processing - 如何使用 OpenGL ES 2.0 着色器完成这些图像处理任务?

java - 着色器中使用的制服处于非 Activity 状态

浮点 gpgpu 的 opengl 纹理格式

c++ - 生成 GPU 粒子

opengl - 有没有办法运行 mesa 编译器来减少着色器文件的大小?

opengl - 将 vec3 乘以模型 View 矩阵

opengl-es - GLSL 优化 : check if variable is within range