James Helferty, TransGaming Inc. (james 'at' transgaming.com)
Daniel Koch, TransGaming Inc. (daniel 'at' transgaming.com)
Status
Approved by the ARB on July 11, 2008.
Version
Last Modified Date: January 13, 2010
Author Revision: 5
Number
ARB Extension #49
Dependencies
Требуется OpenGL 1.1.
Это расширение описано ещё раз в OpenGL 2.1 Спецификации.
ARB_draw_instanced влияет на определение этого расширения.
EXT_draw_instanced влияет на определение этого расширения.
EXT_gpu_shader4 влияет на определение этого расширения.
Обзор
В GL приложениях мы часто рисуем некий объект или группу однотипных объектов, которые оказывают влияние на данные о вершинах, количество примитивов, тип и время рендинга. Данное расширение предоставляет средства для уменьшения вызовов API и сведения количества повторяющихся данных к минимуму.
В частности это расширение является альтернативой ARB_draw_instanced. Оно использует те же вызовы API для рисования, но переопределяет их так, чтобы вершинный шейдер мог использовать, вместо вершинного массива, атрибуты в качестве источника данных.
Расширение предоставляет массив "divisor" ("делитель") для общих атрибутов вершинного массива, который при не-нулевом (non-zero) значении указывает, что атрибут является "instanced". An instanced attribute does not advance per-vertex as usual, but rather after every <divisor> conceptual вызовы рисования.
(Атрибуты, которые не повторяются, повторяются в полном объёме за каждый conceptual вызов рисования.)
Указывая преобразования данных в качестве атрибута копируемого или серии атрибутов копируемого, вершинные шейдеры могут, во взаимодействии с вызовами рисования экземпляров, рисовать несколько экземпляров объекта одним вызовом.
IP Status
No known IP claims.
New Tokens
Приняты <pname> параметры GetVertexAttribdv, GetVertexAttribfv и GetVertexAttribiv:
Добавлено к Главе 2 спецификации OpenGL 2.1 (OpenGL Operation)
Изменён раздел 2.8 (Vertex Arrays), страница 23
(удалены изменения части 2.8 made by ARB_draw_instanced и EXT_draw_instanced, а также заменено всё, начиная со второго параграфа, p. 27 до второго параграфа, страница 30) Внутренний счтчик <instanceID> является 32-bit integer переменной, которая может быть прочитана вершинной программой как <vertex.instance>, как и описано в разделе 2.X.3.2, или vertex shader как <gl_InstanceIDARB>, как описано в разделе 2.15.4.2.Значение этого счетчика всегда равено нулю, за исключением особо оговоренных случаев.
Изменяет скорость, с которой продвигаются общие вершинные атрибуты, когда визуализируется множества копий примитивов в одном вызове рисования. Если <divisor> равен нулю, то <index> продвигается на каждой вершине единожды. Если <divisor> отличнен от нуля, то атрибут продвигается по <divisor> копий единожды во множестве (ах) вершин являющихся визуализируемыми. Атрибут называется <instanced>, если его VERTEX_ATTRIB_ARRAY_DIVISOR_ARB отлична от нуля.
Функция
void ArrayElementInstanced( int i, int instance );
не существует в GL, но используется, чтобы описать функциональность в остальной части этого раздела. Эта функция переводит <i>-количество элементов каждого включённого, не копируемого массива и <instance> элементов каждого включённого копируемого массива GL. Эффект от ArrayElementInstanced (i) такой же, как от следующей последовательность команд
if (normal array enabled)
Normal3[type]v(normal array element i);
if (color array enabled)
Color[size][type]v(color array element i);
if (secondary color array enabled)
SecondaryColor3[type]v(secondary color array element i);
if (fog coordinate array enabled)
FogCoord[type]v(fog coordinate array element i);
for (j = 0; j < textureUnits; j++) {
if (texture coordinate set j array enabled)
MultiTexCoord[size][type]v(TEXTURE0 + j, texture coordinate set j array element i);
}
if (color index array enabled)
Index[type]v(color index array element i);
if (edge flag array enabled)
EdgeFlagv(edge flag array element i);
for (j = 1; j < genericAttributes; j++) {
if (generic vertex attribute j array enabled) {
if (VERTEX_ATTRIB_ARRAY_DIVISOR_ARB[j] > 0)
k = instance / VERTEX_ATTRIB_ARRAY_DIVISOR_ARB[j];
else
k = i;
if (generic vertex attribute j array normalization flag is set, and
type is not FLOAT or DOUBLE)
VertexAttrib[size]N[type]v(j, generic vertex attribute j array element k);
else
VertexAttrib[size][type]v(j, generic vertex attribute j array element k);
}
}
if (generic attribute array 0 enabled) {
if (VERTEX_ATTRIB_ARRAY_DIVISOR_ARB[0] > 0)
k = instance / VERTEX_ATTRIB_ARRAY_DIVISOR_ARB[0];
else
k = i;
if (generic vertex attribute 0 array normalization flag is set, and
type is not FLOAT or DOUBLE)
VertexAttrib[size]N[type]v(0, generic vertex attribute 0 array element k);
else
VertexAttrib[size][type]v(0, generic vertex attribute 0 array element k);
} else if (vertex array enabled) {
Vertex[size][type]v(vertex array element i);
}
Когда <textureUnits> и <genericAttributes> дают номер наборов текстурных координат и общих вершинных атрибутов, поддерживаемых реализацией соответственно. "[size]" и "[type]" общих вершинных атрибутов предполагает, что полный набор команд вершинных атрибут существует, хотя и не все такие функции предусмотрены в GL.
Команда
void ArrayElement( int i );
ведет себя идентично ArrayElementInstanced с экземпляром установлен в ноль, это эквивалентно вызову
ArrayElementInstanced(i, 0);
Изменения, внесенные в массив данных между приведением в исполнение Begin и соответствующие выполнения End может повлиять на вызовы ArrayElement, которые сделаны в том же периуде Begin/End, не связанных последовательным образом. То есть, вызов ArrayElement, который предшествует изменению в массив данных, может получить доступ к измененным данные, а также вызову, который следует за изменением в массиве данных может обратиться к оригинальным данным
Указание вида i < 0 приведёт к непредсказуеому результату. В данном случае рекомендуется генерировать ошибку INVALID VALUE.
Функция
void DrawArraysOneInstance( enum mode, int first, sizei count, int instance );
не существует в GL, но используется, чтобы описать функциональность в остальной части этого раздела. Эта функция создает последовательность геометрических примитивов с использованием элементов <first>, через <first> + <count> - 1 каждого включённого, не копируемого массива, и <instance> элементов каждого включённого, копируемого массива. <mode> определяет, какой вид примитивов будет строиться, он принимает те же значения, как единственной параметр команды Begin. Влияние от
DrawArraysOneInstance (mode, first, count, int instance);
такое же, как от последовательность команд
Begin(mode);
for (int i = 0; i < count ; i++)
ArrayElementInstanced(first+ i, instance);
End();
с одним исключением: текущее нормальные координаты, цвет, secondary цвет, цветовой индекс, флаг ребра, координаты тумана, координаты текстуры и общие атрибуты будут неопределены после выполнение DrawArraysOneInstance, если соответствующий массив включен. Текущие значения, соответствующие выключенным массивам не изменение при выполнении DrawArraysOneInstance.
[Продолжение перевода следует, присылайте свои правки.]