如何将图像存储与3D纹理一起使用?

时间:2015-07-01 08:58:34

标签: c++ opengl 3d opengl-4

我正在尝试将数据存储到3D纹理中,但它似乎无法正常工作。我设置了这样的纹理:

glGenTextures(1, &voxelTexture);
glBindTexture(GL_TEXTURE_3D, voxelTexture);
unsigned char clearData[VoxelSize* VoxelSize* VoxelSize];
memset(clearData, 5, sizeof(clearData));
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8UI, VoxelSize, VoxelSize, VoxelSize, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, clearData);

后来,我写了纹理:

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, VoxelSize, VoxelSize);
glUseProgram(voxelProg);
glBindTexture(GL_TEXTURE_3D, voxelTexture);
glBindImageTexture(0, voxelTexture, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R8UI);
for(const auto & i : models){
    glUniformMatrix4fv(glGetUniformLocation(voxelProg, "M"), 1, GL_FALSE, glm::value_ptr(i->getModelMatrix()));
    glBindVertexArray(i->getMesh()->vao);
    glDrawElements(GL_TRIANGLES, i->getMesh()->nbVertices, GL_UNSIGNED_INT, 0);
}

我知道绘制操作工作正常,因为我在程序的另一部分使用了阴影贴图。

最后,我尝试从纹理中读取数据:

glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
static char data[VoxelSize * VoxelSize *VoxelSize] = {0};
glGetTexImage(GL_TEXTURE_3D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, data);
for(auto & i : data){
    if(i!=5)
        std::cout << (int)i << " ";
}
endl(std::cout);

如您所见,如果数据已被修改,则会打印到cout。我将数据设置为5,以便您可以看到glGetTexImage实际读取纹理数据(因为否则它将全部为零)。

我使用的程序将此作为顶点缓冲区:

#version 430

layout(location = 0) in vec3 position;

uniform mat4 M;

void main(){
    gl_Position = M* vec4(position, 1.0);
}

这是片段缓冲区:

#version 430

layout(binding = 0, r8ui)writeonly restrict uniform uimage3D dataTexture;
void main(){
    imageStore(dataTexture, ivec3(6,6,6), uvec4(30));
}

我使用任意位置写入而不是受片段本身影响的位置,这样我至少可以确信如果任何片段通过它会影响纹理。然而,似乎没有任何作用。我尝试更改imageStore写入的位置,我尝试以各种方式在顶点缓冲区中缩放gl_Position。任何帮助将不胜感激。

编辑:

在遵循将false更改为true的可能重复解决方案之后,它仍然无法正常工作。

1 个答案:

答案 0 :(得分:3)

glUseProgram(voxelProg)glGetUniformLocation(mainProg, "M")引用了不同的着色器程序。因此,矩阵M未设置,顶点形成退化三角形,并且没有片段被栅格化,因此imageStore实际上从未被调用。

同样glBindImageTexture处理3D纹理,因为&#34;分层&#34; 2D纹理,因此分层参数必须为GL_TRUE。见this

[ EDIT ]在这种情况下,由于其他原因M未正确投影几何体(请参阅注释)。要更改M以使其缩放并将网格转换为-1到1的多维数据集以匹配3D图像,请参阅:How to normalize a mesh into -1 to 1, then revert from normalized mesh to original one?