OpenGL 4.0 ++核心配置文件中固定功能管道的属性位置是什么?

Spe*_*tre 2 opengl opengl-4 vao

我想知道nVidia OpenGL驱动程序中固定管道(没有连接着色器)内的属性位置:

glVertex = 0
glColor = 3
glNormal = ?
glTexCoord = ?
glMultiTexCoord 0..7 = ?
glSecondaryColor = ?
glFog = ?
Run Code Online (Sandbox Code Playgroud)

根据经验,我找到了顶点和主要颜色位置,但仍然很高兴知道它们.

如果你想知道原因,那么出于兼容性的原因,甚至是GLSL调试(只是为了看看我是否在着色器不能正常工作时将正确的数据传递到正确的位置)等等......

And*_*man 12

在NVIDIA驱动程序之外,这不起作用(可靠).兼容的驱动程序将只glVertexPointer (...)对属性插槽0进行别名.多年前,NV以其无限的智慧设计了一个标准的非标准方案,他们将所有固定功能指针别名化到某些属性位置,但我不知道新的NV驱动程序是否支持这一点(老实说,我从未关心过这个问题) ,这是一个不好的做法).您可能仍然可以找到NV的别名映射文档,但您不会利用其非标准行为从中受益.

虽然其他驱动程序也可能将固定函数指针别名为通用顶点属性位置,但其映射不存在任何文档.与NV不同,我不相信映射不会在驱动程序版本,硬件或平台之间发生变化.实际上,即使使用NV驱动程序,也不应该利用这一点 - 它旨在促进传统支持,而不是用作新软件的功能.

底线是,改用通用顶点属性或使用相容性分布和版本GLSL的是还支持专门为获取固定功能顶点数据设计了预先声明的变量(例如gl_Color,gl_Normal,gl_MultiTexCoord0...7,...).但是不要混淆和匹配你描述的方式.

还需要一些时间来审查glGetPointerv (...).如果你想获得有关GLSL之外的固定函数指针的信息,这是正确的方法.不要依赖顶点属性别名,因为属性位置的概念基本上是可编程管道功能.它甚至不存在于2.0之前的未扩展OpenGL中(它随ARB顶点程序汇编语言一起引入并通过GLSL升级为核心).


更新:

虽然我仍然强烈建议不要使用这些信息,但我能够找到你想要的确切内容:

NVIDIA OpenGL着色语言支持发行说明 - 200611月9日 - 第7-8页

顶点属性别名

GLSL试图消除顶点属性的混叠,但这对于NVIDIA的硬件方法是不可或缺的,并且是维持与NVIDIA客户所依赖的现有OpenGL应用程序的兼容性所必需的.

因此,NVIDIA的GLSL实现不允许内置顶点属性与使用glBindAttribLocation分配给特定顶点属性索引的通用顶点属性冲突.例如,您不应该使用gl_Normal(内置顶点属性)并使用glBindAttribLocation将名为"whatever"的通用顶点属性绑定到顶点属性索引2,因为gl_Normal别名为索引2.

  表格摘录

如果您想知道,ARB Vertex Program扩展规范的表X.1中也对此进行了概述.我特别提到NV的唯一原因是因为他们选择在GLSL中重复使用别名,而其他供应商的兼容实现只会尊重GLSL中的第一个别名(glVertexPointer (...)0).


Rab*_*d76 7

我将此答案从重复和删除的问题使用顶点属性索引 0,而不是固定功能属性 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, ...    |
| ...               |                          |                                |
Run Code Online (Sandbox Code Playgroud)

这意味着顶点属性0和固定函数属性之间存在“映射” GL_VERTEX_ARRAY,但不一定是任何其他顶点属性的映射。


Nvidia 在NVIDIA OpenGL 着色语言支持的发行说明中领先一步;2006 年 11 月 9 日;- 第 7-8 页
固定函数属性和顶点属性索引之间存在实际映射,如上表所示。
另请参阅答案OpenGL 4.0++ 核心配置文件中固定功能管道的属性位置是什么?

我做了一些测试,得出的结果是,以下代码在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
};
Run Code Online (Sandbox Code Playgroud)

glBegin可以在没有任何着色器的情况下按/glEnd序列绘制,

glBegin( GL_TRIANGLES );
for ( int j=0; j < 3; ++j )
{
    glVertex2fv( varray + j*6 );
    glColor4fv( varray + j*6 + 2 );
}
glEnd();
Run Code Online (Sandbox Code Playgroud)

通过指定固定功能属性,

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 );
Run Code Online (Sandbox Code Playgroud)

并指定索引为 0 和 3 的通用顶点属性数组,其中 对应于Nvidia 硬件的固定函数属性GL_VERTEX_ARRAY和:GL_COLOR_ARRAY

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 );
Run Code Online (Sandbox Code Playgroud)


通过使用以下 OpenGL 2.0 着色器程序,将运行相同的代码,

顶点着色器

#version 110

varying vec4 vertCol;

void main()
{
    vertCol     = gl_Color;
    gl_Position = gl_Vertex;
}
Run Code Online (Sandbox Code Playgroud)

或以下 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);
}
Run Code Online (Sandbox Code Playgroud)

片段着色器巫婆在上述两种情况下都有效(为了完整性):

#version 400

in vec4 vertCol;

out vec4 fragColor;

void main()
{
    fragColor = vertCol;
}
Run Code Online (Sandbox Code Playgroud)