What are the Attribute locations for fixed functio

2019-01-05 06:04发布

I would like to know the attribute locations inside fixed pipeline (no shader attached) for nVidia OpenGL drivers:

glVertex = 0
glColor = 3
glNormal = ?
glTexCoord = ?
glMultiTexCoord 0..7 = ?
glSecondaryColor = ?
glFog = ?

Empirically I found the Vertex and primary Color locations but still will be nice to know them all.

If you want to know why, then for compatibility reasons and even for GLSL debugging (just to see if I pass the correct data to correct locations when shader not works yet) and so on ...

2条回答
别忘想泡老子
2楼-- · 2019-01-05 06:11

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;
}
查看更多
淡お忘
3楼-- · 2019-01-05 06:27

Outside of NVIDIA drivers, this does not work (reliably). Compliant drivers will only alias glVertexPointer (...) to attribute slot 0. NV in their infinite wisdom devised a standard non-standard scheme many years ago where they aliased all of the fixed-function pointers to certain attribute locations, but I do not know if new NV drivers support this (I honestly have never cared enough to try, it is such a bad practice). You might still be able to find NV's documentation for their alias mappings, but you are not benefiting anyone by taking advantage of their non-standard behavior.

While other drivers may also alias the fixed-function pointers to generic vertex attribute locations, no documentation exists for their mappings. Unlike NV, I would not trust that the mapping would not change between driver versions, hardware or platform. In fact, even using NV drivers you should not take advantage of this - it was intended to promote legacy support and not as a feature used for new software.

The bottom line is, use generic vertex attributes instead or use a compatibility profile and a version of GLSL that still supports the pre-declared variables that are specifically designed for getting fixed-function vertex data (e.g. gl_Color, gl_Normal, gl_MultiTexCoord0...7, ...). But do not mix-and-match both the way you are describing.

Also take some time to review glGetPointerv (...). If you want to get information about the fixed-function pointers outside of GLSL, this is the proper way to do it. Do not rely on vertex attribute aliasing, because the concept of attribute locations is fundamentally a programmable pipeline feature. It did not even exist in unextended OpenGL prior to 2.0 (it was introduced with the ARB Vertex Program assembly language and promoted into core with GLSL).


Update:

While I still strongly advise against using this information, I was able to find exactly what you wanted:

Release Notes for NVIDIA OpenGL Shading Language Support - November 9, 2006 - pp. 7-8

Vertex Attribute Aliasing

GLSL attempts to eliminate aliasing of vertex attributes but this is integral to NVIDIA’s hardware approach and necessary for maintaining compatibility with existing OpenGL applications that NVIDIA customers rely on.

NVIDIA’s GLSL implementation therefore does not allow built-in vertex attributes to collide with a generic vertex attributes that is assigned to a particular vertex attribute index with glBindAttribLocation. For example, you should not use gl_Normal (a built-in vertex attribute) and also use glBindAttribLocation to bind a generic vertex attribute named “whatever” to vertex attribute index 2 because gl_Normal aliases to index 2.

  Table excerpt

In case you were wondering, this is also outlined in Table X.1 of the ARB Vertex Program extension specification. The only reason I mentioned NV specifically is because they chose to re-use the aliasing in GLSL whereas compliant implementations from other vendors will only honor the first alias (glVertexPointer (...) to 0) in GLSL.

查看更多
登录 后发表回答