先看一段vertex shader
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
ourColor = aColor;
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
当我们在调用shader之前,会声明vertex的attribPointer,实际上就是告诉显卡,这个vertex的内存布局
location=xxx,这个东东叫vertex attribute index
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 0);
GL.EnableVertexAttribArray(0);
GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 3 * sizeof(float));
GL.EnableVertexAttribArray(1);
GL.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), 6 * sizeof(float));
GL.EnableVertexAttribArray(2);
三次调用GL.VertexAttribPointer的第一个参数,0,1,2,就是location
那么,能不能不按照递增顺序写呢?比如,第一个改成5,怎么样?
答案是,可以。
如果shader里这样写:(省略后半部分shader)
#version 330 core
layout (location = 5) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;
那么描述aPos的代码,就应该这样改:
GL.VertexAttribPointer(5, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), 0);
GL.EnableVertexAttribArray(5);
把vertex attribute index,都修改为5.
那么,最大的vertex attribute index是多少呢?可以通过一个函数来查询:
int maxVertexAttrib = GL.GetInteger(GetPName.MaxVertexAttribs);
我的显卡是gt 1030,这个值是16。
看官方文档,描述如下:
GL_MAX_VERTEX_ATTRIBS
data
returns one value, the maximum number of 4-component generic vertex attributes accessible to a vertex shader. The value must be at least 16. See glVertexAttrib.
官方文档规定的最小值就是16。显卡也就只实现了16个。实际上也够用了,平时也就是位置法线纹理切线负切线。
也就是说,一般情况下,顶点可以有最多16个属性。