ImageLoaderParams LoadMipLevel(const hires_mip_level& item, const std::function<u8*(size_t, bool)>& bufferdelegate, bool cacheresult) { ImageLoaderParams imgInfo; imgInfo.releaseresourcesonerror = cacheresult; imgInfo.dst = nullptr; imgInfo.Path = item.path.c_str(); imgInfo.request_buffer_delegate = bufferdelegate; if (item.is_compressed) { ReadDDS(imgInfo); } else { ReadImageFile(imgInfo); } return imgInfo; }
bool Texture::LoadDDS(const std::string & path, const TextureInfo & info, std::ostream & error) { std::ifstream file(path.c_str(), std::ifstream::in | std::ifstream::binary); if (!file) return false; // test for dds magic value char magic[4]; file.read(magic, 4); if (!IsDDS(magic, 4)) return false; // get length of file: file.seekg (0, file.end); const unsigned long length = file.tellg(); file.seekg (0, file.beg); // read file into memory std::vector<char> data(length); file.read(&data[0], length); // load dds const char * texdata(0); unsigned long texlen(0); unsigned format(0), width(0), height(0), levels(0); if (!ReadDDS( (void*)&data[0], length, (const void*&)texdata, texlen, format, width, height, levels)) { return false; } // set properties m_w = width; m_h = height; m_scale = 1.0f; m_alpha = (format != GL_BGR); m_cube = false; // gl3 renderer expects srgb unsigned iformat = format; if (info.srgb) { if (format == GL_BGR) iformat = GL_SRGB8; else if (format == GL_BGRA) iformat = GL_SRGB8_ALPHA8; else if (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) iformat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; else if (format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) iformat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; else if (format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) iformat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; } // load texture assert(!m_id); glGenTextures(1, &m_id); CheckForOpenGLErrors("Texture ID generation", error); glBindTexture(GL_TEXTURE_2D, m_id); SetSampler(info, levels > 1); const char * idata = texdata; unsigned blocklen = 16 * texlen / (width * height); unsigned ilen = texlen; unsigned iw = width; unsigned ih = height; for (unsigned i = 0; i < levels; ++i) { if (format == GL_BGR || format == GL_BGRA) { // fixme: support compression here? ilen = iw * ih * blocklen / 16; glTexImage2D(GL_TEXTURE_2D, i, iformat, iw, ih, 0, format, GL_UNSIGNED_BYTE, idata); } else { ilen = std::max(1u, iw / 4) * std::max(1u, ih / 4) * blocklen; glCompressedTexImage2D(GL_TEXTURE_2D, i, iformat, iw, ih, 0, ilen, idata); } CheckForOpenGLErrors("Texture creation", error); idata += ilen; iw = std::max(1u, iw / 2); ih = std::max(1u, ih / 2); } // force mipmaps for GL3 if (levels == 1) GenerateMipmap(GL_TEXTURE_2D); return true; }