#include #include #include #include #include #include #include // Your local header file //PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB; #define MAKEFOURCC(ch0, ch1, ch2, ch3) \ ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \ ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) typedef enum _D3DFORMAT { D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), } D3DFORMAT; typedef struct _DDCOLORKEY { uint32_t dwColorSpaceLowValue;/* low boundary of color space that is to * be treated as Color Key, inclusive */ uint32_t dwColorSpaceHighValue;/* high boundary of color space that is * to be treated as Color Key, inclusive */ } DDCOLORKEY,*LPDDCOLORKEY; typedef struct _DDPIXELFORMAT { uint32_t dwSize; /* 0: size of structure */ uint32_t dwFlags; /* 4: pixel format flags */ uint32_t dwFourCC; /* 8: (FOURCC code) */ union { uint32_t dwRGBBitCount; /* C: how many bits per pixel */ uint32_t dwYUVBitCount; /* C: how many bits per pixel */ uint32_t dwZBufferBitDepth; /* C: how many bits for z buffers */ uint32_t dwAlphaBitDepth; /* C: how many bits for alpha channels*/ uint32_t dwLuminanceBitCount; uint32_t dwBumpBitCount; } DUMMYUNIONNAME1; union { uint32_t dwRBitMask; /* 10: mask for red bit*/ uint32_t dwYBitMask; /* 10: mask for Y bits*/ uint32_t dwStencilBitDepth; uint32_t dwLuminanceBitMask; uint32_t dwBumpDuBitMask; } DUMMYUNIONNAME2; union { uint32_t dwGBitMask; /* 14: mask for green bits*/ uint32_t dwUBitMask; /* 14: mask for U bits*/ uint32_t dwZBitMask; uint32_t dwBumpDvBitMask; } DUMMYUNIONNAME3; union { uint32_t dwBBitMask; /* 18: mask for blue bits*/ uint32_t dwVBitMask; /* 18: mask for V bits*/ uint32_t dwStencilBitMask; uint32_t dwBumpLuminanceBitMask; } DUMMYUNIONNAME4; union { uint32_t dwRGBAlphaBitMask; /* 1C: mask for alpha channel */ uint32_t dwYUVAlphaBitMask; /* 1C: mask for alpha channel */ uint32_t dwLuminanceAlphaBitMask; uint32_t dwRGBZBitMask; /* 1C: mask for Z channel */ uint32_t dwYUVZBitMask; /* 1C: mask for Z channel */ } DUMMYUNIONNAME5; /* 20: next structure */ } DDPIXELFORMAT,*LPDDPIXELFORMAT; typedef struct _DDSCAPS2 { uint32_t dwCaps; /* capabilities of surface wanted */ uint32_t dwCaps2; /* additional capabilities */ uint32_t dwCaps3; /* reserved capabilities */ uint32_t dwCaps4; /* more reserved capabilities */ } DDSCAPS2,*LPDDSCAPS2; typedef struct _DDSURFACEDESC2 { uint32_t dwSize; /* 0: size of the DDSURFACEDESC2 structure*/ uint32_t dwFlags; /* 4: determines what fields are valid*/ uint32_t dwHeight; /* 8: height of surface to be created*/ uint32_t dwWidth; /* C: width of input surface*/ union { uint32_t lPitch; /*10: distance to start of next line (return value only)*/ uint32_t dwLinearSize; /*10: formless late-allocated optimized surface size */ } x; uint32_t dwBackBufferCount;/* 14: number of back buffers requested*/ union { uint32_t dwMipMapCount;/* 18:number of mip-map levels requested*/ uint32_t dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ uint32_t dwSrcVBHandle;/* 18:source used in VB::Optimize */ } y; uint32_t dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ uint32_t dwReserved; /* 20:reserved*/ void * lpSurface; /* 24:pointer to the associated surface memory*/ union { DDCOLORKEY ddckCKDestOverlay; /* 28: CK for dest overlay use*/ uint32_t dwEmptyFaceColor; /* 28: color for empty cubemap faces */ } z; DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ union { DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ uint32_t dwFVF; /* 48: vertex format description of vertex buffers */ } t; DDSCAPS2 ddsCaps; /* 68: DDraw surface caps */ uint32_t dwTextureStage; /* 78: stage in multitexture cascade */ } DDSURFACEDESC2,*LPDDSURFACEDESC2; typedef struct { GLsizei width; GLsizei height; GLint components; GLenum format; int numMipMaps; GLubyte *pixels; } DDS_IMAGE_DATA; DDS_IMAGE_DATA* loadDDSTextureFile( const 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, str, "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, str, "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.t.ddpfPixelFormat.dwFourCC ) { case D3DFMT_DXT1: // DXT1's compression ratio is 8:1 pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; factor = 2; break; case D3DFMT_DXT3: // DXT3's compression ratio is 4:1 pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; factor = 4; break; case D3DFMT_DXT5: // DXT5's compression ratio is 4:1 pDDSImageData->format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; 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, str, "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.x.dwLinearSize == 0 ) { // MessageBox( NULL, "dwLinearSize is 0!","ERROR", // MB_OK|MB_ICONEXCLAMATION); return NULL; } if( ddsd.y.dwMipMapCount > 1 ) bufferSize = ddsd.x.dwLinearSize * factor; else bufferSize = ddsd.x.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.y.dwMipMapCount; if( ddsd.t.ddpfPixelFormat.dwFourCC == D3DFMT_DXT1 ) pDDSImageData->components = 3; else pDDSImageData->components = 4; return pDDSImageData; } void destroyDDS( DDS_IMAGE_DATA *pDDSImageData ) { if( pDDSImageData != NULL ) { if( pDDSImageData->pixels != NULL ) free( pDDSImageData->pixels ); free( pDDSImageData ); } } int loadCompressedTexture( DDS_IMAGE_DATA *pDDSImageData ) { int g_compressedTextureID; 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; int i; // Load the mip-map levels for( 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); } } return g_compressedTextureID; } int ddsInit() { char *ext = (char*)glGetString( GL_EXTENSIONS ); if( strstr( ext, "ARB_texture_compression" ) == NULL ) { // MessageBox(NULL,"ARB_texture_compression extension was not found", // "ERROR",MB_OK|MB_ICONEXCLAMATION); return -1; } else { // glCompressedTexImage2DARB = (PFNGLCOMPRESSEDTEXIMAGE2DARBPROC)glxGetProcAddress("glCompressedTexImage2DARB"); // if( !glCompressedTexImage2DARB ) // { // MessageBox(NULL,"One or more ARB_texture_compression functions were not found", // "ERROR",MB_OK|MB_ICONEXCLAMATION); // return -2; // } } return 0; }