Главная Статьи Ссылки Скачать Скриншоты Юмор Почитать Tools Проекты Обо мне Гостевая Форум |
При рендеринге часто возникает ситуация, когда нужно выбрать (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] ) );
}