Каковы местоположения атрибутов для конвейера с фиксированными функциями в профиле ядра 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;
}