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

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

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

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

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


person Spektre    schedule 13.12.2013    source источник
comment
Вам нужно получить к ним доступ в GLSL, используя gl_Vertex, gl_Color и т. Д. У них нет местоположений атрибутов. Хотя вам больше не следует их использовать. Если вы уже используете шейдеры, то почему бы не создать свои собственные атрибуты и униформу, КАК ВАШЕ ПРЕДЛОЖЕНИЕ.   -  person vallentin    schedule 13.12.2013
comment
вы неправильно поняли, что у меня есть модель в VAO, и я хочу настроить местоположения VAO, чтобы они были совместимы с фиксированным конвейером (без GLSL)   -  person Spektre    schedule 13.12.2013
comment
Они не должны работать вместе.   -  person vallentin    schedule 13.12.2013
comment
но они ... не берем берег, если на каком-либо HW, но похоже, что они делают. Я могу найти текстуру и нормали, но остальное я не знаю, как   -  person Spektre    schedule 13.12.2013
comment
Они могут это сделать, но вы должны это делать не так. Вам следует избегать использования чего-либо из конвейера фиксированных функций.   -  person vallentin    schedule 13.12.2013
comment
Я знаю, что это только для тестирования, а не для выходного кода. Я сильно использую GLSL там, где могу   -  person Spektre    schedule 13.12.2013
comment
Что ж, не смешивайте старое с новым, используйте новое или старое. Они ни в коем случае не должны работать вместе, и вам лучше просто использовать новые вещи.   -  person vallentin    schedule 13.12.2013


Ответы (2)


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

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

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

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


Обновлять:

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

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

Псевдоним вершинных атрибутов

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

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

Отрывок из таблицы

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

person Andon M. Coleman    schedule 13.12.2013
comment
как я писал раньше, это только для моего собственного тестирования, а не для выходного / официального кода. Я все равно использую NV для OpenGL (нет смысла использовать что-либо еще из-за дрянных драйверов ogl от всех других поставщиков) спасибо за список, я принял ваш ответ - person Spektre; 14.12.2013

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

можно рисовать без шейдера, с помощью _5 _ / _ 6_ последовательности,

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;
}
person Rabbid76    schedule 21.08.2018
comment
хе +1 не видел этого до сих пор (я ссылался на этот QA), поскольку обычное уведомление сайта не работает ... - person Spektre; 09.04.2019