Ejemplo n.º 1
0
PC_TexFormat GetHiresTex(u64 key, u32 *pWidth, u32 *pHeight, u32 *required_size, u32 *numMips, s32 texformat, u32 data_size, u8 *dst, bool rgbaonly)
{
	if (texturecount == 0)
	{
		return PC_TEX_FMT_NONE;
	}
	auto iter = textureMap.find(key);
	if (iter == textureMap.end())
		return PC_TEX_FMT_NONE;
	LoadImageInfo imgInfo;
	*required_size = data_size;
	imgInfo.data_size = data_size;
	imgInfo.dst = dst;
	imgInfo.Path = iter->second.first.c_str();
	imgInfo.pHeight = pHeight;
	imgInfo.pWidth = pWidth;
	imgInfo.required_size = required_size;
	imgInfo.nummipmaps = numMips;
	PC_TexFormat returnTex = PC_TEX_FMT_NONE;	
	std::string ddscode(".dds");
	std::string cddscode(".DDS");
	if (iter->second.second.compare(ddscode) == 0 || iter->second.second.compare(cddscode) == 0)
	{
		// We have a dds, try to load compressed data
		returnTex = LoadImageFromFile_DDS(imgInfo);
	}
	else
	{
		texformat = rgbaonly ? GX_TF_RGBA8 : texformat;
		switch (texformat)
		{
		case GX_TF_IA4:
		case GX_TF_IA8:
			imgInfo.desiredTex = PC_TEX_FMT_IA8;
			imgInfo.forcedchannels = SOIL_LOAD_LA;
			imgInfo.formatBPP = 2;
			break;
		default:
			imgInfo.desiredTex = PC_TEX_FMT_RGBA32;
			imgInfo.forcedchannels = SOIL_LOAD_RGBA;
			imgInfo.formatBPP = 4;
			break;
		}
		returnTex = LoadImageFromFile_Soil(imgInfo);
	}
	if (returnTex == PC_TEX_FMT_NONE)
	{
		ERROR_LOG(VIDEO, "Custom texture %s failed to load", imgInfo.Path);
	}
	else
	{
		INFO_LOG(VIDEO, "Loading custom texture from %s", imgInfo.Path);
	}
	return returnTex;
}
Ejemplo n.º 2
0
void HiresTexture::Update()
{
  bool BuildMaterialMaps = g_ActiveConfig.bHiresMaterialMapsBuild;
  if (s_prefetcher.joinable())
  {
    s_textureCacheAbortLoading.Set();
    s_prefetcher.join();
  }

  if (!g_ActiveConfig.bHiresTextures)
  {
    s_textureMap.clear();
    s_textureCache.clear();
    size_sum.store(0);
    return;
  }

  if (!g_ActiveConfig.bCacheHiresTextures)
  {
    s_textureCache.clear();
    size_sum.store(0);
  }

  s_textureMap.clear();
  const std::string& game_id = SConfig::GetInstance().GetGameID();
  const std::string texture_directory = GetTextureDirectory(game_id);

  std::string ddscode(".dds");
  std::string cddscode(".DDS");
  std::vector<std::string> Extensions;
  Extensions.push_back(".png");
  if (!BuildMaterialMaps)
  {
    Extensions.push_back(".dds");
  }

  std::vector<std::string> filenames =
      Common::DoFileSearch({texture_directory}, Extensions, /*recursive*/ true);

  const std::string miptag = "mip";

  for (const std::string& fileitem : filenames)
  {
    std::string filename;
    std::string Extension;
    SplitPath(fileitem, nullptr, &filename, &Extension);
    if (filename.substr(0, s_format_prefix.length()) != s_format_prefix)
    {
      // Discard wrong files
      continue;
    }
    size_t map_index = 0;
    size_t max_type = BuildMaterialMaps ? MapType::specular : MapType::normal;
    bool arbitrary_mips = false;
    for (size_t tag = 1; tag <= MapType::specular; tag++)
    {
      if (StringEndsWith(filename, s_maps_tags[tag]))
      {
        map_index = tag;
        filename = filename.substr(0, filename.size() - s_maps_tags[tag].size());
        break;
      }
    }
    if (map_index > max_type)
    {
      continue;
    }
    if (BuildMaterialMaps && map_index == MapType::material)
    {
      continue;
    }
    else if (!BuildMaterialMaps && map_index == MapType::color)
    {
      const size_t arb_index = filename.rfind("_arb");
      arbitrary_mips = arb_index != std::string::npos;
      if (arbitrary_mips)
        filename.erase(arb_index, 4);
    }
    const bool is_compressed = Extension.compare(ddscode) == 0 || Extension.compare(cddscode) == 0;
    hires_mip_level mip_level_detail(fileitem, Extension, is_compressed);
    u32 level = 0;
    size_t idx = filename.find_last_of('_');
    std::string miplevel = filename.substr(idx + 1, std::string::npos);
    if (miplevel.substr(0, miptag.length()) == miptag)
    {
      sscanf(miplevel.substr(3, std::string::npos).c_str(), "%i", &level);
      filename = filename.substr(0, idx);
    }
    HiresTextureCache::iterator iter = s_textureMap.find(filename);
    u32 min_item_size = level + 1;
    if (iter == s_textureMap.end())
    {
      HiresTextureCacheItem item(min_item_size);
      if (arbitrary_mips)
      {
        item.has_arbitrary_mips = true;
      }
      item.maps[map_index].resize(min_item_size);
      std::vector<hires_mip_level>& dst = item.maps[map_index];
      dst[level] = mip_level_detail;
      s_textureMap.emplace(filename, item);
    }
    else
    {
      std::vector<hires_mip_level>& dst = iter->second.maps[map_index];
      if (arbitrary_mips)
      {
        iter->second.has_arbitrary_mips = true;
      }
      if (dst.size() < min_item_size)
      {
        dst.resize(min_item_size);
      }
      dst[level] = mip_level_detail;
    }
  }

  if (g_ActiveConfig.bCacheHiresTextures && s_textureMap.size() > 0)
  {
    // remove cached but deleted textures
    auto iter = s_textureCache.begin();
    while (iter != s_textureCache.end())
    {
      if (s_textureMap.find(iter->first) == s_textureMap.end())
      {
        size_sum.fetch_sub(iter->second->m_cached_data_size);
        iter = s_textureCache.erase(iter);
      }
      else
      {
        iter++;
      }
    }
    s_textureCacheAbortLoading.Clear();
    s_prefetcher = std::thread(Prefetch);
    if (g_ActiveConfig.bWaitForCacheHiresTextures && s_prefetcher.joinable())
    {
      s_prefetcher.join();
    }
  }
}
Ejemplo n.º 3
0
void HiresTexture::Update()
{
	s_check_native_format = false;
	s_check_new_format = false;

	if (s_prefetcher.joinable())
	{
		s_textureCacheAbortLoading.Set();
		s_prefetcher.join();
	}

	if (!g_ActiveConfig.bHiresTextures)
	{
		s_textureMap.clear();
		s_textureCache.clear();
		size_sum.store(0);
		return;
	}

	if (!g_ActiveConfig.bCacheHiresTextures)
	{
		s_textureCache.clear();
		size_sum.store(0);
	}
	
	s_textureMap.clear();
	const std::string& gameCode = SConfig::GetInstance().m_strUniqueID;
	std::string szDir = StringFromFormat("%s%s", File::GetUserPath(D_HIRESTEXTURES_IDX).c_str(), gameCode.c_str());	
	std::string ddscode(".dds");
	std::string cddscode(".DDS");
	std::vector<std::string> Extensions = {
		".png",
		".dds"
	};

	auto rFilenames = DoFileSearch(Extensions, { szDir }, /*recursive*/ true);

	const std::string code = StringFromFormat("%s_", gameCode.c_str());
	const std::string miptag = "mip";
	const std::string normaltag = ".nrm";
	for (u32 i = 0; i < rFilenames.size(); i++)
	{
		std::string FileName;
		std::string Extension;
		SplitPath(rFilenames[i], nullptr, &FileName, &Extension);
		if (FileName.substr(0, code.length()) == code)
		{
			s_check_native_format = true;
		}
		else if (FileName.substr(0, s_format_prefix.length()) == s_format_prefix)
		{
			s_check_new_format = true;
		}
		else
		{
			// Discard wrong files
			continue;
		}
		const bool is_compressed = Extension.compare(ddscode) == 0 || Extension.compare(cddscode) == 0;
		const bool is_normal_map = hasEnding(FileName, normaltag);
		if (is_normal_map)
		{
			FileName = FileName.substr(0, FileName.size() - normaltag.size());
		}
		hires_mip_level mip_level_detail(rFilenames[i], Extension, is_compressed);
		u32 level = 0;
		size_t idx = FileName.find_last_of('_');
		std::string miplevel = FileName.substr(idx + 1, std::string::npos);
		if (miplevel.substr(0, miptag.length()) == miptag)
		{
			sscanf(miplevel.substr(3, std::string::npos).c_str(), "%i", &level);
			FileName = FileName.substr(0, idx);
		}
		HiresTextureCache::iterator iter = s_textureMap.find(FileName);
		u32 min_item_size = level + 1;
		if (iter == s_textureMap.end())
		{
			HiresTextureCacheItem item(min_item_size);
			if (is_normal_map)
			{
				item.normal_map.resize(min_item_size);
			}
			std::vector<hires_mip_level> &dst = is_normal_map ? item.normal_map : item.color_map;
			dst[level] = mip_level_detail;
			s_textureMap.emplace(FileName, item);
		}
		else
		{
			std::vector<hires_mip_level> &dst = is_normal_map ? iter->second.normal_map : iter->second.color_map;
			if (dst.size() < min_item_size)
			{
				dst.resize(min_item_size);
			}
			dst[level] = mip_level_detail;
		}
	}

	if (g_ActiveConfig.bCacheHiresTextures && s_textureMap.size() > 0)
	{
		// remove cached but deleted textures
		auto iter = s_textureCache.begin();
		while (iter != s_textureCache.end())
		{
			if (s_textureMap.find(iter->first) == s_textureMap.end())
			{
				size_sum.fetch_sub(iter->second->m_cached_data_size);
				iter = s_textureCache.erase(iter);
			}
			else
			{
				iter++;
			}
		}
		s_textureCacheAbortLoading.Clear();
		s_prefetcher = std::thread(Prefetch);
	}
}