OpenglES 2.0 顶点着色器属性

OpenglES 2.0 Vertex Shader Attributes

我在教程中读到顶点着色器所需的最低限度定义如下:

attribute vec3 v3_variable;
attribute vec3 v3Pos;

void main()
{
    gl_Position = v3Pos;
}

OpenglES 将着色器顶点数据传递给v3Pos 但这个变量的名称实际上可以是任何名称,其他教程将其命名为a_Positiona_Pos,随便~。

所以我的问题是,OpenglES 如何知道当我调用 glVertexAttribPointer() 时它知道应该将数据放入 v3Pos 而不是 v3_variable

好的,所以在应用端,您将收到一个类似于

的调用
glBindAttribLocation(MyShader, 0, "v3Pos"); 

(在 link 着色器之前)或

vertexLoc = glGetAttribLocation(MyShader, "v3Pos");

在你 link 程序之后。

那么 glVertexAttribPointer 调用的第一个元素将为 0 或 vertexLoc。

glVertexAttribPointer(vertexLoc, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));

简而言之,gl linker 要么将 v3Pos 分配给它自己在内存中的位置,要么按照你告诉它的去做。无论哪种方式,您都必须与着色器执行一些交互才能与属性交互。

希望对您有所帮助

有两种方法可以识别着色器中的哪些属性获得 'paired' 以及您提供给 glVertexAttribPointer 的数据。使用 glVertexAttribPointer 获得的唯一标识符是 index(第一个参数),因此它必须以某种方式通过索引完成。

在第一种方法中,使用 glGetAttribLocation 编译和链接后从着色器中获取属性的索引,并将其用作第一个参数,例如

GLint program = ...;
GLint v3PosAttributeIndex = glGetAttribLocation(program, "v3Pos");
GLint v3varAttributeIndex = glGetAttribLocation(program, "v3_variable");
glVertexAttribPointer(v3PosAttributeIndex, ...);
glVertexAttribPointer(v3varAttributeIndex, ...);

您还可以在创作着色器时显式设置属性的布局(正如@j-p 的评论所建议的那样),因此您可以像这样修改您的着色器:

layout(location = 1) in vec3 v3_variable;
layout(location = 0) in vec3 v3Pos;

然后在代码中明确设置它们:

glVertexAttribPointer(0, ...); // v3Pos data
glVertexAttribPointer(1, ...); // v3_variable data

第二种方法仅适用于 GLES 3.0+(和 OpenGL 3.0+),因此如果您仅使用 GLES 2.0,则可能不适用于您的情况。另请注意,您可以同时使用这两种方法。例如。即使您明确定义布局,也不会限制您以后查询它们。