Расширение ARB_multi_bind

При рендеринге часто возникает ситуация, когда нужно выбрать (bind) сразу группу однотипных объектов, например задать группу текстур для набора текстурных блоков. Традиционно для этого используются многократные вызовы команд glBind*, однако каждый такой вызов несет в себе заметный overhead. Поэтому расширение ARB_multi_bind (вошедшее в состав OpenGL 4.4) дает возможность сократить количество вызовов, используемых в таких случаях.

Данное расширение вводит новые команды, позволяющие задавать привязку сразу для целого ряда различных объектов (буферов, текстур и т.п.). Важным отличием вводимых команд от традиционных команд glBind* является:

Выбор текстур

Для выбора активных текстур сразу для группы текстурных блоков вводится специальная команда glBindTextures.

void glBindTextures ( GLuint first, GLsizei count, const GLuint * textures );

Данная команда для каждого из текстурных блоков, начиная с GL_TEXTURE0+first и заканчивая GL_TEXTURE0+first+count-1 задает текстуры texture[0], ..., textures[count-1]. При этом в качестве типа текстуры берет тот самый тип, для которого она изначально создавалась (для которого для этой текстуры первый раз была вызвана команда glBindTexture). Вызов данной команды эквивалентен следующему фрагменту кода:

for ( int i = 0; i < count; i++ )
{
    GLuint texture;

    if ( textures == NULL )
        texture = 0;
    else
        texture = textures [i];

    glActiveTexture ( GL_TEXTURE0 + i );

    if ( texture != 0 )
    {
        GLenum target = textureTarget ( texture );

        glBindTexture ( target, texture );
    }
    else
        for ( target in allAppropriateTargets )
            glBindTexture ( target, 0 );
}

Выбор сэмплеров

Для выбора группы сэмплеров в наборе последовательных текстурных блоков служит команда glBindSamplers:

void glBindSamplers ( GLuint first, GLsizei count, const GLuint * samplers );

Вызов данной функции эквивалентен выполнению следующего фрагмента кода:

for ( int i = 0; i < count; i++ )
{
    if ( samplers == NULL )
        glBindSamplers ( first + i, 0 );
    else
        glBindSamplers ( first + i, samplers [i] );
}

Выбор вершинных буферов

Аналогично есть команда для привязки сразу набора вершинных буферов с заданными смещениями и началами к набору последовательных точек привязки. Для этого вводится команда glBindVertexBuffers:

void glBindVertexBuffers ( GLuint first, GLsizei count,
      const GLuint * buffers,
      const GLintptr * offsets, const GLsizei * strides );

Данная команда эквивалентна следующему фрагменту кода:

for ( int i = 0; i < count; i++ )
{
    if ( buffers == NULL )
        glBindVertexBuffer ( first + i, 0, 0, 16 );
    else
        glBindVertexBuffer ( first + i, buffers [i], offsets [i], strides [i] );
}

Выбор диапазонов буферов

Команды glBindBuffersBase и glBindBuffersRange позволяют задать привязку для целого набора точек привязки к заданному типу буфера.

void glBindBuffersBase ( GLenum target, 
   GLuint first, GLsizei count,
   const GLuint * buffers );

void glBindBuffersRange ( GLenum target,
    GLuint first, GLsizei count,
    const GLuint * buffers,
    const GLintptr * offsets,
    const GLsizeptr sizes );

Команда glBindBuffersBase эквивалентна следующему фрагменту кода:

for ( int i = 0; i < count; i++ )
{
    if ( buffers == NULL )
        glBindBuffersBase ( target, first + i, 0 );
    else
        glBindBuffersBase ( target, first + i, buffers [i] );
}

Команда glBindBuffersRange эквивалента приводимому ниже фрагменту кода:

for ( int i = 0; i < count; i++ )
{
    if ( buffers == NULL )
        glBindBufferBase( target, first + i, 0 );
    else
        glBindBufferRange ( target, first + i,
            buffres [i], offsets [i], sizes [i] );
}

Задание текстур для блоков изображений

Расширение ARB_shader_image_load_store вводит в OpenGL новую возможность - изображения, в которые шейдеры могут записывать значения (а не только их читать). Каждая такое изображение является слоем в mipmap-пирамиде какой-то текстуры. Для работы с этими изображениями вводятся блоки изображений (image units по аналогии с текстурными блоками) и для работы с изображением нужно выбрать соответствующую текстуру в блоке изображений. Для этого используется команда glBindImageTextureю

При использовании команды glBindImageTextures можно выбрать текстуры сразу для целого набора подряд идущих блоков изображений.

void glBindImageTextures ( GLuint first, GLsizei count, const GLuint * textures );

Данная команда эквивалентна следующему фрагменту кода:

for ( int i = 0; i < count; i++ )
{
    if ( textures == NULL || textures [i] == 0 )
        glBindImageTexture ( first + i, 0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_R8 );
    else
    glBindImageTexture ( first + i, textures [i], 0, GL_TRUE,
            0, GL_READ_WRITE, internalFormat ( textures [i] ) );
}