Problems with ARB texture comrpession

Hi dudes, I’m having problems with ARB texture compression. Performance is not high as expected, in fact is lower that without texture compression.

I can explain here the algorithm used to compress textures:

In general is

Generate a texture
BuildMipMaps (via gluBuild2DMipMaps)
Now Take the data of the MipMaps via glGetTexImage
delete original texture
generate anothe texture
And build the texture (compressing it) with the data obtained above

As ideas, i supose that using only a few textures (4) perhaps is faster use uncompressed textures…
or that i can’t compress textures at load time but i have to compress, save them, an later load them already compressed…
But i don’t know what happens,

Any idea?

Here is the actual algorithm:

void SimpleTex2D::Setup(GLenum format)
{
formatPixel = format;
glGenTextures(1,&handle);
glBindTexture(GL_TEXTURE_2D,handle);
glTexImage2D(GL_TEXTURE_2D, 0, format, height, width,0, format, GL_UNSIGNED_BYTE, data);

unsigned int numMaxLevels;
if(height >= height)
{
int width2 = width;
numMaxLevels = 1;
while(width2 = (width2>>1)) numMaxLevels++;
}
else
{
int height2 = height;
numMaxLevels = 1;
while(height2 = (height2>>1)) numMaxLevels++;
}

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,numMaxLevels);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER ,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER ,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE);
ConstruirMipMaps();

//OK, hem carregat la imatge, ara la comprimirem sencera (MipMaps inclosos)
GLfloat numMipMaps;
unsigned char** dataMipMaps;
glGetTexParameterfv(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,&numMipMaps);
dataMipMaps = new unsigned char*[numMipMaps];
int widthMipMaps = new int [numMipMaps];
int heightMipMaps = new int [numMipMaps];
unsigned int indexMipMaps;
for(indexMipMaps = 0; indexMipMaps < numMipMaps; indexMipMaps++)
{
if(format == GL_RGB) dataMipMaps[indexMipMaps] = new unsigned char[amplada
height
3];
else
dataMipMaps[indexMipMaps] = new unsigned char[widthheight4];
glGetTexImage(GL_TEXTURE_2D,indexMipMaps,format,GL_UNSIGNED_BYTE,dataMipMaps[indexMipMaps]);
glGetTexLevelParameteriv(GL_TEXTURE_2D,indexMipMaps,GL_TEXTURE_HEIGHT,&(heightMipMaps[indexMipMaps]));
glGetTexLevelParameteriv(GL_TEXTURE_2D,indexMipMaps,GL_TEXTURE_WIDTH,&(widthMipMaps[indexMipMaps]));
}

//Tenim totes les dades a dataMipMaps (la textura original tb està inclosa (al nivell 0))

glDeleteTextures(1,&handle);

glGenTextures(1,&handle);
glBindTexture(GL_TEXTURE_2D,handle);
GLint compressed;

for(indexMipMaps = 0 ; indexMipMaps < numMipMaps;indexMipMaps++)
{
if(format == GL_RGBA)
glTexImage2D(GL_TEXTURE_2D,indexMipMaps, GL_COMPRESSED_RGBA_ARB, widthMipMaps[indexMipMaps],heightMipMaps[indexMipMaps], 0,format,GL_UNSIGNED_BYTE,dataMipMaps[indexMipMaps]);
else
glTexImage2D(GL_TEXTURE_2D,indexMipMaps, GL_COMPRESSED_RGB_ARB, widthMipMaps[indexMipMaps],heightMipMaps[indexMipMaps], 0,format,GL_UNSIGNED_BYTE,dataMipMaps[indexMipMaps]);

glGetTexLevelParameteriv(GL_TEXTURE_2D,indexMipMaps,GL_TEXTURE_COMPRESSED_ARB, &compressed);
if(compressed)
{
  GLint formatIntern,sizeCompressed;
  unsigned char * dataCompressed;
  glGetTexLevelParameteriv(GL_TEXTURE_2D,indexMipMaps,GL_TEXTURE_INTERNAL_FORMAT,&formatIntern);
  glGetTexLevelParameteriv(GL_TEXTURE_2D,indexMipMaps,GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB,&sizeCompressed);

  dataCompressed = new unsigned char[sizeCompressed];
  glGetCompressedTexImageARB(GL_TEXTURE_2D,indexMipMaps,dataCompressed);

  glCompressedTexImage2D(GL_TEXTURE_2D,indexMipMaps,formatIntern, widthMipMaps[indexMipMaps],heightMipMaps[indexMipMaps],0,sizeCompressed,dataCompressed);
  delete [] dataCompressed;     
}

}
for(indexMipMaps = 0; indexMipMaps < numMipMaps; indexMipMaps++)
{
delete [] dataMipMaps[indexMipMaps];
}
delete [] dataMipMaps;

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER ,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER ,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE);
}

Greetings,

Toni (aka TAG)

Uploading from uncompressed data to a compressed texture is significantly slower than uploading just uncompressed data, because the driver has to do compression at run-time (the hardware can only de-compress).

Texture compression is a heavy-duty operation (more so than MIP map generation). In addition, the driver doesn’t do a great job of compressing the images, because it has to run pseudo-interactively. An offline compressor, such as the Photoshop .DDS plug-in from nVIDIA, will do a substantially better job on image quality.

Rendering with a compressed texture, once it’s uploaded, is likely to be faster, because it uses less texture memory bandwidth.

The intended use of texture compression is to load pre-compressed data from disk (such as DXT1/DXT5 data from .DDS files) an upload in its compressed form. Uploading pre-compressed data is oftentimes faster than uploading uncompressed data (because it’s smaller).

Last: using GLU to generate the MIP maps is very slow. You can easily write a much faster MIP map generation routine in C, and most certainly using MMX assembly. This is assuming box filtering, which is what GLU uses internally AFAICT.