c++ - 在 OpenGL 中使用 imageStore 写入图像

标签 c++ opengl graphics glsl renderdoc

目前我正在尝试使用 OpenGL 中的 imageStore 写入图像。然而,使用 renderdock 作为我的调试器,我在运行我的程序后发现只有一个黑色纹理。

我创建并绑定(bind)要写入的图像,如下所示:

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()。

结果是黑色网格,我希望是青色网格

最佳答案

图像加载/存储操作在 incoherent memory access 规则下运行.这意味着对它们的写入对以后的读取不可见,除非您明确地执行某些操作以使它们可见。通常,这是对 glMemoryBarrier 的调用。

永远记住 glMemoryBarrier 指定了您打算如何访问写入的值,而不是您如何写入它。在这种情况下,两种方式的机制都是相同的:GL_SHADER_IMAGE_ACCESS_BARRIER_BIT。此命令必须放在写入数据的命令之后和读取数据的命令之前。

另外,我不能说这个着色器是否有未定义的行为。您有多个调用都写入同一内​​存位置。但就您而言,他们写的是相同的值。从说明书上的描述看不清楚这是正品UB还是没问题。如果调用写入不同的数据肯定是 UB,但我不知道它们写入相同数据是否存在某些异常。

不过,我会很犹豫是否要这样做。

关于c++ - 在 OpenGL 中使用 imageStore 写入图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50321736/

相关文章:

java - 当我使用自己的多种方法来绘制图像时出现 NullpointerException

c++ - 使用自定义提取运算符时出现错误 C2679

c++ - OpenGL矩形莫名其妙地占据了整个窗口

c++ - glUseProgram() 和速度之后 uniform 的行为

c++ - 使用 openGL 时立方体未按预期输出

C++ 如何制作图形动画 (POO)

c# - 图形变换缩放后第一像素列的一半丢失

c++ - 通过按索引选择范围的元素来创建 View

c++ - 我正在尝试将 lambda 作为参数传递给模板可变参数

c++ - iOS:更新到 Xcode 8.3 后编译器中的 C++ 警告