更改内部格式会导致纹理参数不正确

2022-03-24 00:00:00 opengl textures c++

我设置了在其上绘制场景的帧缓冲区纹理,如下所示:

glGenFramebuffers(1, &renderFBO);

glGenTextures(1, &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, &width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &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);

通过验证widthheight,它们确实具有正确的维度1024, 768

现在我正在尝试设置第二个纹理,用作计数器,这意味着我正在尝试通过递增纹理中的适当纹理元素来计算每个颜色值的出现次数。因为我正在尝试计算颜色,所以我使用大小为256 x 3的2D纹理。在每个单元格中,我想要一个单独的无符号整数,表示特定颜色值在该点之前出现的次数。例如,如果遇到颜色(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, &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, &width);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &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);
}

解决方案

您会收到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);

我建议您使用Debug Output,它可以节省大量时间,让您可以快速找到此类错误。

相关文章