#c #opengl #textures
#c #opengl #Текстуры
Вопрос:
Я настроил текстуру фреймбуфера для рисования сцены следующим образом:
glGenFramebuffers(1, amp;renderFBO);
glGenTextures(1, amp;renderTexture);
glBindTexture(GL_TEXTURE_2D, renderTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, W_WIDTH, W_HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
int width, height;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, amp;width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, amp;height);
cout << "width: " << width << " height: " << height << endl;
glBindFramebuffer(GL_FRAMEBUFFER, renderFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Проверяя width
и height
, они действительно имеют правильные размеры, 1024, 768
.
Теперь я пытаюсь настроить вторую текстуру, которая будет использоваться в качестве счетчика, то есть я пытаюсь подсчитать вхождения каждого значения цвета, увеличивая соответствующий тексель в текстуре. Поскольку я пытаюсь подсчитать цвета, я использую текстуру 2D размера 256 x 3
. В каждой ячейке мне нужно одно целое число без знака, показывающее, сколько раз определенное значение цвета появлялось до этого момента. Например, если (255,5,3)
был обнаружен цвет, я бы увеличил числа внутри tex[255][0], tex[5][0], tex[3][0]
num_bins = 256;
GLuint* hist_data = new GLuint[num_bins * color_components]();
glGenTextures(1, amp;tex_output);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex_output);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, 256, 3, 0, GL_RED, GL_UNSIGNED_INT, hist_data);
glBindImageTexture(0, tex_output, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32UI);
int width, height;
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, amp;width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, amp;height);
cout << "width: " << width << " height: " << height << endl;
Я использовал соответствие размера и базового внутреннего формата, показанное в спецификации opengl. Однако при выполнении этого кода выходные значения являются width=0, height=0
. Входные данные, похоже, не являются проблемой, потому что я попытался указать NULL
их в качестве последнего аргумента, и это все равно не сработало. Чего мне здесь не хватает?
Редактировать:
Предполагается, что увеличение значений в текстуре должно происходить внутри следующего вычислительного шейдера:
#version 450
layout(local_size_x = 1, local_size_y = 1) in;
layout(rgba32f, binding = 0) uniform image2D img_input;
layout(r32ui, binding = 1) uniform uimage2D img_output;
void main() {
// grabbing pixel value from input image
vec4 pixel_color = imageLoad(img_input, ivec2(gl_GlobalInvocationID.xy));
vec3 rgb = round(pixel_color.rgb * 255);
ivec2 r = ivec2(rgb.r, 0);
ivec2 g = ivec2(rgb.g, 1);
ivec2 b = ivec2(rgb.b, 2);
uint inc = 1;
imageAtomicAdd(img_output, r, inc);
imageAtomicAdd(img_output, g, inc);
imageAtomicAdd(img_output, b, inc);
}
Комментарии:
1. Итак, это сработало после того, как вы вчера приняли вопрос, но сегодня это не работает?
2. @Rabbid76 Он работал без ошибок. Однако данные не записываются в текстуру, и кажется, что она создается неправильно.
Ответ №1:
Вы получаете GL_INVALID_OPERATION
сообщение об ошибке, поскольку аргумент формата текстуры не соответствует внутреннему формату текстуры. Для беззнакового интегрального формата вы должны использовать GL_RED_INTEGER
вместо GL_RED
(см. glTexImage2D
):
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, 256, 3, 0, GL_RED, GL_UNSIGNED_INT, hist_data);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32UI, 256, 3, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, hist_data);
Я рекомендую использовать отладочный вывод, это экономит много времени и позволяет быстро находить такие ошибки.