copying a 3D texture using glCopyTexImage

Hi everyone,

I’ve been trying to get copying of a 3D textured image to work. What I’d like
to do is texture a polygon with a 3D texture in the first pass. Then, copy this
texture, manipulate it some in later passes, and then copy it again to my
original 3D texture. Below, I’ve removed all the manipulation part (I’m going
to be using multitexturing later on), and I simply have 2 passes - one texturing
pass, and one copy and texturing pass. The output I’m expecting is just to see
the exact same image as the first pass, but instead I get nothing at all. I
have an Nvidia 4600 card, and will soon get the 5900, but I think neither of
those cards support glCopyTexSubImage3DEXT so I can’t use that function. Below
is the snippet of my code.

Would it make more sense for me to use a 2D Texture in the second pass as the
target rather than GL_TEXTURE_3D_EXT? But if I do that, how do I store a 2D
slice back to a 3D texture?

Any help is greatly appreciated! Thanks!

  • Quynh.

    // First pass - simply render a square textured with a 3D texture.
    glEnable(GL_TEXTURE_3D_EXT);
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glBindTexture(GL_TEXTURE_3D_EXT, texture[shape]);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // Clears out previous textures - no combining.
    glTexParameteri(GGL_TEXTURE_3D_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_S,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_T,GL_CLAMP);

    // Draw initial shape onto a quad.
    // Texturing function MUST be glMultiTexCoord2fARB. Does NOT work with just glTexCoord2f
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_QUADS);
    glMultiTexCoord3fARB(GL_TEXTURE0_ARB, 0.0f, 0.0f, zslice);
    glVertex3f(-1.0f, -1.0f, 0.0f);
    glMultiTexCoord3fARB(GL_TEXTURE0_ARB, 1.0f, 0.0f, zslice);
    glVertex3f(1.0f, -1.0f, 0.0f);
    glMultiTexCoord3fARB(GL_TEXTURE0_ARB, 1.0f, 1.0f, zslice);
    glVertex3f(1.0f, 1.0f, 0.0f);
    glMultiTexCoord3fARB(GL_TEXTURE0_ARB, 0.0f, 1.0f, zslice);
    glVertex3f(-1.0f, 1.0f, 0.0f);
    glEnd();
    glFlush();

    // Create and bind accum_texture for accumulation. Copy what was rendered
    // in the last pass to a texture.
    glActiveTextureARB(GL_TEXTURE1_ARB); // Doesn’t seem to work if using TEXTURE0!
    glEnable(GL_TEXTURE_3D_EXT);
    glGenTextures(1, &accum_texture); // Create one texture
    glBindTexture(GL_TEXTURE_3D_EXT,accum_texture);
    glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_S,GL_CLAMP);
    glTexParameteri(GL_TEXTURE_3D_EXT,GL_TEXTURE_WRAP_T,GL_CLAMP);
    glCopyTexImage2D(GL_TEXTURE_3D_EXT, 0, GL_LUMINANCE_ALPHA, 0, 0, IMAGE_SIZE, IMAGE_SIZE, 0);
    glFlush();

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_QUADS);
    glMultiTexCoord3fARB(GL_TEXTURE1_ARB, 0.0f, 0.0f, zslice);
    glVertex3f(-1.0f, -1.0f, 0.0f);
    glMultiTexCoord3fARB(GL_TEXTURE1_ARB, 1.0f, 0.0f, zslice);
    glVertex3f(1.0f, -1.0f, 0.0f);
    glMultiTexCoord3fARB(GL_TEXTURE1_ARB, 1.0f, 1.0f, zslice);
    glVertex3f(1.0f, 1.0f, 0.0f);
    glMultiTexCoord3fARB(GL_TEXTURE1_ARB, 0.0f, 1.0f, zslice);
    glVertex3f(-1.0f, 1.0f, 0.0f);
    glEnd();
    glFlush();

3D textures and glCopyTexSubImage3D have been part of the OpenGL spec since version 1.2. Your Geforce 4 certainly should support it and an FX5900 definitely will. It’s not in the default gl.h that comes with Visual Studio, though, so you’ll have to load it up like an extension. Any good extension loader library that you can find on the net should certainly have it.

glCopyTexImage2D?

You should use glCopyTexImage3D

Flushing should not be necessary, but couldn’t hurt.
Another major problem with this is that glCopyTexImage3D reallocates the texture.
You should use glCopyTexSubImage3D instead.

Thanks for the replies! I actually did use glCopyTexSubImage3DEXT
initially, but that didn’t work. The code was the same as I have
listed, except with the line, instead of glCopyTexImage2D:

glCopyTexSubImage3DEXT(GL_TEXTURE_3D_EXT, 0, 0, zslice, 0, 0, IMAGE_SIZE, IMAGE_SIZE);

So, then I checked to see if the GL_EXT_copy_texture was available on my
card using glGetString(GL_EXTENSIONS), and neither GL_EXT_copy_texture nor
GL_EXT_subtexture were listed. I think I have the latest version of the
driver (I’m not at my machine right now, so I can’t check it, but it was a
2003 driver). I just checked the extensions loader that I’m using, and it
does load all the copy_texture extensions. I guess I can check the return
from loading glCopyTexSubImage3DEXT and see if it was successful.

I also tried using glCopyTexImage2DEXT in place of glCopyTexImage2D at a
different section of my code that was working before, and it did not work
properly with glCopyTexImage2DEXT. Perhaps I need to enable something
other than GL_TEXTURE_3D_EXT? Or, perhaps I should use
glCopyTexSubImage3D instead of glCopyTexSubImage3DEXT? I just noticed
that the extensions loader loads both of these functions.

The documentation on GL_EXT_copy_texture at http://oss.sgi.com/projects/ogl-sample/registry/EXT/copy_texture.txt does
not list glCopyTexImage3D, and it also isn’t in the loader … which
brings me to another question. If I do get glCopyTexSubImage3DEXT to
work, then how do I initialize the format for the 3D texture? Normally
with 2D textures, I would call glCopyTexImage2D first, then later call
glCopyTexSubImage2D so that the texture is not reallocated. Should I just
bind an existing 3D texture first, and then call glCopyTexSubImage3DEXT?

As always, I really appreciate the help!

  • Quynh.

I’m not sure that EXT_copy_texture is in any drivers for any video card any more. The functionality exposed by it was integrated into OpenGL 1.2. If you’ll look at the GL1.2 section of the glext.h file, you’ll see glCopyTexSubImage3D in there.

EDIT: Also, don’t use GL_TEXTURE_3D_EXT. Just skip the _EXT and use GL_TEXTURE_3D. Whatever extension header you have should definitely have it. Furthermore, use glCopyTexSubImage3D and not glCopyTexSubImage3DEXT.

[This message has been edited by Ostsol (edited 01-03-2004).]

They will probably give the same pointer whether you use EXT or not.

It’s only in a few rare cases where EXT and ARB and core have different functions and tokens.

Also copy_texture is a GL 1.0 extension I guess. So is EXT_texture.
This stuff is ancient history.
Look at the date on copy_texture.txt (1995/06/17)

Be sure to use glGetError.