Opengl 为什么有多种方法可以将VAO传递给GLSL计划?

Opengl 为什么有多种方法可以将VAO传递给GLSL计划?,opengl,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); 所

示例代码:

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),在这个步骤中,我们似乎将这个属性指针绑定到特定程序中的特定变量。然后在我们的GLSL中,我们只写下以下内容:

in vec3 in_position;
没有提到一个位置

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


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

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

第二个示例没有任何作用,除非尚未链接
shaderProgramHandle
<代码>GLBindAttriblLocation位置仅在程序链接之前起作用。一旦程序被链接,就不能更改其属性的来源

在任何情况下,您真正的问题是为什么有些人使用
glBindAttribLocation(…,0)
而不是将
layout(location=X)
放在着色器中。原因很简单:
layout(location)
语法是(相对)新的
glBindAttribLocation
可以追溯到GLSL的OpenGL接口的第一个版本,可以追溯到2003年左右的ARB_vertex_着色器扩展中<代码>布局(位置)来自更新的ARB_explicit_attrib_位置,它是GL 3.3及以上版本中唯一的核心。3.3仅在2010年发布。因此,自然会有更多的材料谈论旧方法


每种方法的“利弊”都是显而易见的。从纯实用的角度来看,
布局(位置)
是新的,需要更新的驱动程序(尽管它不需要GL 3.3。NVIDIA的6xxx+硬件支持ARB_explicit_attrib_location,尽管只有2.1)
glbindattiblocation
在源代码中工作,而
layout(location)
内置于GLSL着色器本身。因此,如果您需要决定哪些属性在运行时使用哪些索引,那么使用
layout(location)
比不使用它要困难得多。但是,如果像大多数人一样,你想从着色器控制它们,那么
布局(位置)
就是你所需要的。

这很奇怪……因为我有一个正在运行的程序可以做到这一点。它与上面的不完全一样(它是一个C#包装器),但在调用GLBindAttriblLocation之前它肯定会链接程序。如果
layout(location)
是一种新的做事方式,我想我会继续这样做,直到遇到一个让我信服的障碍。谢谢。@Mark:函数什么都不做并不意味着你就不会走运。如果你不使用
布局(位置)
glBindAttribLocation
,那么OpenGL会自动分配它认为合适的属性索引。哈哈哈……你真是个天才!我刚刚打电话给glBindAttribLocation,它运行的完全一样。也许我应该联系OpenTK的人员,因为这就是他们的库附带的示例+2征求意见。很有启发性。特别是“仅仅因为一个函数什么都不做并不意味着你就不走运”。关于这个答案的快速问题,为什么大多数人想从着色器控制它们?在我看来,如果您在着色器中这样定义它们,您仍然需要知道glvertexattributepointer的C代码中的硬编码位置。为什么不在一个地方定义它,然后用它来完成呢?我肯定我错过了什么。谢谢