Расширение EXT_direct_state_access

Важной особенностью OpenGL является наличие специальных команд (селекторов), служащих для установки состояния, влияющего на выполнение других команд. Так команда glMatrixMode определяет к какой именно матрице относятся команды glRotate и glPushMatrix. Аналогично команда glActiveTexture задает к какому именно текстурному блоку будут относиться ряд команд по работе с текстурами. Подобным образом ведут себя все команды glBind*.

С одной стороны такой подход (когда для изменения фактически используется модель bind-modify-unbind) упрощает работу и уменьшает количество передаваемых аргументов. Кроме того именно подобная модель позволила ряду расширений легко ввести новую функциональность, не ломая предыдущую. Однако, с другой стороны, такой подход затрудняет написание многоуровневых библиотек и порождает необходимость постоянного отслеживания состояние селекторов и восстановление значения после изменений.

Расширение EXT_direct_state_access - это первый шаг от модели bind-modify-unbind к прямому обращению непосредственно к требуемому объекту без селекторов. Данное расширение не отменяет селекторы, а вводит большое количество дополнительных функций, обеспечивающих прямой доступ к объекту без помощи селектора. Рассмотрим как обычно осуществляется задание данных для вершинного буфера (VBO).

GLuint saveBuffer;

glGetIntegerv (  GL_ARRAY_BUFFER, &saveBuffer );     // get bound buffer id
glBindBuffer  ( GL_ARRAY_BUFFER, buf );              // bind buffer
                                                     // set data for it
glBufferData  ( numVertices * sizeof ( Vertex ), vertices, GL_STATIC_DRAW );
glBindBuffer  ( GL_ARRAY_BUFFER, saveBuffer );       // restore previously bound buffer

Используя же расширение EXT_direct_state_access это можно сделать всего одной командой:

glNamedBufferDataEXT ( buf, numVertices * sizeof ( Vertex ), vertices, GL_STATIC_DRAW );

При этом данная команда вообще никак не меняет binding'и буферов, а обращается к буферу напрямую. Расширение EXT_direct_state_access вводит очень большое количество новых функций для непосредственного доступа минуя селекторы. Однако в этой статье будут рассмотрены только некоторые из этих функций, которые можно использовать в OpenGL 3.3 core profile (большая часть вводимых функций касается deprectaed-функционала).

Работа с буферами

Для непосредственной работы с буферами (VBO) вводятся аналоги всех основных функций для работы с буферами:

void      glNamedBufferDataEXT     ( GLuint buffer, GLsizeiptr size, const void * data, GLenum usage );

void      glNamedBufferSubDataEXT  ( GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data);

void *    glMapNamedBufferEXT      ( GLuint buffer, GLenum access );

GLboolean glUnmapNamedBufferEXT    ( GLuint buffer );

void *    glMapNamedBufferRangeEXT ( GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access );

void      glFlushMappedNamedBufferRangeEXT ( GLuint buffer, GLintptr offset, GLsizeiptr length );

void      glNamedCopyBufferSubDataEXT      ( GLuint readBuffer, GLuint writeBuffer, 
                                             GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size );

Использование этих функций позволяет заметно снизить необходимость в команде glBind* и упростить код.

Работа с атрибутами

Следующие две команды обеспечивают связать между вершинным буфером (VBO), VAO и задают параметры вершинного атрибута с заданным индексом (команда glVertexAttribPointer).

void glVertexArrayVertexAttribOffsetEXT  ( GLuint vao, GLuint buffer, GLuint index, int size, GLenum type, 
                                           GLboolean normalized, GLsizei stride, GLintptr offset );
										  
void glVertexArrayVertexAttribIOffsetEXT ( GLuint vao, GLuint buffer, GLuint index, GLint size, GLenum type, 
                                           GLsizei stride, intptr offset );

Фактически каждая из этих команд заменяет собой следующий блок кода:

glBindVertexArray     ( vao );
glBindBuffer          ( GL_ARRAY_BUFFER, buffer );
glVertexAttribPointer ( index, size, type, normalized, stride, offset );
glBindBuffer          ( savedVbo );
glBindVertexArray     ( savedVao );

Следующие две команды включают и выключают использование атрибута с заданным индексом в VAO.

void glEnableVertexArrayAttribEXT        ( GLuint vaobj, GLuint index );
void glDisableVertexArrayAttribEXT       ( GLuint vaobj, GLuint index );

Задание uniform-переменных

Большая группа функций позволяет напрямую (избегая команды glUseProgram) устанавливать значения uniform-переменных.

void glProgramUniform1fEXT ( GLuint program, int location, float v0 );
void glProgramUniform2fEXT ( GLuint program, int location, float v0, float v1 );
void glProgramUniform3fEXT ( GLuint program, int location, float v0, float v1, float v2 );
void glProgramUniform4fEXT ( GLuint program, int location, float v0, float v1, float v2, float v3 );

void glProgramUniform1iEXT ( GLuint program, int location, int v0 );
void glProgramUniform2iEXT ( GLuint program, int location, int v0, int v1 );
void glProgramUniform3iEXT ( GLuint program, int location, int v0, int v1, int v2 );
void glProgramUniform4iEXT ( GLuint program, int location, int v0, int v1, int v2, int v3 );

void glProgramUniform1uiEXT ( GLuint program, int location, GLuint v0 );
void glProgramUniform2uiEXT ( GLuint program, int location, GLuint v0, GLuint v1 );
void glProgramUniform3uiEXT ( GLuint program, int location, GLuint v0, GLuint v1, GLuint v2 );
void glProgramUniform4uiEXT ( GLuint program, int location, GLuint v0, GLuint v1, GLuint v2, GLuint v3 );

void glProgramUniform1ivEXT ( GLuint program, int location, GLsizei count, const int * values );
void glProgramUniform2ivEXT ( GLuint program, int location, GLsizei count, const int * values );
void glProgramUniform3ivEXT ( GLuint program, int location, GLsizei count, const int * values );
void glProgramUniform4ivEXT ( GLuint program, int location, GLsizei count, const int * values );

void glProgramUniform1uivEXT ( GLuint program, int location, GLsizei count, const GLuint * values );
void glProgramUniform2uivEXT ( GLuint program, int location, GLsizei count, const GLuint * values );
void glProgramUniform3uivEXT ( GLuint program, int location, GLsizei count, const GLuint * values );
void glProgramUniform4uivEXT ( GLuint program, int location, GLsizei count, const GLuint * values );
						 
void glProgramUniform1fvEXT ( GLuint program, int location, GLsizei count, const float * values );
void glProgramUniform2fvEXT ( GLuint program, int location, GLsizei count, const float * values );
void glProgramUniform3fvEXT ( GLuint program, int location, GLsizei count, const float * values );
void glProgramUniform4fvEXT ( GLuint program, int location, GLsizei count, const float * values );

void glProgramUniformMatrix2fvEXT ( GLuint program, int location, GLsizei count, GLboolean transpose, const float * values );
void glProgramUniformMatrix3fvEXT ( GLuint program, int location, GLsizei count, GLboolean transpose, const float * values );
void glProgramUniformMatrix4fvEXT ( GLuint program, int location, GLsizei count, GLboolean transpose, const float * values );

void glProgramUniformMatrix2x3fvEXT ( GLuint program, int location, GLsizei count, GLboolean transpose, const float * values );
void glProgramUniformMatrix3x2fvEXT ( GLuint program, int location, GLsizei count, GLboolean transpose, const float * values );
void glProgramUniformMatrix2x4fvEXT ( GLuint program, int location, GLsizei count, GLboolean transpose, const float * values );
void glProgramUniformMatrix4x2fvEXT ( GLuint program, int location, GLsizei count, GLboolean transpose, const float * values );
void glProgramUniformMatrix3x4fvEXT ( GLuint program, int location, GLsizei count, GLboolean transpose, const float * values );
void glProgramUniformMatrix4x3fvEXT ( GLuint program, int location, GLsizei count, GLboolean transpose, const float * values );

Работа с фреймбуфером

Аналогично вводится группа функций для прямой работы с FBO и рендербуферами без использования команд glBind*.

void   glGenerateTextureMipmapEXT         ( GLuint texture, GLenum target );
void   glGenerateMultiTexMipmapEXT        ( GLenum texunit, GLenum target );

void   glNamedRenderbufferStorageEXT      ( GLuint renderBuffer, GLenum internalFormat, GLsizei width, GLsizei height );
GLenum glCheckNamedFramebufferStatusEXT   ( GLuint frameBuffer, GLenum target );

void   glNamedFramebufferTexture1DEXT     ( GLuint frameBuffer, GLenum attachment, GLenum textarget, GLuint texture, int level );
void   glNamedFramebufferTexture2DEXT     ( GLuint frameBuffer, GLenum attachment, GLenum textarget, GLuint texture, int level );
void   glNamedFramebufferTexture3DEXT     ( GLuint frameBuffer, GLenum attachment, GLenum textarget, GLuint texture, int level, int zOffset );

void   glNamedFramebufferRenderbufferEXT  ( GLuint frameBuffer, GLenum attachment, GLenum renderBufferTarget, GLuint renderBuffer );

void   glNamedFramebufferTextureEXT       ( GLuint frameBuffer, GLenum attachment, GLuint texture, int level );
void   glNamedFramebufferTextureLayerEXT  ( GLuint frameBuffer, GLenum attachment, GLuint texture, int level, int layer );
void   glNamedFramebufferTextureFaceEXT   ( GLuint frameBuffer, GLenum attachment, GLuint texture, int level, GLenum face );

void   glFramebufferDrawBufferEXT  ( GLuint frameBuffer, GLenum mode );
void   glFramebufferDrawBuffersEXT ( GLuint frameBuffer, GLsizei n, const GLenum * bufs );
void   glFramebufferReadBufferEXT  ( GLuint frameBuffer, GLenum mode );

void   glGetNamedRenderbufferParameterivEXT          ( GLuint renderBuffer, GLenum pname, int * params );
void   glGetNamedFramebufferAttachmentParameterivEXT ( GLuint frameBuffer, GLenum attachment, GLenum pname, int * params );

Используются технологии uCoz