OpenglES 2.0顶点着色器属性

OpenglES 2.0 Vertex Shader Attributes

本文关键字:属性 顶点 OpenglES      更新时间:2023-10-16

我在教程中读到,最低顶点着色器需要定义如下:

attribute vec3 v3_variable;
attribute vec3 v3Pos;
void main()
{
    gl_Position = v3Pos;
}

OpenglES将着色器顶点数据传递给v3Pos,但这个变量的名称实际上可以是任何东西,其他教程将其命名为a_Position, a_Pos,无论什么~。

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

有两种方法来确定您的着色器中哪些属性与您提供给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

第二种方法只适用于gles3.0 +(和opengl3.0 +),所以如果你只使用gles2.0,它可能不适用于你的情况。另外,请注意,您可以同时使用这两种方法。如。即使您显式地定义了布局,也不会限制您以后查询它们。

好的,那么在应用程序端你将有一个调用看起来像

glBindAttribLocation(MyShader, 0, "v3Pos"); 

(在你链接着色器之前)或

vertexLoc = glGetAttribLocation(MyShader, "v3Pos");

链接程序后。

那么调用glVertexAttribPointer的第一个元素要么为0,要么为vertexLoc。

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

简而言之,gl链接器要么将v3Pos分配给它自己在内存中的位置,要么执行您告诉它的操作。无论哪种方式,你都必须与着色器进行一些交互,以便与属性进行交互。

希望有帮助