В настоящее время я пытаюсь записать изображение с помощью imageStore в OpenGL. Однако, используя renderdock в качестве моего отладчика, я нахожу только черную текстуру после запуска моей программы.
Я создаю и привязываю изображение для записи следующим образом:
glGenTextures(1, &textureID);
glBindTexture(target, textureID);
glObjectLabel(GL_TEXTURE, textureID, -1, "\"3D Texture\"");
glTexStorage3D(target, 1, GL_RGBA8, width, height, depth);
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Затем я загружаю текстуру в программу, выполнив:
glBindImageTexture(0, textureID, 0, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA8);
GLuint location = glGetUniformLocation(programID, uniform);
glUniform1i(location,0);
И, наконец, я рендеринг, вызывая glDrawArrays ().
Мой фрагментный шейдер выглядит так:
#version 440
out vec3 f_pos;
out vec3 f_norm;
out vec2 f_uv;
layout(RGBA8) uniform image3D volumeMap;
void main()
{
imageStore(volumeMap, ivec3(0,0,0),
vec4(0,1,1,0));
}
Поэтому я ожидаю найти голубой пиксель в верхнем левом углу первого слоя. Однако этот пиксель черный.
Я успешно загрузил и прочитал из сэмплеров с помощью вызова texture ().
Я не уверен, что я пропускаю шаги или то, как я делаю вещи, неправильно.
РЕДАКТИРОВАТЬ:
Я изменил свой код, чтобы не полагаться на RenderDoc для проверки цвета.
Поэтому я представляю вещи следующим образом
Конечный фрагмент шейдера:
#version 440
out vec4 fragment_color;
layout(binding=3, RGBA8) uniform image3D vMap;
void main()
{
fragment_color = imageLoad(vMap, ivec3(0,0,0));
}
C ++
glUseProgram(Program1);
/*load texture as above*/
draw();
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
glUseProgram(Program2);
/*load texture as above*/
draw();
draw просто устанавливает геометрические буферы, а затем вызывает glDrawArrays ().
В результате получается черная сетка, где я ожидаю голубой сетки
Операции загрузки / хранения изображений работают по правилам некогерентный доступ к памяти. Это означает, что записи в них не видны для последующего чтения, если вы явно не делаете что-то для делать их видно. Обычно это призыв к glMemoryBarrier
,
Всегда помни это glMemoryBarrier
указывает, как вы собираетесь доступ письменное значение, а не как вы написали к нему. В этом случае механизм одинаков в любом случае: GL_SHADER_IMAGE_ACCESS_BARRIER_BIT
, Эта команда должна быть помещена после команды, которая записывает данные, и перед той, которая их читает.
Кроме того, я не могу сказать, имеет ли этот шейдер неопределенное поведение или нет. У вас есть несколько вызовов, которые все записывают в одну и ту же область памяти. Но в вашем случае они пишут одинаковое значение. Из описания в описании неясно, является ли это подлинным UB или это нормально. Конечно, было бы UB, если вызовы записывали разные данные, но я не знаю, существует ли какое-то исключение для них, пишущих одни и те же данные.
Однако я бы очень сомневался в этом.
Других решений пока нет …