0
votes

Question: I am trying to map a single 2D image to a 3D texture. When I visualize the output, OpenGL renders a white texture floating in black background. Why is this happening? Is it possible to map a 2D image to a 3D texture?

My goal is to place multiple 2D images along the z-dimension to resemble a volume. An example of such an approach is in this video: http://cvlab.epfl.ch/research/medical/em/synapses

Approaches attempted: I took 2D images and mapped them to 2D textures. I have also used 2D texture arrays. Both of these approaches provide a good result. However, when I tried to paint the surface of a 3D texture with the same image, I get a white texture floating around in a black space.

Code I have followed the texture mapping tutorial that is available on NeHe's website. http://nehe.gamedev.net/tutorial/lesson_06_texturing_update/47002/

Except changes to these three functions, everything else in the program (present in the solution file in the website) is the same.

... // header file declarations

#include <glext.h>

PFNGLTEXIMAGE3DPROC glTexImage3D;
GLuint  texture;    


int LoadGLTextures()    // Load Bitmaps And Convert To Textures
{
            /* load an image file directly as a new OpenGL texture */

            texture = SOIL_load_OGL_texture("Data/NeHe.bmp",SOIL_LOAD_AUTO, 
            SOIL_CREATE_NEW_ID,S OIL_FLAG_INVERT_Y);
            // "Data/NeHe.bmp"

            if(texture == 0) {return false;}

            glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
            if (glTexImage3D == NULL) 
            {
            printf("Error in line %d: Couldn't load glTexImage3D function. Aborting.\n", __LINE__);
            return -1;
            }

    glBindTexture(GL_TEXTURE_3D, texture);
    glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    //glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 4096, 4096, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    return true;    
}


int InitGL(GLvoid)      
{
            if (!LoadGLTextures())  
            { return FALSE; }

    glEnable(GL_TEXTURE_3D);
    // glEnable(GL_TEXTURE_2D); 
    glShadeModel(GL_SMOOTH);    //
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);   // Black Background
    glClearDepth(1.0f);         // Depth Buffer Setup
    glEnable(GL_DEPTH_TEST);    
    glDepthFunc(GL_LEQUAL);     
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective calculations
    return TRUE;    // Initialization Went OK
}


int DrawGLScene(GLvoid)   
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glLoadIdentity();   
    glTranslatef(0.0f,0.0f,-5.0f);
    glRotatef(xrot,1.0f,0.0f,0.0f);
    glRotatef(yrot,0.0f,1.0f,0.0f);
    glRotatef(zrot,0.0f,0.0f,1.0f);

    // glBindTexture(GL_TEXTURE_2D, texture[0]);
    glBindTexture(GL_TEXTURE_3D, texture);
    glBegin(GL_QUADS);

    glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  0.0f);
    glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  0.0f);
    glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  0.0f);
    glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  0.0f);

    glEnd();

    xrot+=0.3f;
    yrot+=0.2f;
    zrot+=0.4f;
    return TRUE;                                        
}

...
1
What did you expect to happen when you commented out the texture upload (glTexImage3D())?genpfault
Well, I wanted to check if the image was actually being bound to the texture. So, I commented out that line and set a breakpoint at the if(texture == 0) loop. The breakpoint wasn't taken and the program stepped through that code. Also, uncommenting that line did not help; the output is still the same.Eagle

1 Answers

0
votes

It is better to use 3D textures instead of 2D ones as you will be able to apply rotations correctly using glRotate(). You will also need to do blending and/or alpha-testing to see different layers of your 2D image.

To create a 3D texture, you can create an array of dimension [width x height x number_of_slices] and then store the raw data slice by slice

Look at this tutorial: http://www.codeproject.com/Articles/352270/Getting-started-with-Volume-Rendering?msg=4729498#xx4729498xx

It's very good and it worked for me to do the same thing