#include "Images.hpp" using namespace render; std::unique_ptr (*Texture::loadFunc)(const std::string&, const sampling&) = nullptr; std::unique_ptr (*TextureCube::loadFunc)(const std::array&, const Texture::sampling &) = nullptr; std::unique_ptr (*TextureArray::loadFunc)(const std::vector&, const Texture::sampling &) = nullptr; #include #include #include #define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII #define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII #define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII std::optional Image::Read(const std::string& imagepath, std::vector& data, bool srgb) { unsigned char header[124]; properties info; FILE *fp; /* try to open the file */ fp = fopen(imagepath.c_str(), "rb"); if (fp == NULL){ printf("%s could not be opened.\n", imagepath.c_str()); getchar(); return {}; } /* verify the type of file */ char filecode[4]; fread(filecode, 1, 4, fp); if (strncmp(filecode, "DDS ", 4) != 0) { fclose(fp); return {}; } /* get the surface desc */ fread(&header, 124, 1, fp); info.size.height = *(unsigned int*)&(header[8 ]); info.size.width = *(unsigned int*)&(header[12]); unsigned int linearSize = *(unsigned int*)&(header[16]); info.mipmapLevels = *(unsigned int*)&(header[24]); unsigned int fourCC = *(unsigned int*)&(header[80]); /* how big is it going to be including all mipmaps? */ unsigned int bufsize = info.mipmapLevels > 1 ? linearSize * 2 : linearSize; data.resize(bufsize); fread(data.data(), 1, bufsize, fp); /* close the file pointer */ fclose(fp); switch(fourCC) { case FOURCC_DXT3: info.format = srgb ? Format::BC2 : Format::BC2_UNORM; break; case FOURCC_DXT5: info.format = srgb ? Format::BC3 : Format::BC3_UNORM; break; //MAYBE: VK_FORMAT_BC6H_SFLOAT_BLOCK default: return {}; } //FIXME: miplevels with size < block size (2 last) are corrupted const uint32_t maxMipmapLevels = 1 + std::floor(std::log2(std::max(info.size.height, info.size.width))) - 2; info.mipmapLevels = std::min(maxMipmapLevels, info.mipmapLevels); return info; }