791 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			791 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| ///////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| // OpenGL Image Copyright (c) 2008 - 2011 G-Truc Creation (www.g-truc.net)
 | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| // Created : 2010-09-08
 | |
| // Updated : 2010-09-27
 | |
| // Licence : This source is under MIT License
 | |
| // File    : gli/gtx/loader_dds9.inl
 | |
| ///////////////////////////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| namespace gli{
 | |
| namespace gtx{
 | |
| namespace loader_dds9{
 | |
| namespace detail
 | |
| {
 | |
| 	// DDS Documentation
 | |
| 	/*
 | |
| 		http://msdn.microsoft.com/en-us/library/bb943991(VS.85).aspx#File_Layout1
 | |
| 		http://msdn.microsoft.com/en-us/library/bb943992.aspx
 | |
| 	*/
 | |
| 
 | |
| 	#define GLI_MAKEFOURCC(ch0, ch1, ch2, ch3) \
 | |
| 	  (glm::uint32)( \
 | |
| 		(((glm::uint32)(glm::uint8)(ch3) << 24) & 0xFF000000) | \
 | |
| 		(((glm::uint32)(glm::uint8)(ch2) << 16) & 0x00FF0000) | \
 | |
| 		(((glm::uint32)(glm::uint8)(ch1) <<  8) & 0x0000FF00) | \
 | |
| 		 ((glm::uint32)(glm::uint8)(ch0)        & 0x000000FF) )
 | |
| 
 | |
| 	//enum dds_format
 | |
| 	//{
 | |
| 	//	GLI_D3DFMT_R8G8B8               = 20,
 | |
| 	//	GLI_D3DFMT_A8R8G8B8             = 21,
 | |
| 	//	GLI_D3DFMT_X8R8G8B8             = 22,
 | |
| 	//	GLI_D3DFMT_A8                   = 28,
 | |
| 	//	GLI_D3DFMT_A2B10G10R10          = 31,
 | |
| 	//	GLI_D3DFMT_A8B8G8R8             = 32,
 | |
| 	//	GLI_D3DFMT_X8B8G8R8             = 33,
 | |
| 	//	GLI_D3DFMT_G16R16               = 34,
 | |
| 	//	GLI_D3DFMT_A2R10G10B10          = 35,
 | |
| 	//	GLI_D3DFMT_A16B16G16R16         = 36,
 | |
| 
 | |
| 	//	GLI_D3DFMT_L8                   = 50,
 | |
| 	//	GLI_D3DFMT_A8L8                 = 51,
 | |
| 
 | |
| 	//	GLI_D3DFMT_DXT1                 = GLI_MAKEFOURCC('D', 'X', 'T', '1'),
 | |
| 	//	GLI_D3DFMT_DXT2                 = GLI_MAKEFOURCC('D', 'X', 'T', '2'),
 | |
| 	//	GLI_D3DFMT_DXT3                 = GLI_MAKEFOURCC('D', 'X', 'T', '3'),
 | |
| 	//	GLI_D3DFMT_DXT4                 = GLI_MAKEFOURCC('D', 'X', 'T', '4'),
 | |
| 	//	GLI_D3DFMT_DXT5                 = GLI_MAKEFOURCC('D', 'X', 'T', '5'),
 | |
| 	//	GLI_D3DFMT_DX10                 = GLI_MAKEFOURCC('D', 'X', '1', '0'),
 | |
| 
 | |
| 	//	GLI_D3DFMT_D32                  = 71,
 | |
| 	//	GLI_D3DFMT_D24S8                = 75,
 | |
| 	//	GLI_D3DFMT_D24X8                = 77,
 | |
| 	//	GLI_D3DFMT_D16                  = 80,
 | |
| 	//	GLI_D3DFMT_L16                  = 81,
 | |
| 	//	GLI_D3DFMT_D32F_LOCKABLE        = 82,
 | |
| 	//	GLI_D3DFMT_D24FS8               = 83,
 | |
| 
 | |
| 	//	GLI_D3DFMT_R16F                 = 111,
 | |
| 	//	GLI_D3DFMT_G16R16F              = 112,
 | |
| 	//	GLI_D3DFMT_A16B16G16R16F        = 113,
 | |
| 
 | |
| 	//	GLI_D3DFMT_R32F                 = 114,
 | |
| 	//	GLI_D3DFMT_G32R32F              = 115,
 | |
| 	//	GLI_D3DFMT_A32B32G32R32F        = 116
 | |
| 	//};
 | |
| 
 | |
| 	enum ddsCubemapflag
 | |
| 	{
 | |
| 		GLI_DDSCAPS2_CUBEMAP				= 0x00000200,
 | |
| 		GLI_DDSCAPS2_CUBEMAP_POSITIVEX		= 0x00000400,
 | |
| 		GLI_DDSCAPS2_CUBEMAP_NEGATIVEX		= 0x00000800,
 | |
| 		GLI_DDSCAPS2_CUBEMAP_POSITIVEY		= 0x00001000,
 | |
| 		GLI_DDSCAPS2_CUBEMAP_NEGATIVEY		= 0x00002000,
 | |
| 		GLI_DDSCAPS2_CUBEMAP_POSITIVEZ		= 0x00004000,
 | |
| 		GLI_DDSCAPS2_CUBEMAP_NEGATIVEZ		= 0x00008000,
 | |
| 		GLI_DDSCAPS2_VOLUME					= 0x00200000
 | |
| 	};
 | |
| 
 | |
| 	enum ddsSurfaceflag
 | |
| 	{
 | |
| 		GLI_DDSCAPS_COMPLEX				= 0x00000008,
 | |
| 		GLI_DDSCAPS_MIPMAP				= 0x00400000,
 | |
| 		GLI_DDSCAPS_TEXTURE				= 0x00001000
 | |
| 	};
 | |
| 
 | |
| 	struct ddsPixelFormat
 | |
| 	{
 | |
| 		glm::uint32 size; // 32
 | |
| 		glm::uint32 flags;
 | |
| 		glm::uint32 fourCC;
 | |
| 		glm::uint32 bpp;
 | |
| 		glm::uint32 redMask;
 | |
| 		glm::uint32 greenMask;
 | |
| 		glm::uint32 blueMask;
 | |
| 		glm::uint32 alphaMask;
 | |
| 	};
 | |
| 
 | |
| 	struct ddsHeader
 | |
| 	{
 | |
| 		glm::uint32 size;
 | |
| 		glm::uint32 flags;
 | |
| 		glm::uint32 height;
 | |
| 		glm::uint32 width;
 | |
| 		glm::uint32 pitch;
 | |
| 		glm::uint32 depth;
 | |
| 		glm::uint32 mipMapLevels;
 | |
| 		glm::uint32 reserved1[11];
 | |
| 		ddsPixelFormat format;
 | |
| 		glm::uint32 surfaceFlags;
 | |
| 		glm::uint32 cubemapFlags;
 | |
| 		glm::uint32 reserved2[3];
 | |
| 	};
 | |
| 
 | |
| 	glm::uint32 const GLI_D3DFMT_R8G8B8  = 20;
 | |
| 	glm::uint32 const GLI_D3DFMT_A8R8G8B8 = 21;
 | |
| 	glm::uint32 const GLI_D3DFMT_X8R8G8B8 = 22;
 | |
| 	glm::uint32 const GLI_D3DFMT_R5G6B5 = 23;
 | |
| 	glm::uint32 const GLI_D3DFMT_X1R5G5B5 = 24;
 | |
| 	glm::uint32 const GLI_D3DFMT_A1R5G5B5 = 25;
 | |
| 	glm::uint32 const GLI_D3DFMT_A4R4G4B4 = 26;
 | |
| 	glm::uint32 const GLI_D3DFMT_X4R4G4B4 = 30;
 | |
| 	glm::uint32 const GLI_D3DFMT_A2B10G10R10 = 31;
 | |
| 	glm::uint32 const GLI_D3DFMT_A8B8G8R8 = 32;
 | |
| 	glm::uint32 const GLI_D3DFMT_X8B8G8R8 = 33;
 | |
| 	glm::uint32 const GLI_D3DFMT_G16R16 = 34;
 | |
| 	glm::uint32 const GLI_D3DFMT_A2R10G10B10 = 35;
 | |
| 	glm::uint32 const GLI_D3DFMT_A16B16G16R16 = 36;
 | |
| 
 | |
| 
 | |
| 	glm::uint32 const GLI_FOURCC_DXT1 = GLI_MAKEFOURCC('D', 'X', 'T', '1');
 | |
| 	glm::uint32 const GLI_FOURCC_DXT2 = GLI_MAKEFOURCC('D', 'X', 'T', '2');
 | |
| 	glm::uint32 const GLI_FOURCC_DXT3 = GLI_MAKEFOURCC('D', 'X', 'T', '3');
 | |
| 	glm::uint32 const GLI_FOURCC_DXT4 = GLI_MAKEFOURCC('D', 'X', 'T', '4');
 | |
| 	glm::uint32 const GLI_FOURCC_DXT5 = GLI_MAKEFOURCC('D', 'X', 'T', '5');
 | |
| 	glm::uint32 const GLI_FOURCC_ATI1 = GLI_MAKEFOURCC('A', 'T', 'I', '1');			// ATI1
 | |
| 	glm::uint32 const GLI_FOURCC_ATI2 = GLI_MAKEFOURCC('A', 'T', 'I', '2');			// ATI2 (AKA 3Dc)
 | |
| 	glm::uint32 const GLI_FOURCC_DX10 = GLI_MAKEFOURCC('D', 'X', '1', '0');
 | |
| 	glm::uint32 const GLI_FOURCC_BC4U = GLI_MAKEFOURCC('B', 'C', '4', 'U');
 | |
| 	glm::uint32 const GLI_FOURCC_BC4S = GLI_MAKEFOURCC('B', 'C', '4', 'S');
 | |
| 	glm::uint32 const GLI_FOURCC_BC5U = GLI_MAKEFOURCC('B', 'C', '5', 'U');
 | |
| 	glm::uint32 const GLI_FOURCC_BC5S = GLI_MAKEFOURCC('B', 'C', '5', 'S');
 | |
| 	glm::uint32 const GLI_FOURCC_BC6H = GLI_MAKEFOURCC('B', 'C', '6', 'H');
 | |
| 	glm::uint32 const GLI_FOURCC_BC7  = GLI_MAKEFOURCC('B', 'C', '7', 'U');
 | |
| 
 | |
| 	glm::uint32 const GLI_FOURCC_R16F                          = 0x0000006f;         // 16-bit float Red
 | |
| 	glm::uint32 const GLI_FOURCC_G16R16F                       = 0x00000070;         // 16-bit float Red/Green
 | |
| 	glm::uint32 const GLI_FOURCC_A16B16G16R16F                 = 0x00000071;         // 16-bit float RGBA
 | |
| 	glm::uint32 const GLI_FOURCC_R32F                          = 0x00000072;         // 32-bit float Red
 | |
| 	glm::uint32 const GLI_FOURCC_G32R32F                       = 0x00000073;         // 32-bit float Red/Green
 | |
| 	glm::uint32 const GLI_FOURCC_A32B32G32R32F                 = 0x00000074;         // 32-bit float RGBA
 | |
| 
 | |
| 	glm::uint32 const GLI_DDPF_ALPHAPIXELS							= 0x00000001; // The surface has alpha channel information in the pixel format.
 | |
| 	glm::uint32 const GLI_DDPF_ALPHA								= 0x00000002; // The pixel format contains alpha only information
 | |
| 	glm::uint32 const GLI_DDPF_FOURCC                               = 0x00000004; // The FourCC code is valid.
 | |
| 	glm::uint32 const GLI_DDPF_RGB									= 0x00000040; // The RGB data in the pixel format structure is valid.
 | |
| 	//glm::uint32 const GLI_DDPF_COMPRESSED							= 0x00000080; // The surface will accept pixel data in the format specified and compress it during the write.
 | |
| 	//glm::uint32 const GLI_DDPF_RGBTOYUV								= 0x00000100; // The surface will accept RGB data and translate it during the write to YUV data.
 | |
| 	glm::uint32 const GLI_DDPF_YUV                                  = 0x00000200; // Pixel format is YUV - YUV data in pixel format struct is valid.
 | |
| 	//glm::uint32 const GLI_DDPF_ZBUFFER                              = 0x00000400; // Pixel format is a z buffer only surface
 | |
| 	//glm::uint32 const GLI_DDPF_ZPIXELS                              = 0x00002000; // The surface contains Z information in the pixels
 | |
| 	//glm::uint32 const GLI_DDPF_STENCILBUFFER                        = 0x00004000; // The surface contains stencil information along with Z
 | |
| 	//glm::uint32 const GLI_DDPF_ALPHAPREMULT                         = 0x00008000; // Premultiplied alpha format -- the color components have been premultiplied by the alpha component.
 | |
| 	glm::uint32 const GLI_DDPF_LUMINANCE                            = 0x00020000; // Luminance data in the pixel format is valid.
 | |
| 	//glm::uint32 const GLI_DDPF_BUMPLUMINANCE                        = 0x00040000; // Use this flag for luminance-only or luminance+alpha surfaces, the bit depth is then ddpf.dwLuminanceBitCount.
 | |
| 	//glm::uint32 const GLI_DDPF_BUMPDUDV                             = 0x00080000; // Bump map dUdV data in the pixel format is valid.
 | |
| 
 | |
| 	glm::uint32 const GLI_DDSD_CAPS				= 0x00000001;
 | |
| 	glm::uint32 const GLI_DDSD_HEIGHT			= 0x00000002;
 | |
| 	glm::uint32 const GLI_DDSD_WIDTH			= 0x00000004;
 | |
| 	glm::uint32 const GLI_DDSD_PITCH			= 0x00000008;
 | |
| 	glm::uint32 const GLI_DDSD_PIXELFORMAT		= 0x00001000;
 | |
| 	glm::uint32 const GLI_DDSD_MIPMAPCOUNT		= 0x00020000;
 | |
| 	glm::uint32 const GLI_DDSD_LINEARSIZE		= 0x00080000;
 | |
| 	glm::uint32 const GLI_DDSD_DEPTH			= 0x00800000;
 | |
| 
 | |
| 	struct DDLoader
 | |
| 	{
 | |
| 		glm::uint32 BlockSize;
 | |
| 		glm::uint32 BPP;
 | |
| 		gli::format Format;
 | |
| 	};
 | |
| 
 | |
| 	enum format_type
 | |
| 	{
 | |
| 		FORMAT_TYPE_NULL,
 | |
| 		FORMAT_RGBA,
 | |
| 		FORMAT_FOURCC
 | |
| 	};
 | |
| 
 | |
| 	inline glm::uint32 getFormatFourCC(gli::texture2D const & Image)
 | |
| 	{
 | |
| 		switch(Image.format())
 | |
| 		{
 | |
| 		default:
 | |
| 			return 0;
 | |
| 		case DXT1:
 | |
| 			return GLI_FOURCC_DXT1;
 | |
| 		case DXT3:
 | |
| 			return GLI_FOURCC_DXT3;
 | |
| 		case DXT5:
 | |
| 			return GLI_FOURCC_DXT5;
 | |
| 		case ATI1N_UNORM:
 | |
| 		case ATI1N_SNORM:
 | |
| 		case ATI2N_UNORM:
 | |
| 		case ATI2N_SNORM:
 | |
| 		case BP_UF16:
 | |
| 		case BP_SF16:
 | |
| 		case BP:
 | |
| 			return GLI_FOURCC_DX10;
 | |
| 		case R16F:
 | |
| 			return GLI_FOURCC_R16F;
 | |
| 		case RG16F:
 | |
| 			return GLI_FOURCC_G16R16F;
 | |
| 		case RGBA16F:
 | |
| 			return GLI_FOURCC_A16B16G16R16F;
 | |
| 		case R32F:
 | |
| 			return GLI_FOURCC_R32F;
 | |
| 		case RG32F:
 | |
| 			return GLI_FOURCC_G32R32F;
 | |
| 		case RGBA32F:
 | |
| 			return GLI_FOURCC_A32B32G32R32F;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	inline glm::uint32 getFormatBlockSize(gli::texture2D const & Image)
 | |
| 	{
 | |
| 		switch(Image.format())
 | |
| 		{
 | |
| 		default:
 | |
| 			return 0;
 | |
| 		case DXT1:
 | |
| 			return 8;
 | |
| 		case DXT3:
 | |
| 			return 16;
 | |
| 		case DXT5:
 | |
| 			return 16;
 | |
| 		case ATI1N_UNORM:
 | |
| 		case ATI1N_SNORM:
 | |
| 			return 16;
 | |
| 		case ATI2N_UNORM:
 | |
| 		case ATI2N_SNORM:
 | |
| 			return 32;
 | |
| 		case BP_UF16:
 | |
| 		case BP_SF16:
 | |
| 			return 32;
 | |
| 		case BP:
 | |
| 			return 32;
 | |
| 		case R16F:
 | |
| 			return 2;
 | |
| 		case RG16F:
 | |
| 			return 4;
 | |
| 		case RGBA16F:
 | |
| 			return 8;
 | |
| 		case R32F:
 | |
| 			return 4;
 | |
| 		case RG32F:
 | |
| 			return 8;
 | |
| 		case RGBA32F:
 | |
| 			return 16;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	inline glm::uint32 getFormatFlags(gli::texture2D const & Image)
 | |
| 	{
 | |
| 		glm::uint32 Result = 0;
 | |
| 
 | |
| 		switch(Image.format())
 | |
| 		{
 | |
| 		default: 
 | |
| 			break;
 | |
| 		case R8U:
 | |
| 		case RG8U:
 | |
| 		case RGB8U:
 | |
| 		case RGBA8U:
 | |
| 		case R16U:
 | |
| 		case RG16U:
 | |
| 		case RGB16U:
 | |
| 		case RGBA16U:
 | |
| 		case R32U:
 | |
| 		case RG32U:
 | |
| 		case RGB32U:
 | |
| 		case RGBA32U:
 | |
| 		case R8I:
 | |
| 		case RG8I:
 | |
| 		case RGB8I:
 | |
| 		case RGBA8I:
 | |
| 		case R16I:
 | |
| 		case RG16I:
 | |
| 		case RGB16I:
 | |
| 		case RGBA16I:
 | |
| 		case R32I:
 | |
| 		case RG32I:
 | |
| 		case RGB32I:
 | |
| 		case RGBA32I:
 | |
| 			Result |= GLI_DDPF_RGB;
 | |
| 			break;
 | |
| 		case R16F:
 | |
| 		case RG16F:
 | |
| 		case RGB16F:
 | |
| 		case RGBA16F:
 | |
| 		case R32F:
 | |
| 		case RG32F:
 | |
| 		case RGB32F:
 | |
| 		case RGBA32F:
 | |
| 		case RGBE8:
 | |
| 		case RGB9E5:
 | |
| 		case RG11B10F:
 | |
| 		case R5G6B5:
 | |
| 		case RGBA4:
 | |
| 		case RGB10A2:
 | |
| 		case D16:
 | |
| 		case D24X8:
 | |
| 		case D24S8:
 | |
| 		case D32F:
 | |
| 		case D32FS8X24:
 | |
| 		case DXT1:
 | |
| 		case DXT3:
 | |
| 		case DXT5:
 | |
| 		case ATI1N_UNORM:
 | |
| 		case ATI1N_SNORM:
 | |
| 		case ATI2N_UNORM:
 | |
| 		case ATI2N_SNORM:
 | |
| 		case BP_UF16:
 | |
| 		case BP_SF16:
 | |
| 		case BP:
 | |
| 			Result |= GLI_DDPF_FOURCC;
 | |
| 			break;
 | |
| 		};
 | |
| 
 | |
| 		return Result;
 | |
| 	}
 | |
| 
 | |
| 	inline glm::uint32 getFormatBPP(gli::texture2D const & Image)
 | |
| 	{
 | |
| 		switch(Image.format())
 | |
| 		{
 | |
| 		default:
 | |
| 			return 0;
 | |
| 		case R8U:
 | |
| 		case R8I:
 | |
| 			return 8;
 | |
| 		case RG8U:
 | |
| 		case RG8I:
 | |
| 			return 16;
 | |
| 		case RGB8U:
 | |
| 		case RGB8I:
 | |
| 			return 24;
 | |
| 		case RGBA8U:
 | |
| 		case RGBA8I:
 | |
| 			return 32;
 | |
| 		case DXT1:
 | |
| 			return 4;
 | |
| 		case DXT3:
 | |
| 			return 8;
 | |
| 		case DXT5:
 | |
| 			return 8;
 | |
| 		case ATI1N_UNORM:
 | |
| 		case ATI1N_SNORM:
 | |
| 			return 4;
 | |
| 		case ATI2N_UNORM:
 | |
| 		case ATI2N_SNORM:
 | |
| 			return 8;
 | |
| 		case BP_UF16:
 | |
| 		case BP_SF16:
 | |
| 			return 8;
 | |
| 		case BP:
 | |
| 			return 8;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	inline bool isCompressed(gli::texture2D const & Image)
 | |
| 	{
 | |
| 		switch(Image.format())
 | |
| 		{
 | |
| 		default:
 | |
| 			return false;
 | |
| 		case DXT1:
 | |
| 		case DXT3:
 | |
| 		case DXT5:
 | |
| 		case ATI1N_UNORM:
 | |
| 		case ATI1N_SNORM:
 | |
| 		case ATI2N_UNORM:
 | |
| 		case ATI2N_SNORM:
 | |
| 		case BP_UF16:
 | |
| 		case BP_SF16:
 | |
| 		case BP:
 | |
| 			return true;
 | |
| 		}
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| }//namespace detail
 | |
| 
 | |
| 	inline texture2D loadDDS9
 | |
| 	(
 | |
| 		std::string const & Filename
 | |
| 	)
 | |
| 	{
 | |
| 		std::ifstream FileIn(Filename.c_str(), std::ios::in | std::ios::binary);
 | |
| 		if(FileIn.fail())
 | |
| 			return texture2D();
 | |
| 
 | |
| 		detail::ddsHeader SurfaceDesc;
 | |
| 		char Magic[4]; 
 | |
| 
 | |
| 		//* Read magic number and check if valid .dds file 
 | |
| 		FileIn.read((char*)&Magic, sizeof(Magic));
 | |
| 
 | |
| 		assert(strncmp(Magic, "DDS ", 4) == 0);
 | |
| 
 | |
| 		// Get the surface descriptor 
 | |
| 		FileIn.read((char*)&SurfaceDesc, sizeof(SurfaceDesc));
 | |
| 
 | |
| 		std::size_t Width = SurfaceDesc.width;
 | |
| 		std::size_t Height = SurfaceDesc.height;
 | |
| 
 | |
| 		//std::size_t Levels = glm::max(glm::highestBit(Width), glm::highestBit(Height));
 | |
| 
 | |
| 		detail::DDLoader Loader;
 | |
| 		if(SurfaceDesc.format.flags & detail::GLI_DDPF_FOURCC)
 | |
| 		{
 | |
| 			switch(SurfaceDesc.format.fourCC)
 | |
| 			{
 | |
| 			case detail::GLI_FOURCC_DX10:
 | |
| 				assert(0);
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_DXT1:
 | |
| 				Loader.BlockSize = 8;
 | |
| 				Loader.Format = DXT1;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_DXT3:
 | |
| 				Loader.BlockSize = 16;
 | |
| 				Loader.Format = DXT3;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_DXT5:
 | |
| 				Loader.BlockSize = 16;
 | |
| 				Loader.Format = DXT5;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_R16F:
 | |
| 				Loader.BlockSize = 2;
 | |
| 				Loader.Format = R16F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_G16R16F:
 | |
| 				Loader.BlockSize = 4;
 | |
| 				Loader.Format = RG16F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_A16B16G16R16F:
 | |
| 				Loader.BlockSize = 8;
 | |
| 				Loader.Format = RGBA16F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_R32F:
 | |
| 				Loader.BlockSize = 4;
 | |
| 				Loader.Format = R32F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_G32R32F:
 | |
| 				Loader.BlockSize = 8;
 | |
| 				Loader.Format = RG32F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_A32B32G32R32F:
 | |
| 				Loader.BlockSize = 16;
 | |
| 				Loader.Format = RGBA32F;
 | |
| 				break;
 | |
| 
 | |
| 			default:
 | |
| 				assert(0);
 | |
| 				return texture2D();
 | |
| 			}
 | |
| 		}
 | |
| 		else if(SurfaceDesc.format.flags & detail::GLI_DDPF_RGB)
 | |
| 		{
 | |
| 			switch(SurfaceDesc.format.bpp)
 | |
| 			{
 | |
| 			case 8:
 | |
| 				Loader.BlockSize = 2;
 | |
| 				Loader.Format = R8U;
 | |
| 				break;
 | |
| 			case 16:
 | |
| 				Loader.BlockSize = 2;
 | |
| 				Loader.Format = RG8U;
 | |
| 				break;
 | |
| 			case 24:
 | |
| 				Loader.BlockSize = 3;
 | |
| 				Loader.Format = RGB8U;
 | |
| 				break;
 | |
| 			case 32:
 | |
| 				Loader.BlockSize = 4;
 | |
| 				Loader.Format = RGBA8U;
 | |
| 				break;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		gli::format Format = Loader.Format;
 | |
| 
 | |
| 		std::streamoff Curr = FileIn.tellg();
 | |
| 		FileIn.seekg(0, std::ios_base::end);
 | |
| 		std::streamoff End = FileIn.tellg();
 | |
| 		FileIn.seekg(Curr, std::ios_base::beg);
 | |
| 
 | |
| 		std::vector<glm::byte> Data(std::size_t(End - Curr), 0);
 | |
| 		std::size_t Offset = 0;
 | |
| 
 | |
| 		FileIn.read((char*)&Data[0], std::streamsize(Data.size()));
 | |
| 
 | |
| 		//image Image(glm::min(MipMapCount, Levels));//SurfaceDesc.mipMapLevels);
 | |
| 		std::size_t MipMapCount = (SurfaceDesc.flags & detail::GLI_DDSD_MIPMAPCOUNT) ? SurfaceDesc.mipMapLevels : 1;
 | |
| 		//if(Loader.Format == DXT1 || Loader.Format == DXT3 || Loader.Format == DXT5) 
 | |
| 		//	MipMapCount -= 2;
 | |
| 		texture2D Image(MipMapCount);
 | |
| 		for(std::size_t Level = 0; Level < Image.levels() && (Width || Height); ++Level)
 | |
| 		{
 | |
| 			Width = glm::max(std::size_t(Width), std::size_t(1));
 | |
| 			Height = glm::max(std::size_t(Height), std::size_t(1));
 | |
| 
 | |
| 			std::size_t MipmapSize = 0;
 | |
| 			if(Loader.Format == DXT1 || Loader.Format == DXT3 || Loader.Format == DXT5)
 | |
| 				MipmapSize = ((Width + 3) >> 2) * ((Height + 3) >> 2) * Loader.BlockSize;
 | |
| 			else
 | |
| 				MipmapSize = Width * Height * Loader.BlockSize;
 | |
| 			std::vector<glm::byte> MipmapData(MipmapSize, 0);
 | |
| 
 | |
| 			memcpy(&MipmapData[0], &Data[0] + Offset, MipmapSize);
 | |
| 
 | |
| 			image2D::dimensions_type Dimensions(Width, Height);
 | |
| 			Image[Level] = image2D(Dimensions, Format, MipmapData);
 | |
| 
 | |
| 			Offset += MipmapSize;
 | |
| 			Width >>= 1;
 | |
| 			Height >>= 1;
 | |
| 		}
 | |
| 
 | |
| 		return Image;
 | |
| 	}
 | |
| 
 | |
| 	inline textureCube loadTextureCubeDDS9
 | |
| 	(
 | |
| 		std::string const & Filename
 | |
| 	)
 | |
| 	{
 | |
| 		std::ifstream FileIn(Filename.c_str(), std::ios::in | std::ios::binary);
 | |
| 		if(FileIn.fail())
 | |
| 			return textureCube();
 | |
| 
 | |
| 		detail::ddsHeader SurfaceDesc;
 | |
| 		char Magic[4]; 
 | |
| 
 | |
| 		//* Read magic number and check if valid .dds file 
 | |
| 		FileIn.read((char*)&Magic, sizeof(Magic));
 | |
| 
 | |
| 		assert(strncmp(Magic, "DDS ", 4) == 0);
 | |
| 
 | |
| 		// Get the surface descriptor 
 | |
| 		FileIn.read((char*)&SurfaceDesc, sizeof(SurfaceDesc));
 | |
| 
 | |
| 		std::size_t Width = SurfaceDesc.width;
 | |
| 		std::size_t Height = SurfaceDesc.height;
 | |
| 
 | |
| 		//std::size_t Levels = glm::max(glm::highestBit(Width), glm::highestBit(Height));
 | |
| 
 | |
| 		detail::DDLoader Loader;
 | |
| 		if(SurfaceDesc.format.flags & detail::GLI_DDPF_FOURCC)
 | |
| 		{
 | |
| 			switch(SurfaceDesc.format.fourCC)
 | |
| 			{
 | |
| 			case detail::GLI_FOURCC_DX10:
 | |
| 				assert(0);
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_DXT1:
 | |
| 				Loader.BlockSize = 8;
 | |
| 				Loader.Format = DXT1;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_DXT3:
 | |
| 				Loader.BlockSize = 16;
 | |
| 				Loader.Format = DXT3;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_DXT5:
 | |
| 				Loader.BlockSize = 16;
 | |
| 				Loader.Format = DXT5;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_R16F:
 | |
| 				Loader.BlockSize = 2;
 | |
| 				Loader.Format = R16F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_G16R16F:
 | |
| 				Loader.BlockSize = 4;
 | |
| 				Loader.Format = RG16F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_A16B16G16R16F:
 | |
| 				Loader.BlockSize = 8;
 | |
| 				Loader.Format = RGBA16F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_R32F:
 | |
| 				Loader.BlockSize = 4;
 | |
| 				Loader.Format = R32F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_G32R32F:
 | |
| 				Loader.BlockSize = 8;
 | |
| 				Loader.Format = RG32F;
 | |
| 				break;
 | |
| 			case detail::GLI_FOURCC_A32B32G32R32F:
 | |
| 				Loader.BlockSize = 16;
 | |
| 				Loader.Format = RGBA32F;
 | |
| 				break;
 | |
| 
 | |
| 			default:
 | |
| 				assert(0);
 | |
| 				return textureCube();
 | |
| 			}
 | |
| 		}
 | |
| 		else if(SurfaceDesc.format.flags & detail::GLI_DDPF_RGB)
 | |
| 		{
 | |
| 			switch(SurfaceDesc.format.bpp)
 | |
| 			{
 | |
| 			case 8:
 | |
| 				Loader.BlockSize = 2;
 | |
| 				Loader.Format = R8U;
 | |
| 				break;
 | |
| 			case 16:
 | |
| 				Loader.BlockSize = 2;
 | |
| 				Loader.Format = RG8U;
 | |
| 				break;
 | |
| 			case 24:
 | |
| 				Loader.BlockSize = 3;
 | |
| 				Loader.Format = RGB8U;
 | |
| 				break;
 | |
| 			case 32:
 | |
| 				Loader.BlockSize = 4;
 | |
| 				Loader.Format = RGBA8U;
 | |
| 				break;
 | |
| 			}
 | |
| 		}
 | |
| 		else
 | |
| 		{
 | |
| 
 | |
| 		}
 | |
| 
 | |
| 		gli::format Format = Loader.Format;
 | |
| 
 | |
| 		std::streamoff Curr = FileIn.tellg();
 | |
| 		FileIn.seekg(0, std::ios_base::end);
 | |
| 		std::streamoff End = FileIn.tellg();
 | |
| 		FileIn.seekg(Curr, std::ios_base::beg);
 | |
| 
 | |
| 		std::vector<glm::byte> Data(std::size_t(End - Curr), 0);
 | |
| 		std::size_t Offset = 0;
 | |
| 
 | |
| 		FileIn.read((char*)&Data[0], std::streamsize(Data.size()));
 | |
| 
 | |
| 		//image Image(glm::min(MipMapCount, Levels));//SurfaceDesc.mipMapLevels);
 | |
| 		std::size_t MipMapCount = (SurfaceDesc.flags & detail::GLI_DDSD_MIPMAPCOUNT) ? SurfaceDesc.mipMapLevels : 1;
 | |
| 		//if(Loader.Format == DXT1 || Loader.Format == DXT3 || Loader.Format == DXT5) 
 | |
| 		//	MipMapCount -= 2;
 | |
| 		textureCube Texture(MipMapCount);
 | |
| 
 | |
| 		for(textureCube::size_type Face = 0; Face < FACE_MAX; ++Face)
 | |
| 		{
 | |
| 			Width = SurfaceDesc.width;
 | |
| 			Height = SurfaceDesc.height;
 | |
| 
 | |
| 			for(textureCube::size_type Level = 0; Level < Texture.levels() && (Width || Height); ++Level)
 | |
| 			{
 | |
| 				Width = glm::max(std::size_t(Width), std::size_t(1));
 | |
| 				Height = glm::max(std::size_t(Height), std::size_t(1));
 | |
| 
 | |
| 				std::size_t MipmapSize = 0;
 | |
| 				if(Loader.Format == DXT1 || Loader.Format == DXT3 || Loader.Format == DXT5)
 | |
| 					MipmapSize = ((Width + 3) >> 2) * ((Height + 3) >> 2) * Loader.BlockSize;
 | |
| 				else
 | |
| 					MipmapSize = Width * Height * Loader.BlockSize;
 | |
| 				std::vector<glm::byte> MipmapData(MipmapSize, 0);
 | |
| 
 | |
| 				memcpy(&MipmapData[0], &Data[0] + Offset, MipmapSize);
 | |
| 
 | |
| 				textureCube::dimensions_type Dimensions(Width, Height);
 | |
| 				Texture[textureCube::face_type(Face)][Level] = image2D(Dimensions, Format, MipmapData);
 | |
| 
 | |
| 				Offset += MipmapSize;
 | |
| 				Width >>= 1;
 | |
| 				Height >>= 1;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return Texture;
 | |
| 	}
 | |
| 
 | |
| 	inline void saveDDS9
 | |
| 	(
 | |
| 		texture2D const & Texture, 
 | |
| 		std::string const & Filename
 | |
| 	)
 | |
| 	{
 | |
| 		std::ofstream FileOut(Filename.c_str(), std::ios::out | std::ios::binary);
 | |
| 		if (!FileOut)
 | |
| 			return;
 | |
| 
 | |
| 		char const * Magic = "DDS ";
 | |
| 		FileOut.write((char*)Magic, sizeof(char) * 4);
 | |
| 
 | |
| 		glm::uint32 Caps = detail::GLI_DDSD_CAPS | detail::GLI_DDSD_HEIGHT | detail::GLI_DDSD_WIDTH | detail::GLI_DDSD_PIXELFORMAT;
 | |
| 
 | |
| 		detail::ddsHeader SurfaceDesc;
 | |
| 		SurfaceDesc.size = sizeof(detail::ddsHeader);
 | |
| 		SurfaceDesc.flags = Caps | (detail::isCompressed(Texture) ? detail::GLI_DDSD_LINEARSIZE : detail::GLI_DDSD_PITCH) | (Texture.levels() > 1 ? detail::GLI_DDSD_MIPMAPCOUNT : 0); //659463;
 | |
| 		SurfaceDesc.width = Texture[0].dimensions().x;
 | |
| 		SurfaceDesc.height = Texture[0].dimensions().y;
 | |
| 		SurfaceDesc.pitch = loader_dds9::detail::isCompressed(Texture) ? size(Texture, LINEAR_SIZE) : 32;
 | |
| 		SurfaceDesc.depth = 0;
 | |
| 		SurfaceDesc.mipMapLevels = glm::uint32(Texture.levels());
 | |
| 		SurfaceDesc.format.size = sizeof(detail::ddsPixelFormat);
 | |
| 		SurfaceDesc.format.flags = detail::getFormatFlags(Texture);
 | |
| 		SurfaceDesc.format.fourCC = detail::getFormatFourCC(Texture);
 | |
| 		SurfaceDesc.format.bpp = detail::getFormatBPP(Texture);
 | |
| 		SurfaceDesc.format.redMask = 0;
 | |
| 		SurfaceDesc.format.greenMask = 0;
 | |
| 		SurfaceDesc.format.blueMask = 0;
 | |
| 		SurfaceDesc.format.alphaMask = 0;
 | |
| 		SurfaceDesc.surfaceFlags = detail::GLI_DDSCAPS_TEXTURE | (Texture.levels() > 1 ? detail::GLI_DDSCAPS_MIPMAP : 0);
 | |
| 		SurfaceDesc.cubemapFlags = 0;
 | |
| 
 | |
| 		FileOut.write((char*)&SurfaceDesc, sizeof(SurfaceDesc));
 | |
| 
 | |
| 		for(texture2D::level_type Level = 0; Level < Texture.levels(); ++Level)
 | |
| 		{
 | |
| 			texture2D::size_type ImageSize = size(Texture[Level], gli::LINEAR_SIZE);
 | |
| 			FileOut.write((char*)(Texture[Level].data()), ImageSize);
 | |
| 		}
 | |
| 
 | |
| 		if(FileOut.fail() || FileOut.bad())
 | |
| 			return;
 | |
| 
 | |
| 		FileOut.close ();
 | |
| 	}
 | |
| 
 | |
| 	inline void saveTextureCubeDDS9
 | |
| 	(
 | |
| 		textureCube const & Texture, 
 | |
| 		std::string const & Filename
 | |
| 	)
 | |
| 	{
 | |
| 		std::ofstream FileOut(Filename.c_str(), std::ios::out | std::ios::binary);
 | |
| 		if (!FileOut || Texture.empty())
 | |
| 			return;
 | |
| 
 | |
| 		char const * Magic = "DDS ";
 | |
| 		FileOut.write((char*)Magic, sizeof(char) * 4);
 | |
| 
 | |
| 		glm::uint32 Caps = detail::GLI_DDSD_CAPS | detail::GLI_DDSD_HEIGHT | detail::GLI_DDSD_WIDTH | detail::GLI_DDSD_PIXELFORMAT | detail::GLI_DDSCAPS_COMPLEX;
 | |
| 
 | |
| 		detail::ddsHeader SurfaceDesc;
 | |
| 		SurfaceDesc.size = sizeof(detail::ddsHeader);
 | |
| 		SurfaceDesc.flags = Caps | (detail::isCompressed(Texture[POSITIVE_X]) ? detail::GLI_DDSD_LINEARSIZE : detail::GLI_DDSD_PITCH) | (Texture.levels() > 1 ? detail::GLI_DDSD_MIPMAPCOUNT : 0); //659463;
 | |
| 		SurfaceDesc.width = Texture[POSITIVE_X][0].dimensions().x;
 | |
| 		SurfaceDesc.height = Texture[POSITIVE_X][0].dimensions().y;
 | |
| 		SurfaceDesc.pitch = loader_dds9::detail::isCompressed(Texture[POSITIVE_X]) ? size(Texture[POSITIVE_X], LINEAR_SIZE) : 32;
 | |
| 		SurfaceDesc.depth = 0;
 | |
| 		SurfaceDesc.mipMapLevels = glm::uint32(Texture.levels());
 | |
| 		SurfaceDesc.format.size = sizeof(detail::ddsPixelFormat);
 | |
| 		SurfaceDesc.format.flags = detail::getFormatFlags(Texture[POSITIVE_X]);
 | |
| 		SurfaceDesc.format.fourCC = detail::getFormatFourCC(Texture[POSITIVE_X]);
 | |
| 		SurfaceDesc.format.bpp = detail::getFormatBPP(Texture[POSITIVE_X]);
 | |
| 		SurfaceDesc.format.redMask = 0;
 | |
| 		SurfaceDesc.format.greenMask = 0;
 | |
| 		SurfaceDesc.format.blueMask = 0;
 | |
| 		SurfaceDesc.format.alphaMask = 0;
 | |
| 		SurfaceDesc.surfaceFlags = detail::GLI_DDSCAPS_TEXTURE | (Texture.levels() > 1 ? detail::GLI_DDSCAPS_MIPMAP : 0);
 | |
| 		SurfaceDesc.cubemapFlags = 
 | |
| 			detail::GLI_DDSCAPS2_CUBEMAP | detail::GLI_DDSCAPS2_CUBEMAP_POSITIVEX | detail::GLI_DDSCAPS2_CUBEMAP_NEGATIVEX | detail::GLI_DDSCAPS2_CUBEMAP_POSITIVEY | detail::GLI_DDSCAPS2_CUBEMAP_NEGATIVEY | detail::GLI_DDSCAPS2_CUBEMAP_POSITIVEZ | detail::GLI_DDSCAPS2_CUBEMAP_NEGATIVEZ;
 | |
| 
 | |
| 		FileOut.write((char*)&SurfaceDesc, sizeof(SurfaceDesc));
 | |
| 
 | |
| 		for(textureCube::size_type Face = 0; Face < FACE_MAX; ++Face)
 | |
| 		for(texture2D::level_type Level = 0; Level < Texture.levels(); ++Level)
 | |
| 		{
 | |
| 			texture2D::size_type ImageSize = size(Texture[textureCube::face_type(Face)][Level], gli::LINEAR_SIZE);
 | |
| 			FileOut.write((char*)(Texture[textureCube::face_type(Face)][Level].data()), ImageSize);
 | |
| 		}
 | |
| 
 | |
| 		if(FileOut.fail() || FileOut.bad())
 | |
| 			return;
 | |
| 
 | |
| 		FileOut.close ();
 | |
| 	}
 | |
| 
 | |
| }//namespace loader_dds9
 | |
| }//namespace gtx
 | |
| }//namespace gli
 | 
