Каковы местоположения атрибутов для конвейера с фиксированными функциями в профиле ядра OpenGL 4.0++?

Я хотел бы знать расположение атрибутов внутри фиксированного конвейера (без шейдеров) для драйверов nVidia OpenGL:

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

Опытным путем я нашел места расположения вершин и основных цветов, но все же будет приятно узнать их все.

Если вы хотите знать почему, то по причинам совместимости и даже для отладки GLSL (просто чтобы посмотреть, передам ли я правильные данные в правильные местоположения, когда шейдер еще не работает) и так далее...

2 ответа

Решение

Вне драйверов NVIDIA это не работает (надежно). Совместимые драйверы будут только псевдонимами glVertexPointer (...) приписать слот 0. Н. В. в своей бесконечной мудрости разработал стандартную нестандартную схему много лет назад, где они связали все указатели с фиксированными функциями для определенных местоположений атрибутов, но я не знаю, поддерживают ли это новые драйверы NV (я, честно говоря, никогда не заботился настолько, чтобы попытаться Это такая плохая практика). Возможно, вы по-прежнему сможете найти документацию NV для их сопоставлений псевдонимов, но вы никому не поможете, воспользовавшись их нестандартным поведением.

В то время как другие драйверы могут также связывать указатели фиксированной функции с общими местоположениями атрибутов вершин, для их отображений не существует документации. В отличие от NV, я бы не поверил, что отображение не изменится между версиями драйверов, аппаратными средствами или платформой. На самом деле, даже используя драйверы NV, вы не должны этим пользоваться - он был предназначен для поддержки устаревшей поддержки, а не как функция, используемая для нового программного обеспечения.

Суть в том, что вместо этого используйте общие атрибуты вершин или используйте профиль совместимости и версию GLSL, которая по-прежнему поддерживает предварительно объявленные переменные, которые специально предназначены для получения данных вершин с фиксированной функцией (например, gl_Color, gl_Normal, gl_MultiTexCoord0...7...) Но не смешивайте и сочетайте то, что вы описываете.

Также найдите время, чтобы рассмотреть glGetPointerv (...), Если вы хотите получить информацию об указателях с фиксированной функцией вне GLSL, это правильный способ сделать это. Не полагайтесь на псевдонимы атрибутов вершин, потому что концепция расположения атрибутов по сути является программируемой функцией конвейера. Он даже не существовал в расширенном OpenGL до 2.0 (он был представлен на языке ассемблера ARB Vertex Program и был переведен в ядро ​​с помощью GLSL).


Обновить:

Хотя я все еще настоятельно рекомендую не использовать эту информацию, я смог найти именно то, что вы хотели:

Замечания к выпуску поддержки языка затенения NVIDIA OpenGL - 9 ноября 2006 г. - стр. 7-8

Взаимосвязь атрибутов вершин

GLSL пытается исключить наложение атрибутов вершин, но это является неотъемлемой частью аппаратного подхода NVIDIA и необходимо для обеспечения совместимости с существующими приложениями OpenGL, на которые полагаются клиенты NVIDIA.

Поэтому реализация NVIDIA GLSL не позволяет встроенным атрибутам вершин сталкиваться с общими атрибутами вершин, которые назначаются определенному индексу атрибутов вершин с помощью glBindAttribLocation. Например, вы не должны использовать gl_Normal (встроенный атрибут вершины), а также использовать glBindAttribLocation для привязки общего атрибута вершины с именем "что угодно" к атрибуту вершины с индексом 2, потому что псевдоним gl_Normal к индексу 2.

Выдержка из таблицы

Если вам интересно, это также описано в Таблице X.1 спецификации расширения ARB Vertex Program. Единственная причина, по которой я упомянул NV, заключается в том, что они решили повторно использовать псевдонимы в GLSL, тогда как совместимые реализации других поставщиков будут учитывать только первый псевдоним (glVertexPointer (...) до 0) в GLSL.

Я переместил этот ответ из дубликата и удаленного вопроса, используя индекс атрибута вершины 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, ...    |
| ...               |                          |                                |

Это означает, что существует "отображение" между атрибутом вершины 0 и атрибутом фиксированной функции GL_VERTEX_ARRAY, но не обязательно отображение для любого другого атрибута вершины.


Nvidia идет на шаг вперед, как указано в Примечаниях к выпуску для поддержки языка шейдеров NVIDIA OpenGL; 9 ноября 2006 г.; - с. 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
};

может быть нарисован без какого-либо шейдера, 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);
}

Шейдер Fragment работает в обоих вышеперечисленных случаях (для полноты картины):

#version 400

in vec4 vertCol;

out vec4 fragColor;

void main()
{
    fragColor = vertCol;
}
Другие вопросы по тегам