openglglsl3d-texture

Working with GL_TEXTURE_3D


I'm trying to read a file representing values to be mapped to colors when rendering a volume. I.e., each voxel has its color represented in the input file. Here it follows a dummy test file:

4 4 4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

It should define a value with its top black, followed by a white layer, black layer and white again.

That's how I read it:

int width, height, depth;
file >> width;
file >> height;
file >> depth;

printf("Texture data: %d, %d, %d\n", width, height, depth);

// Creating buffer
unsigned char buffer[height][width][depth];

// Reading content
int v;
for (int i = 0; i < height; i ++) {
    for (int j = 0; j < width; j ++) {
        for (int k = 0; k < depth; k ++) {
            file >> v;
            buffer[i][j][k] = v * 255;
        }
    }
}

And that's how I create my texture:

// Create one OpenGL texture
GLuint textureID;
glGenTextures(1, &textureID);

// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_3D, textureID);

// Give the image to OpenGL
glTexImage3D(GL_TEXTURE_3D, 0, GL_RED, height, width, depth, 0, GL_RED, GL_UNSIGNED_BYTE, buffer);

glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

These are the values that are going to be used to construct my VAO:

_modelCoordinates = { -1.0, -1.0,  1.0,
                       1.0, -1.0,  1.0,
                       1.0,  1.0,  1.0,
                      -1.0,  1.0,  1.0,
                      -1.0, -1.0, -1.0,
                       1.0, -1.0, -1.0,
                       1.0,  1.0, -1.0,
                      -1.0,  1.0, -1.0 };

_modelIndices = { 0, 1, 2,
                  2, 3, 0,
                  1, 5, 6,
                  6, 2, 1,
                  7, 6, 5,
                  5, 4, 7,
                  4, 0, 3,
                  3, 7, 4,
                  4, 5, 1,
                  1, 0, 4,
                  3, 2, 6,
                  6, 7, 3 };

_textureCoordinates = {  0.0, 0.0, 1.0,
                         1.0, 0.0, 1.0,
                         1.0, 1.0, 1.0,
                         0.0, 1.0, 1.0,
                         0.0, 0.0, 0.0,
                         1.0, 0.0, 0.0,
                         1.0, 1.0, 0.0,
                         0.0, 1.0, 0.0 };

Finally, this are my shaders:

  1. Vertex Shader:

.

#version 410 core

uniform mat4 mvMatrix;
uniform mat4 pMatrix;

in vec4 vPosition;
in vec3 texCoord;

// Input for the fragment shader
smooth out vec3 uv;

void main() {
    gl_Position = pMatrix * mvMatrix * vPosition;
    uv = texCoord;
}   
  1. Frag Shader:

.

#version 410 core

uniform sampler3D tex;

in vec3 uv;
out vec4 fragColor;

void main()
{ 
   vec3 color = texture(tex, uv).rrr;
   fragColor.rgb = color;
}

After loading the uniforms and attribute values, I draw the volume:

_modelView = modelView;
_projection = projection;

_succeed = Bind();
if (_succeed)
{
    glBindVertexArray(_vao);
    LoadUniformVariables();
    glDrawElements(GL_TRIANGLES, _modelIndices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}
UnBind();

However, all that I get is a blank volume:

enter image description here

I dont't know how to proper set the texture coordinates and how to correctly implement the fragment shader for this case.


Solution

  • After adding these lines:

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

    Everything worked fine.