3

I am trying to store data into a 3D texture, however it doesn't seem to work. I set up the texture like this:

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);

Later, I write to the texture:

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);
}

I know the draw operation works fine because I have used it with a shadow map in another part of the program.

Finally, I try to read the data from the texture:

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);

As you can see, if the data was modified then it would print to cout. I set the data to be 5 so that you can see that glGetTexImage actually reads the texture data (because otherwise it would be all zeroes).

The program that I use has this as the vertex buffer:

#version 430

layout(location = 0) in vec3 position;

uniform mat4 M;

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

And this as the fragment buffer:

#version 430

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

I used an arbitrary location to write to rather than one that is affected by the fragment itself so that I could at least be assured that if any fragment got passed through it would affect the texture. However, nothing seems to work. I've tried changing where the imageStore writes to, I've tried scaling gl_Position in the vertex buffer in various ways. Any help would be appreciated.

Edit:

After following the possible duplicates solution of changing the layered setting from false to true, it still doesn't work.

user975989
  • 2,578
  • 1
  • 20
  • 38
  • possible duplicate of [Compute shader not modifying 3d texture](http://stackoverflow.com/questions/17015132/compute-shader-not-modifying-3d-texture) – jozxyqk Jul 01 '15 at 09:02
  • I tried it. I'm also not using a computer shader but rather a fragment shader. – user975989 Jul 01 '15 at 09:13
  • Then not a dupe. I can't spot anything really obvious. Are you sure fragments are actually drawing? Try moving `imageStore` to the vertex shader just as a test. – jozxyqk Jul 01 '15 at 09:29
  • You're right, it worked in the vertex shader. I have no idea why it's not passing into the frag shader though. – user975989 Jul 01 '15 at 09:33

1 Answers1

4

glUseProgram(voxelProg) and glGetUniformLocation(mainProg, "M") reference different shader programs. Consequently, the matrix M isn't set, the vertices form degenerate triangles and no fragments are rasterized so imageStore never actually gets called.

Also glBindImageTexture handles 3D textures as "layered" 2D textures, so the layered argument must be GL_TRUE. see this.

[EDIT] In this case, M is not projecting the geometry correctly for other reasons too (see the comments). To change M so that it scales and translates the mesh into a -1 to 1 cube to match the 3D image, see: How to normalize a mesh into -1 to 1, then revert from normalized mesh to original one?

Community
  • 1
  • 1
jozxyqk
  • 16,424
  • 12
  • 91
  • 180
  • I changed both of those but I still don't write to the texture. – user975989 Jul 01 '15 at 09:50
  • @user975989 Does `getModelMatrix` include any necessary projection and view matrices? Are you sure your geometry is correct? Maybe back face culling is interfering? For whatever reason, no geometry is being rasterized. – jozxyqk Jul 01 '15 at 09:54
  • Hmm, you're right. The idea behind this is to voxelize a model. I thought the proper way to do this is to not use a projection or a view matrix, but rather just the model matrix. When I multiplied by them it worked fine. However, the issues is that the projection matrix is perspective and the view matrix depends on where I am. I want to voxelize the model regardless of those two characteristics. Shouldn't just the model matrix suffice? Also, `GL_DEPTH_TEST` and `GL_CULL_FACE` are both disabled. – user975989 Jul 01 '15 at 10:04
  • You might want to use an orthographic projection that bounds the model. If you need to keep correct aspect ratio, then use the axis with the longest bounds and center the model on the other two. In other words, find the min and max x,y,z vertex positions, then use that tp scale the model into the -1 to 1 normalized device coordinates cube for your shader. Keeping your current code, update `M` to perform the scale and translate to the origin. – jozxyqk Jul 01 '15 at 10:10
  • @user975989 added a related link. – jozxyqk Jul 01 '15 at 10:21
  • I normalized the coordinates of my models to be between 0 and 1, but retaining the aspect ratio. Now, it voxelizes the model completely, however the issue is that the various viewpoints don't converge. For example, something projected from the x axis doesn't align properly with something projected from the y or the z axis. I tried centering the model on the two non dominant axis, however this doesn't solve the problem. Do you have any clue how to solve this issue? – user975989 Jul 02 '15 at 07:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/82165/discussion-between-user975989-and-jozxyqk). – user975989 Jul 02 '15 at 07:22