我将这个答案从重复和删除的问题Using vertex attribute index 0, instead of Fixed-Function attribute GL_VERTEX_ARRAY移到了这里。
如果 OpenGL 扩展ARB_vertex_program; Modify Section 2.7, Vertex Specification
有效,则固定函数属性和属性索引之间存在映射:
设置通用顶点属性零指定一个顶点;四个顶点坐标取自属性零的值。
Vertex2、Vertex3 或 Vertex4 命令完全等同于索引为零的相应 VertexAttrib 命令。设置任何其他通用顶点属性会更新属性的当前值。顶点属性零没有当前值。
实现可以但不一定对通用和某些常规顶点属性的当前值使用相同的存储。当指定除零以外的任何通用顶点属性时,表 X.1 中相应常规属性的当前值将变为未定义。此外,当指定常规顶点属性时,表 X.1 中相应通用顶点属性的当前值将变为未定义。例如,设置当前法线将使通用顶点属性 2 未定义,反之亦然。
| Generic Attribute | Conventional Attribute | Conventional Attribute Command |
|-------------------|--------------------------|--------------------------------|
| 0 | vertex position | Vertex |
| 1 | vertex weights 0-3 | WeightARB, VertexWeightEXT |
| 2 | normal | Normal |
| 3 | primary color | Color |
| 4 | secondary color | SecondaryColorEXT |
| 5 | fog coordinate | FogCoordEXT |
| 6 | - | - |
| 7 | - | - |
| 8 | texture coordinate set 0 | MultiTexCoord(TEXTURE0, ... |
| ... | | |
这意味着顶点属性0和固定函数属性之间存在“映射” GL_VERTEX_ARRAY
,但不一定是任何其他顶点属性的映射。
Nvidia 比NVIDIA OpenGL 着色语言支持发行说明中的规定领先一步;2006 年 11 月 9 日;- 第 7-8 页。
如上表所示,固定函数属性和顶点属性索引之间存在实际映射。
另请参阅OpenGL 4.0++ 核心配置文件中固定功能管道的属性位置是什么?
我做了一些测试并得出结果,以下 cod 在Nvidia GeForce 940MX上运行,但无法在集成Intel(R) HD Graphics 620上运行。
三角形指定如下
static const float varray[]
{
// x y red green blue alpha
-0.707f, -0.75f, 1.0f, 0.0f, 0.0f, 1.0f,
0.707f, -0.75f, 1.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.75f, 0.0f, 0.0f, 1.0f, 1.0f
};
可以在没有任何着色器的情况下按glBegin
/glEnd
序列绘制,
glBegin( GL_TRIANGLES );
for ( int j=0; j < 3; ++j )
{
glVertex2fv( varray + j*6 );
glColor4fv( varray + j*6 + 2 );
}
glEnd();
通过指定固定函数属性,
glVertexPointer( 2, GL_FLOAT, 6*sizeof(*varray), varray );
glColorPointer( 4, GL_FLOAT, 6*sizeof(*varray), varray+2 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
glDrawArrays( GL_TRIANGLES, 0, 3 );
glDisableClientState( GL_VERTEX_ARRAY );
glDisableClientState( GL_COLOR_ARRAY );
并指定索引为 0 和 3 的通用顶点属性数组,其中对应于固定函数属性GL_VERTEX_ARRAY
和GL_COLOR_ARRAY
,对于 Nvidia 硬件:
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 6*sizeof(*varray), varray );
glVertexAttribPointer( 3, 4, GL_FLOAT, GL_FALSE, 6*sizeof(*varray), varray+2 );
glEnableVertexAttribArray( 0 );
glEnableVertexAttribArray( 3 );
glDrawArrays( GL_TRIANGLES, 0, 3 );
glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 3 );
通过使用以下 OpenGL 2.0 着色器程序,将运行相同的代码,
顶点着色器
#version 110
varying vec4 vertCol;
void main()
{
vertCol = gl_Color;
gl_Position = gl_Vertex;
}
或以下 OpenGL 4.0 着色器程序:
顶点着色器
#version 400
layout (location = 0) in vec3 inPos;
layout (location = 3) in vec4 inColor;
out vec4 vertCol;
void main()
{
vertCol = inColor;
gl_Position = vec4(inPos, 1.0);
}
片段着色器女巫在上述两种情况下都有效(为了完整起见):
#version 400
in vec4 vertCol;
out vec4 fragColor;
void main()
{
fragColor = vertCol;
}