OpenglES 2.0 顶点着色器属性
OpenglES 2.0 Vertex Shader Attributes
我在教程中读到顶点着色器所需的最低限度定义如下:
attribute vec3 v3_variable;
attribute vec3 v3Pos;
void main()
{
gl_Position = v3Pos;
}
OpenglES 将着色器顶点数据传递给v3Pos
但这个变量的名称实际上可以是任何名称,其他教程将其命名为a_Position
、a_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,则可能不适用于您的情况。另请注意,您可以同时使用这两种方法。例如。即使您明确定义布局,也不会限制您以后查询它们。
我在教程中读到顶点着色器所需的最低限度定义如下:
attribute vec3 v3_variable;
attribute vec3 v3Pos;
void main()
{
gl_Position = v3Pos;
}
OpenglES 将着色器顶点数据传递给v3Pos
但这个变量的名称实际上可以是任何名称,其他教程将其命名为a_Position
、a_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,则可能不适用于您的情况。另请注意,您可以同时使用这两种方法。例如。即使您明确定义布局,也不会限制您以后查询它们。