OpenGL 4.6 без glBind: разбор Direct State Access на C++23
В OpenGL 4.5 появился Direct State Access (DSA): функции получают имя объекта первым аргументом и работают с ним, не читая и не меняя гнёзда контекста. В статье на примере квадрата с текстурой и индексами показано, как такой подход избавляет от обязательного ритуала glGenBuffers, glBindBuffer и glBufferData.
При старом стиле строка glBufferData не называет буфер: функция берёт объект из гнезда GL_ARRAY_BUFFER, и результат зависит от последнего вызова glBindBuffer, который мог стоять в другой функции. На примере загрузки иконки показано, как это ломает настройку текстуры стены, а отдельная ловушка связана с гнездом GL_ELEMENT_ARRAY_BUFFER, которое принадлежит привязанному VAO.
Ключевое отличие в коде — glCreateBuffers вместо glGenBuffers: объект создаётся сразу, а не при первой привязке. Смешивать стили нельзя: если передать имя от glGenBuffers в glNamedBufferStorage, вызов завершается ошибкой GL_INVALID_OPERATION и память не выделяется. То же происходит с glGenTextures и glTextureParameteri.
Память буфера выделяет glNamedBufferStorage, причём её размер неизменяем: повторный вызов для того же буфера даёт GL_INVALID_OPERATION. Флаги в последнем аргументе задают дальнейшую работу с содержимым, в частности GL_DYNAMIC_STORAGE_BIT нужен для обновления данных, а GL_MAP_READ_BIT или GL_MAP_WRITE_BIT — для отображения буфера в память программы.
В VAO формат атрибута и источник байтов разведены: glVertexArrayVertexBuffer задаёт буфер, начало данных и шаг, а glVertexArrayAttribFormat описывает формат и смещение. Чтобы нарисовать тем же VAO другую модель с такой же раскладкой вершины, достаточно одного вызова glVertexArrayVertexBuffer.
Текстура создаётся через glCreateTextures с видом в первом аргументе, память выделяет glTextureStorage2D, пиксели копирует glTextureSubImage2D. Номер текстурного блока передаётся аргументом, поэтому glActiveTexture и glUniform1i для сэмплера не нужны. Для шейдеров применён std::expected: функция возвращает либо имя шейдера, либо текст ошибки.
Привязка осталась только перед рисованием: программа, вершины и текстура связываются в цикле кадра, тогда как настройка выполняется один раз до него. DSA требует OpenGL 4.5 и недоступен на macOS, где OpenGL остановлен на версии 4.1, а также в OpenGL ES и WebGL. Код проверен только на MSVC из Visual Studio 2026 с флагом /W4, на GCC и Clang автор не собирал.