81 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			81 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include <cstdio>
 | |
| #include <glm/gtc/round.hpp>
 | |
| #include "../load_kmg.hpp"
 | |
| #include "filter.hpp"
 | |
| #include "file.hpp"
 | |
| 
 | |
| namespace gli
 | |
| {
 | |
| 	inline bool save_kmg(texture const & Texture, std::vector<char> & Memory)
 | |
| 	{
 | |
| 		if(Texture.empty())
 | |
| 			return false;
 | |
| 
 | |
| 		Memory.resize(sizeof(detail::FOURCC_KMG100) + sizeof(detail::kmgHeader10) + Texture.size());
 | |
| 
 | |
| 		std::memcpy(&Memory[0], detail::FOURCC_KMG100, sizeof(detail::FOURCC_KMG100));
 | |
| 
 | |
| 		std::size_t Offset = sizeof(detail::FOURCC_KMG100);
 | |
| 
 | |
| 		texture::swizzles_type Swizzle = Texture.swizzles();
 | |
| 
 | |
| 		detail::kmgHeader10 & Header = *reinterpret_cast<detail::kmgHeader10*>(&Memory[0] + Offset);
 | |
| 		Header.Endianness = 0x04030201;
 | |
| 		Header.Format = Texture.format();
 | |
| 		Header.Target = Texture.target();
 | |
| 		Header.SwizzleRed = Swizzle[0];
 | |
| 		Header.SwizzleGreen = Swizzle[1];
 | |
| 		Header.SwizzleBlue = Swizzle[2];
 | |
| 		Header.SwizzleAlpha = Swizzle[3];
 | |
| 		Header.PixelWidth = static_cast<std::uint32_t>(Texture.extent().x);
 | |
| 		Header.PixelHeight = static_cast<std::uint32_t>(Texture.extent().y);
 | |
| 		Header.PixelDepth = static_cast<std::uint32_t>(Texture.extent().z);
 | |
| 		Header.Layers = static_cast<std::uint32_t>(Texture.layers());
 | |
| 		Header.Levels = static_cast<std::uint32_t>(Texture.levels());
 | |
| 		Header.Faces = static_cast<std::uint32_t>(Texture.faces());
 | |
| 		Header.GenerateMipmaps = FILTER_NONE;
 | |
| 		Header.BaseLevel = static_cast<std::uint32_t>(Texture.base_level());
 | |
| 		Header.MaxLevel = static_cast<std::uint32_t>(Texture.max_level());
 | |
| 
 | |
| 		Offset += sizeof(detail::kmgHeader10);
 | |
| 
 | |
| 		for(texture::size_type Layer = 0, Layers = Texture.layers(); Layer < Layers; ++Layer)
 | |
| 		for(texture::size_type Level = 0, Levels = Texture.levels(); Level < Levels; ++Level)
 | |
| 		{
 | |
| 			texture::size_type const FaceSize = Texture.size(Level);
 | |
| 			for(texture::size_type Face = 0, Faces = Texture.faces(); Face < Faces; ++Face)
 | |
| 			{
 | |
| 				std::memcpy(&Memory[0] + Offset, Texture.data(Layer, Face, Level), FaceSize);
 | |
| 
 | |
| 				Offset += FaceSize;
 | |
| 				GLI_ASSERT(Offset <= Memory.size());
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return true;
 | |
| 	}
 | |
| 
 | |
| 	inline bool save_kmg(texture const & Texture, char const * Filename)
 | |
| 	{
 | |
| 		if(Texture.empty())
 | |
| 			return false;
 | |
| 
 | |
| 		FILE* File = detail::open_file(Filename, "wb");
 | |
| 		if(!File)
 | |
| 			return false;
 | |
| 
 | |
| 		std::vector<char> Memory;
 | |
| 		bool const Result = save_kmg(Texture, Memory);
 | |
| 
 | |
| 		std::fwrite(&Memory[0], 1, Memory.size(), File);
 | |
| 		std::fclose(File);
 | |
| 
 | |
| 		return Result;
 | |
| 	}
 | |
| 
 | |
| 	inline bool save_kmg(texture const & Texture, std::string const & Filename)
 | |
| 	{
 | |
| 		return save_kmg(Texture, Filename.c_str());
 | |
| 	}
 | |
| }//namespace gli
 | 
