• Advertisement
Sign in to follow this  

DDS on openGL on 64bit

This topic is 1844 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello. I'm using a samplecode from codesampler.com to load a compressed DDS to openGL and it seems to work on 32 bit compilation but not on x64.

  void loadCompressedTexture( void )
{
DDS_IMAGE_DATA *pDDSImageData = loadDDSTextureFile( "lena.dds" );

if( pDDSImageData != NULL )
{
int nHeight = pDDSImageData->height;
int nWidth = pDDSImageData->width;
int nNumMipMaps = pDDSImageData->numMipMaps;

int nBlockSize;

if( pDDSImageData->format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )
nBlockSize = 8;
else
nBlockSize = 16;

glGenTextures( 1, &g_compressedTextureID );
glBindTexture( GL_TEXTURE_2D, g_compressedTextureID );

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

int nSize;
int nOffset = 0;

// Load the mip-map levels

for( int i = 0; i < nNumMipMaps; ++i )
{
if( nWidth == 0 ) nWidth = 1;
if( nHeight == 0 ) nHeight = 1;

nSize = ((nWidth+3)/4) * ((nHeight+3)/4) * nBlockSize;

glCompressedTexImage2DARB( GL_TEXTURE_2D,
i,
pDDSImageData->format,
nWidth,
nHeight,
0,
nSize,
pDDSImageData->pixels + nOffset );

nOffset += nSize;

// Half the image size for the next mip-map level...
nWidth = (nWidth / 2);
nHeight = (nHeight / 2);
}
}

if( pDDSImageData != NULL )
{
if( pDDSImageData->pixels != NULL )
free( pDDSImageData->pixels );

free( pDDSImageData );
}
}

 

 


DDS_IMAGE_DATA* loadDDSTextureFile( char *filename )
{
DDS_IMAGE_DATA *pDDSImageData;
DDSURFACEDESC2 ddsd;
char filecode[4];
FILE *pFile;
int factor;
int bufferSize;

// Open the file
pFile = fopen( filename, "rb" );

if( pFile == NULL )
{
char str[255];
// sprintf( str, "loadDDSTextureFile couldn't find, or failed to load \"%s\"", filename );
MessageBox( NULL, L"loadDDSTextureFile couldn't find, or failed to load ", L"ERROR", MB_OK|MB_ICONEXCLAMATION );
return NULL;
}

// Verify the file is a true .dds file
fread( filecode, 1, 4, pFile );

if( strncmp( filecode, "DDS ", 4 ) != 0 )
{
char str[255];
// sprintf( str, "The file \"%s\" doesn't appear to be a valid .dds file!", filename );
MessageBox( NULL, L"The file \"%s\" doesn't appear to be a valid .dds file!", L"ERROR", MB_OK|MB_ICONEXCLAMATION );
fclose( pFile );
return NULL;
}

// Get the surface descriptor
fread( &ddsd, sizeof(ddsd), 1, pFile );

pDDSImageData = (DDS_IMAGE_DATA*) malloc(sizeof(DDS_IMAGE_DATA));

memset( pDDSImageData, 0, sizeof(DDS_IMAGE_DATA) );

//
// This .dds loader supports the loading of compressed formats DXT1, DXT3
// and DXT5.
//

switch( ddsd.ddpfPixelFormat.dwFourCC )
{
case FOURCC_DXT1:
// DXT1's compression ratio is 8:1
pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
MessageBox(NULL,L"DXT1",L"Compression level",NULL);
factor = 2;
break;

case FOURCC_DXT3:
// DXT3's compression ratio is 4:1
pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
MessageBox(NULL,L"DXT3",L"Compression level",NULL);
factor = 4;
break;

case FOURCC_DXT5:
// DXT5's compression ratio is 4:1
pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
MessageBox(NULL,L"DXT5",L"Compression level",NULL);
factor = 4;
break;

default:
char str[255];
// sprintf( str, "The file \"%s\" doesn't appear to be compressed "
// "using DXT1, DXT3, or DXT5!", filename );
MessageBox( NULL,L"The file \"%s\" doesn't appear to be compressed", L"ERROR", MB_OK|MB_ICONEXCLAMATION );
return NULL;
}

//
// How big will the buffer need to be to load all of the pixel data
// including mip-maps?
//

if( ddsd.dwLinearSize == 0 )
{
MessageBox( NULL,L"dwLinearSize is 0!",L"ERROR",
MB_OK|MB_ICONEXCLAMATION);
}

if( ddsd.dwMipMapCount > 1 )
bufferSize = ddsd.dwLinearSize * factor;
else
bufferSize = ddsd.dwLinearSize;

pDDSImageData->pixels = (unsigned char*)malloc(bufferSize * sizeof(unsigned char));

fread( pDDSImageData->pixels, 1, bufferSize, pFile );

// Close the file
fclose( pFile );

pDDSImageData->width = ddsd.dwWidth;
pDDSImageData->height = ddsd.dwHeight;
pDDSImageData->numMipMaps = ddsd.dwMipMapCount;

if( ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1 )
pDDSImageData->components = 3;
else
pDDSImageData->components = 4;

return pDDSImageData;
}

 

It seems that when I compile the code on X64 I get an MessageBox error that the texture is not compressed. Any idea why? Should I try recoding to Windows ReadFile instead of fread ?

Share this post


Link to post
Share on other sites
Advertisement

I found this on Google: http://xboxforums.create.msdn.com/forums/p/40860/239509.aspx

 

The size of a pointer changes depending whether you build on a 32-bit or 64-bit system. All of the data members below lpSurface in DDSURFACEDESC2 are shifted "down" an extra 32-bits when you compile on 64 bit. This throws off the data in ddpfPixelFormat since you just read in a solid block of memory. I'm not sure if there is an elegant work around, but loading each member, one at a time, would potentially resolve this. There has to be a better way.

Share this post


Link to post
Share on other sites
Can't you define a struct the same as DDSURFACEDESC2 but replace the LPVOID with LPVOID POINTER_32 instead in that case?

EDIT: That's a hack of course, but better than reading fields one at a time. Edited by Paradigm Shifter

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement