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.
80 lines
2.5 KiB
80 lines
2.5 KiB
#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
|
|
|