Sign in to follow this  
Papadopol

DDS on openGL on 64bit

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.

[code]  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 );
}
}[/code]

 

 

[code]
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;
}
[/code]

 

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

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

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