使用imageStore()时出现问题(OpenGL 4.3)

End*_*dox 3 opengl shader textures compute-shader

我正在尝试将一些数据从计算着色器输出到纹理,但是imageStore()似乎什么都不做.这是着色器:

#version 430

layout(RGBA32F) uniform image2D image;

layout (local_size_x = 1, local_size_y = 1) in;
void main() {
    imageStore(image, ivec2(gl_GlobalInvocationID.xy), vec4(0.0f, 1.0f, 1.0f, 1.0f));
}
Run Code Online (Sandbox Code Playgroud)

和应用程序代码在这里:

GLuint tex;

glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, 0);

glBindImageTexture(0, tex, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F);
glUseProgram(program->GetName());
glUniform1i(program->GetUniformLocation("image"), 0);

glDispatchCompute(WIDTH, HEIGHT, 1);
Run Code Online (Sandbox Code Playgroud)

然后使用该纹理渲染全屏四边形,但目前它只显示来自视频内存的一些随机旧数据.知道什么可能是错的吗?

编辑:

这是我显示纹理的方式:

// This comes right after the previous block of code
glUseProgram(drawProgram->GetName());

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, tex);
glUniform1i(drawProgram->GetUniformLocation("sampler"), 0);

glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 6);

glfwSwapBuffers();
Run Code Online (Sandbox Code Playgroud)

drawProgram包括:

#version 430
#extension GL_ARB_explicit_attrib_location : require

layout(location = 0) in vec2 position;
out vec2 uvCoord;

void main() {
    gl_Position = vec4(position.x, position.y, 0.0f, 1.0f);
    uvCoord = position;
}
Run Code Online (Sandbox Code Playgroud)

和:

#version 430

in vec2 uvCoord;
out vec4 color;

uniform sampler2D sampler;

void main() {
    vec2 uv = (uvCoord + vec2(1.0f)) / 2.0f;
    uv.y = 1.0f - uv.y;

    color = texture(sampler, uv);
    //color = vec4(uv.x, uv.y, 0.0f, 1.0f);
}
Run Code Online (Sandbox Code Playgroud)

片段着色器中的最后一个注释行生成此输出:渲染输出

顶点数组对象(vao)有一个带有6个2D顶点的缓冲区:

-1.0,-1.0

1.0,-1.0

1.0,1.0

1.0,1.0

-1.0,1.0

-1.0,-1.0

Nic*_*las 6

这是我显示纹理的方式:

这还不够好.我没有看到呼叫glMemoryBarrier,因此无法保证您的代码确实有效.

请记住:通过图像加载/存储写入图像不是内存连贯的.它们在可见之前需要显式用户同步.如果要将以后存储的图像用作纹理,则必须glMemoryBarrier写入它的渲染命令之后,但在渲染命令之前进行显式调用,然后从渲染命令中将其作为纹理进行采样.

为什么这是一个问题,我不知道

因为桌面OpenGL 不是 OpenGL ES.

最后三个参数描述了您为OpenGL提供的像素数据排列.他们对OpenGL如何存储数据一无所知.在ES中,他们这样做,但这仅仅是因为ES不进行格式转换.

在桌面OpenGL中,将浮点数据上传到规范化的整数纹理是完全合法的.预计OpenGL会尽可能地转换数据.ES不进行转换,因此必须更改内部格式(第三个参数)以匹配数据.

桌面GL没有.如果您想要特定的图像格式,请提出要求.Desktop GL为您提供您所要求的内容,以及您所要求的内容.

始终使用大小的内部格式.