Sign in to follow this  
jmakitalo

Compressed texture array

Recommended Posts

I'm trying to create a texture array of DXT1/DXT3/DXT5 compressed images loaded from separate dds files (compressed, with mipmaps). I load the dds file with a function

unsigned char *load_dds(const char *filename, int &w, int &h, int &nmipmaps, GLenum &format, int &size);

where format is GL_COMPRESSED_RGBA_S3TC_DXT*_EXT and size the the total size of the data (including mipmaps). I have tested this for basic 2D textures and it seems to work.

 

I then create the texture and allocate data for all layers by calling glCompressedTexImage3D with no input data:

GLenum target = GL_TEXTURE_2D_ARRAY;
glCompressedTexImage3D(target, 0, format, w, h, nlayers, 0, size, 0);

This gives "invalid value" error. I'm not sure what size should reflect here. Should it include mipmaps and all layers? Is it allowed here to give NULL data pointer?

 

After allocating the data, I call for each image i

int mipWidth = w;
int mipHeight = h;
int blockSize = (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;
int offset = 0;

for(int mip = 0; mip < numMipmaps; ++mip){
   int mipSize = ((mipWidth + 3) / 4) * ((mipHeight + 3) / 4) * blockSize;

  glCompressedTexSubImage3D(target, mip, 0, 0, i, mipWidth, mipHeight, 1, format,
                                    mipSize, data + offset);

  mipWidth = max (mipWidth >> 1, 1);
  mipHeight = max (mipHeight >> 1, 1);

  offset += mipSize;
}

where data is pointer returned by load_dds. This generates error "invalid operation". Is it necessary to call glCompressedTexImage3D prior to glCompressedTexSubImage3D to allocate the memory? What else could be wrong here? I would appreciate any hints.

Share this post


Link to post
Share on other sites

The size in glCompressedTexImage3D must be (w + 3) / 4) * ((h + 3) / 4) * blockSize*nlayers as this removes the "invalid value" error. I still get "invalid operation" for glCompressedTexSubImage3D.

Share this post


Link to post
Share on other sites

I circumvented the issue by implementing a dds loader, which loads an array of images directly into a contiguous memory block with mipmaps properly chained. Then I just used glCompressedTexImage3D and it worked fine. This is not as elegant a solution IMHO and the original problem remains unsolved. I of course googled a bit, but all I could find concerning issues with glCompressedTexSubImage3D was this thread in Ogre forums, where it is suggested that one should prefer the non-sub version for compatibility.

Edited by jmakitalo

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this