Как получить точку привязки переменной изображения в OpenGLES

Я пытаюсь получить точку привязки переменной изображения в моем шейдере GLES. Я могу сделать это для блоков хранения юниформ или шейдеров, используя этот код:

GLenum Prop = GL_BUFFER_BINDING;
GLint Binding = -1;
GLint ValuesWritten = 0;
glGetProgramResourceiv( GLProgram, GL_UNIFORM_BLOCK, i, 1, &Prop, 1, &ValuesWritten, &Binding );

К сожалению, такого понятия, как GL_IMAGE_BINDING, не существует. В десктопном GL я просто получаю местоположение униформы изображения, используя GetUniformLocation, а затем привязываю его к слоту изображения, используя glProgramUniform1i. К сожалению, в OpenGLES glProgramUniform1i можно использовать только для юниформ-образцов и не работает для униформ-образов. Причина, по которой мне нужна эта точка привязки, заключается в том, что я выполняю автоматическую привязку ресурсов. Мои ресурсы могут быть связаны с единым именем переменной. Я хочу, чтобы они автоматически назначались правильному слоту изображения. Пока это работает нормально для всех ресурсов, кроме изображений в GLES.


person Egor    schedule 10.12.2014    source источник


Ответы (1)


Единицей изображения является значение переменной юниформ изображения. Хотя спецификация ES 3.1 не позволяет устанавливать значения для этих переменных с помощью glProgramUniform1i(), я не вижу ничего, что мешало бы вам получить значение, которое было установлено в коде GLSL с помощью квалификатор макета binding=....

Это основано на разделе 7.10 «Изображения» спецификации. На странице 112 написано:

Значение униформы изображения представляет собой целое число, указывающее единицу изображения, к которой осуществляется доступ.

и в том же разделе на странице 113:

Местоположение переменной изображения запрашивается с помощью GetUniformLocation, как и любая юниформ-переменная.

Поэтому, чтобы получить единицу изображения для переменной "MyImage" в программе prog:

GLint loc = glGetUniformLocation(prog, "MyImage");
GLint imgUnit = -1;
glGetUniformiv(prog, loc, &imgUnit);

Это дает вам единицу изображения, к которой привязана переменная изображения в шейдере. Если вам нужно имя изображения, вы можете продолжить запрос:

GLint imgName = -1;
glGetIntegeri_v(GL_IMAGE_BINDING_NAME, imgUnit, &imgName);
person Reto Koradi    schedule 15.12.2014
comment
Спасибо, это именно то, что мне нужно. Я работал с DX в течение многих лет и плохо знаком с OpenGL, поэтому некоторые вещи меня сильно смущают. Запрос модуля привязки изображения сильно отличается от получения привязки к юниформ-буферу и выглядит, на мой взгляд, как бэкдор. - person Egor; 16.12.2014
comment
Изображения гораздо больше похожи на текстуры/сэмплеры. Основное отличие состоит в том, что вы можете установить привязку текстуры/сэмплера с помощью glUniform1i(), но не привязку изображения. На самом деле была версия спецификации, в которой говорилось, что вы можете, но она была отредактирована (все еще там, но с перечеркнутым). В истории изменений упоминается ошибка Khronos, которую мне не удалось найти в общедоступной базе данных ошибок. Мне бы хотелось узнать, почему они его удалили. Возможно, они просто посчитали это излишним, раз можно указать привязку в коде шейдера. - person Reto Koradi; 16.12.2014