3

i have tried to load stack of .png image files into glTexImage3D for volume rendering purpose. However, i just cant make it work as it keeps crashing. BTW, the problem seems to be related with pData.

Below is the code for your reference:

GLubyte * pData = new GLubyte[XDIM*YDIM*ZDIM];
ifstream volumeData;

getFileNameWithSpecificExtension(dir_path);
sort(begin(fileIndex), end(fileIndex));

for (int i = 0; i < 201; i ++)
{
    volumeData.open(FrontPart + to_string(fileIndex[i]) + ".png", ios::binary);
}

volumeData.read(reinterpret_cast<char*>(pData), XDIM*YDIM*ZDIM*sizeof(GLubyte));
volumeData.close();


glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_3D, textureID);

// set the texture parameters
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

//set the mipmap levels (base and max)
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 4);

//allocate data with internal format and foramt as (GL_RED) 
glTexImage3D(GL_TEXTURE_3D, 0, GL_RED, XDIM, YDIM, ZDIM, 0, GL_RED, GL_UNSIGNED_BYTE, pData);
GL_CHECK_ERRORS

//generate mipmaps
glGenerateMipmap(GL_TEXTURE_3D);

//delete the volume data allocated on heap
delete[] pData;
Kromster
  • 7,181
  • 7
  • 63
  • 111
vincent911001
  • 523
  • 1
  • 6
  • 20
  • 2
    You're opening 201 files, and then try to read the entire content from the last file you opened. You probably wanted to read one slice from each of the 201 files? Also, it looks like you're reading a png file and using the content as raw data. png files are compressed. – Reto Koradi Mar 11 '15 at 07:04
  • Hi, thanks for your reply, yes, i would like to read every single slice from the 201 files. As for reading the png file, i will try to use some library to read them, but what can i do to load those images into a 3d texture. FYI, the code is based on tutorial by Mobeen (OpenGL Development Cookbook). Thanks a lot. – vincent911001 Mar 11 '15 at 07:09
  • FYI, the image size is non power of two... Thanks – vincent911001 Mar 11 '15 at 07:10

1 Answers1

4

Non-Power-of-2 is no issue since OpenGL-2.0 removed that constraint. For reading each image slice into the texture use glTexImage3D with a NULL pointer to initialize the texture, then in the loop iterating over the files, read each file, decode it and load it into the right slice using glTexSubImage3D. Also don't use explicit new and delete[] but a std::vector.

Properly implementing the "foreach file" loop and the "ImageFileReader" are left as an exercise for the reader. I suggest looking into the Generic Image library for one particular candidate (http://sourceforge.net/adobe/genimglib/home/Home/). Also keep in mind that it's a very bad idea to hardcode any image dimensions into your code.

glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_3D, textureID);

// set the texture parameters
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

//set the mipmap levels (base and max)
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 4);

//allocate data with internal format and foramt as (GL_RED) 
glTexImage3D(GL_TEXTURE_3D, 0, GL_RED, XDIM, YDIM, ZDIM, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
GL_CHECK_ERRORS

GLubyte * pData = new GLubyte[XDIM*YDIM*ZDIM];
std::vector<GLubyte> vData(XDIM*YDIM*ZDIM);
foreach file in filenames (...)
{
    ImageFileReader ifr(FrontPart + to_string(fileIndex[i]) + ".png")
    ifr.decode(vData);
    glTexSubImage3D(GL_TEXTURE_3D, 0,
        0 /* x offset */,
        0 /* y offset */,
        z,
        XDIM, YDIM, 1,
        GL_RED, GL_UNSIGNED_BYTE,
        &vData[0] );
}

//generate mipmaps
glGenerateMipmap(GL_TEXTURE_3D);
datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Hi datenwolf, thanks a lot for your suggestion and guidelines, i will try to work out the solution later. Really appreciate your help, thanks again – vincent911001 Mar 12 '15 at 00:08