3D Texture Map Not working.

I’ve been trying to get a 3D texture mapping working on some CT data. (16 bit grey scale data)
The images a 512 x 512 with 22 slices…

Here is the code I use to create the texture…
The ThreeDTexture is a simple structure that has the width, height and depth along with a pointer to the ‘unsigned short’ data.

When I view this all is see is a white cube.
I’m thinking perhaps I either have my textcords and or verticies wrong or that OpenGL doesn’t support 16 bit grey scale or that I haven’t initialized OpenGL correctly.

The ideal image would be a MIP image… i.e. a maximum intensity projection…

- (void) makeCube:(int) name s:(GLfloat *)s text:(ThreeDTexture *)text
{
    int imageWidth, imageHeight, imageDepth;
    
    imageWidth  = text->width;
    imageHeight = text->height;
    imageDepth  = text->depth;

    glNewList(name, GL_COMPILE);

    glPushMatrix();
    
    glScalef(s[0], s[1], s[2]);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
    glTexImage3D(GL_TEXTURE_3D,
                 0,
                 GL_INTENSITY16,
                 imageWidth,
                 imageHeight,
                 imageDepth,
                 0,
                 GL_LUMINANCE,
                 GL_UNSIGNED_SHORT,
                 (GLvoid *) text->image);

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

    glBegin(GL_QUADS);

    // Do the six faces of the cube...
    //front
    glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f(+1.0f, -1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f(+1.0f, +1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, +1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)

    //right side
    glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f(+1.0f, -1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 0.0f, 1.0f); glVertex3f(+1.0f, -1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 1.0f, 1.0f); glVertex3f(+1.0f, +1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f(+1.0f, +1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)

    //back
    glTexCoord3f(1.0f, 0.0f, 1.0f); glVertex3f(+1.0f, -1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(0.0f, 1.0f, 1.0f); glVertex3f(-1.0f, +1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 1.0f, 1.0f); glVertex3f(+1.0f, +1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)

    //left side
    glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, +1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(0.0f, 1.0f, 1.0f); glVertex3f(-1.0f, +1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)

    // top
    glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f(-1.0f, +1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f(+1.0f, +1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 1.0f, 1.0f); glVertex3f(+1.0f, +1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(0.0f, 1.0f, 1.0f); glVertex3f(-1.0f, +1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)

    // bottom
    glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 0.0f, 1.0f); glVertex3f(+1.0f, -1.0f, +1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)
    glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f(+1.0f, -1.0f, -1.0f); //glNormal3f(<#GLfloat nx#>,<#GLfloat ny#>,<#GLfloat nz#>)

    glEnd();
    
    glPopMatrix();
    glEndList();
}
  
- (BOOL) initGL
{ 
   glShadeModel( GL_SMOOTH );                // Enable smooth shading
   glClearColor( 0.0f, 0.0f, 0.0f, 0.5f );   // Black background
   glClearDepth( 1.0f );                     // Depth buffer setup
   glEnable( GL_DEPTH_TEST );                // Enable depth testing
   glDepthFunc( GL_LEQUAL );                 // Type of depth test to do
   // Really nice perspective calculations
   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
   
   // added for mip.
 //  glBlendEquationEXT(GL_MAX_EXT)

   // mine.
   //glEnable(GL_CULL_FACE);
   //glCullFace(GL_BACK);
   glEnable(GL_TEXTURE_3D);  
   
   [self createObjects];
   return TRUE;
}

You cannot create a 3D Texturemap with 22 slices. You have to use a power of two, meaning 32.

Jan.

If your card doesn’t support the GL_ARB_texture_non_power_of_two extension, you may need to set your number of slices to a power of two.

Ok I just chopped off a few slices and tried 16 slices… Still no difference…

umm…maybe try storing the texture in a texture object and binding the texture.

What do you expect to see here?

You seem to be drawing a cube with the extremities of your texture mapped onto the cube.

The correct behaviour is for OpenGL to sample the texture on those faces from the edge of the cube.

If you want to see the volume you must itterate the slices through the volume of the 3D texture blending the results in the framebuffer. You need to generate the fragments INSIDE the 3D texture volume to sample the texture in there.

Dr Bob, your other thread asked about this and I sent this link:

http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=get_topic;f=3;t=006597

READ IT, don’t skim it. Heck you could cut & paste the code in this thread and it would work so why you’re posting this question and only drawing the outside edge of the volume I don’t know.

Read the excellent links that have already been given to you.

Ok, a couple of things. First, I don’t see a texture bind (or even a texture name being created in the first place) in there anywhere.
Also, you may want to pull the texture creation code outside of the list generation. If I am reading my documentation right here (which is no guarantee), the glTexParameteri calls are getting compiled into the list but the glPixelStorei and the glTexImage3D call are being executed immediately. Not sure what the consequences of this are.

Ok I see what your saying Dorbie… Its like the 3D teapot example… The wood texture was 3D but the teapot is defined with the 3D texture…

I did ‘read’ the example you posted previously but don’t quite understand…

The code is completly different from what I’m doing and sort of understand.

I want to do Maximum Intensity Projection and I’m not sure this example does that.

Second and possibly irrelivant it that my data is 16 bit grey scale.

One of your links specified that I use glBlendEXT(GL_MAX_EXT);
GL_MAX_EXT seems to be undefined in my implimentation of OpenGL. (For MIP)

Your web pages www.dorbie.com are gone… pitty.
What part of this code itterates a polygon through the texture and accumulates?

Any comments on gdewans suggestions?

I posted updated links for the dorbie.com contents the last time you posted on this subject. Go check that thread.

gdewan’s comments make sense. You definitely want to use a texture bind and get the image loading outside your list, but these are purely performance oriented issues, rather than functional ones.