You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and dots ('.'), can be up to 35 characters long. Letters must be lowercase.
		
		
		
		
		
			
		
			
				
					
					
						
							790 lines
						
					
					
						
							23 KiB
						
					
					
				
			
		
		
	
	
							790 lines
						
					
					
						
							23 KiB
						
					
					
				| /////////////////////////////////////////////////////////////////////////////////////////////////// | |
| // 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
 | |
| 
 |