Изменение внутреннего формата приводит к тому, что текстура имеет неправильные параметры

#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);
 

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