首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >imageStore()的麻烦(OpenGL 4.3)

imageStore()的麻烦(OpenGL 4.3)
EN

Stack Overflow用户
提问于 2013-01-12 04:07:24
回答 3查看 5.7K关注 0票数 3

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

代码语言:javascript
运行
复制
#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));
}

应用程序代码如下:

代码语言:javascript
运行
复制
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);

然后,使用该纹理渲染全屏四边形,但目前它只显示视频内存中的一些随机旧数据。你知道会出什么问题吗?

编辑:

这是我显示纹理的方式:

代码语言:javascript
运行
复制
// 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();

drawProgram由以下几部分组成:

代码语言:javascript
运行
复制
#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;
}

和:

代码语言:javascript
运行
复制
#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);
}

片段着色器中的最后一个注释行生成以下输出:Render output

顶点数组对象(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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-13 01:16:12

这是我显示纹理的方式:

这还不够好。我看不到call to glMemoryBarrier,所以不能保证你的代码能正常工作。

请记住:通过Image Load/Store写入图像不是内存一致的。他们require explicit user synchronization before they become visible。如果要在以后使用已存储为纹理的图像,则必须在写入该图像的渲染命令之后显式调用glMemoryBarrier,但在将该图像作为纹理进行采样的渲染命令之前。

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

因为桌面OpenGL不是OpenGL ES。

最后三个参数仅描述您提供给OpenGL的arrangement of the pixel data。它们没有改变OpenGL存储数据的方式。在ES中,它们可以,但这只是因为ES不进行格式转换。

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

桌面GL则不会。如果你想要一个特定的image format,你需要它。Desktop GL为您提供了您所要求的内容,并且只提供您所要求的内容。

始终使用已调整大小的内部格式。

票数 6
EN

Stack Overflow用户

发布于 2013-01-12 23:27:18

GL_RGBA不是一种大小很大的内部格式,因此您无法知道它到底是哪种格式。大多数情况下,OpenGL会将其转换为GL_RGBA8。

在您的示例中,设置的GL_FLOAT参数仅描述可以在纹理中上载的像素数据。

请阅读表2 here以了解可以设置为内部纹理格式的内容。

票数 3
EN

Stack Overflow用户

发布于 2013-01-12 20:28:12

好了,我找到了解决方案。问题出在这里:

代码语言:javascript
运行
复制
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, 0);

该行没有指定内部格式(GL_RGBA)的大小。当我提供GL_RGBA32F时,它就开始工作了。为什么这是一个问题,我不知道(希望有人能够解释)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14285849

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档