コード例 #1
0
void TextureCooker::process(
    Vector<VirtFS::VirtDesc>& files, TerminalCursor& cursor)
{
    using FileElement   = Pair<CString, ImageProcessor>;
    using FileContainer = Vector<FileElement>;

    FileContainer targets;

    for(auto& desc : files)
    {
        auto path = Path(desc.filename);

        for(auto ext : imageExtensions)
            /* Check if we recognize the extension */
            if(libc::str::cmp<libc::str::comp_nocase>(
                   path.extension().c_str(), ext.c_str()))
            {
                if(ext == "")
                    continue;
#if defined(HAVE_LIBTIFF)
                else if(ext == "TIFF" || ext == "TIF")
                    targets.push_back({desc.filename, ImageProc_tiff});
#endif
                else
                    targets.push_back({desc.filename, ImageProc_stb});

                continue;
            }
    }

    /* Set default texture sizes, for the cases where nothing is specified.
     * There is also a program-defined default to fallback to. */
    if(Env::ExistsVar(TEX_MAX_SIZE))
        max_texture_size = cast_string<i32>(Env::GetVar(TEX_MAX_SIZE));
    if(Env::ExistsVar(TEX_MIN_SIZE))
        min_texture_size = cast_string<i32>(Env::GetVar(TEX_MIN_SIZE));

    cursor.progress(
        TEXCOMPRESS_API "Compressable textures found: {0}", targets.size());

    Map<ThreadId::Hash, Vector<VirtFS::VirtDesc>> threadFiles;

    /* Each thread works on a texture and its mipmaps. */
    threads::Parallel::ForEach(
        targets,
        static_cast<Function<void(FileElement&)>>([&](FileElement& e) {
            CompressTextureSet(threadFiles[ThreadId().hash()], e, this, cursor);
        }),
        this->numWorkers);

    for(auto& thread : threadFiles)
    {
        files.reserve(files.size() + thread.second.size());

        for(auto& file : thread.second)
            files.push_back(std::move(file));
    }

#if defined(HAVE_LIBTIFF)
    auto removePred = [&](VirtFS::VirtDesc const& desc) {
        for(auto const& e : targets)
            if(e.first == desc.filename)
                return true;

        return false;
    };

    auto removeIt = std::remove_if(files.begin(), files.end(), removePred);

    for(auto it = removeIt; it != files.end(); it++)
        it->data = Bytes();

    files.erase(removeIt, files.end());
#endif
}