I moved this answer from the duplicate and deleted question Using vertex attribute index 0, instead of Fixed-Function attribute GL_VERTEX_ARRAY to here.
If the OpenGL extension ARB_vertex_program; Modify Section 2.7, Vertex Specification
is valid,
then there is a mapping between Fixed function attributes and attribute indices:
Setting generic vertex attribute zero specifies a vertex; the four vertex coordinates are taken from the values of attribute zero.
A Vertex2, Vertex3, or Vertex4 command is completely equivalent to the corresponding VertexAttrib command with an index of zero.
Setting any other generic vertex attribute updates the current values of the attribute.
There are no current values for vertex attribute zero.
Implementations may, but do not necessarily, use the same storage for the current values of generic and certain conventional vertex attributes.
When any generic vertex attribute other than zero is specified, the current values for the corresponding conventional attribute in Table X.1 become undefined.
Additionally, when a conventional vertex attribute is specified, the current values for the corresponding generic vertex attribute in Table X.1 become undefined.
For example, setting the current normal will leave generic vertex attribute 2 undefined, and vice versa.
| 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, ... |
| ... | | |
This means there is a "mapping" between vertex attribute 0 and the fixed function attribute GL_VERTEX_ARRAY
, but not necessarily a mapping for any other vertex attribute.
Nvidia goes a step ahead as specified in Release Notes for NVIDIA OpenGL Shading Language Support; November 9, 2006; - pp. 7-8.
There is an actual mapping between the fixed function attributes and vertex attribute indices, as specified in the table above.
See also the answer to What are the Attribute locations for fixed function pipeline in OpenGL 4.0++ core profile?
I did some test and came to the result, that the following cod runs on Nvidia GeForce 940MX, but fails to run on integrated Intel(R) HD Graphics 620.
The triangle specified as follows
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
};
can be drawn without any shader, by glBegin
/glEnd
sequence,
glBegin( GL_TRIANGLES );
for ( int j=0; j < 3; ++j )
{
glVertex2fv( varray + j*6 );
glColor4fv( varray + j*6 + 2 );
}
glEnd();
by specifying Fixed Function attributes,
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 );
and specifying the array of generic vertex attributes with the indices 0 and 3, with are corresponding to the fixed function attributes GL_VERTEX_ARRAY
and GL_COLOR_ARRAY
, for Nvidia hardware:
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 );
The same code will run, by using the following OpenGL 2.0 shader program,
Vertex shader
#version 110
varying vec4 vertCol;
void main()
{
vertCol = gl_Color;
gl_Position = gl_Vertex;
}
or the following OpenGL 4.0 shader program:
Vertex shader
#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);
}
The Fragment shader witch works in both of the above cases (for sake of completeness):
#version 400
in vec4 vertCol;
out vec4 fragColor;
void main()
{
fragColor = vertCol;
}