先看一段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個屬性。