Skip to content

Commit

Permalink
Optimize texture loading
Browse files Browse the repository at this point in the history
Textures are only refreshed when the soruce file time has changed
A new command called "reloadtextures" was added
  • Loading branch information
BlueAmulet committed Feb 22, 2021
1 parent 6eafc46 commit 49576ee
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 18 deletions.
28 changes: 28 additions & 0 deletions ConsoleUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using HarmonyLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace VSideLoader
{
[HarmonyPatch(typeof(Console), "InputText")]
internal static class ConsoleUtils
{
public static void Postfix(ref Console __instance)
{
string text = __instance.m_input.text;
string[] array = text.Split(' ');
if (array.Length > 0)
{
if (array[0] == "reloadtextures")
{
TextureReplacement.HandleTextures(false);
__instance.Print("Reloaded textures");
}
}
}
}
}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ BepInEx\plugins\Textures\Dump
BepInEx\plugins\Textures\Load
It will also create a config file at BepInEx\config\VSideLoader.cfg

VSideLoader adds a new command called "reloadtextures", to quickly reload textures in game

Dump: (default false)
If enabled, dumps all textures to the `BepInEx\plugins\Textures\Dump` folder
Load: (default true)
Expand Down
21 changes: 21 additions & 0 deletions TextureInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace VSideLoader
{
internal class TextureInfo
{
internal Texture2D tex;
internal DateTime time;

internal TextureInfo(Texture2D tex, DateTime time)
{
this.tex = tex;
this.time = time;
}
}
}
55 changes: 38 additions & 17 deletions TextureReplacement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace VSideLoader
internal static class TextureReplacement
{
private static Dictionary<string, Texture> texSet = new Dictionary<string, Texture>();
private static Dictionary<string, Texture> loadedTextures = new Dictionary<string, Texture>();
private static Dictionary<string, TextureInfo> loadedTextures = new Dictionary<string, TextureInfo>();

private static string[] smokeNames = {
"aoe_smoke_MainTex",
Expand Down Expand Up @@ -53,7 +53,7 @@ internal static class TextureReplacement
"_SnowNormal"
};

internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
internal static void HandleTextures(bool allowDump)
{
string basePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Textures");
string dumpPath = Path.Combine(basePath, "Dump");
Expand All @@ -75,7 +75,7 @@ internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
Texture texture = material.GetTexture(propertyName);
if (texture != null)
{
bool dumpTexture = true;
bool dumpTexture = allowDump;
if (Settings.useTextureName.Value && !Settings.ignoreName.Contains(texture.name))
{
texName = texture.name;
Expand All @@ -92,7 +92,7 @@ internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
{
texName = matTexName;
}
if (Settings.blackList.Contains(texName) || loadedTextures.ContainsValue(texture))
if (Settings.blackList.Contains(texName) || loadedTextures.Any(pair => pair.Value.tex == texture))
{
// ignore texture
dumpTexture = false;
Expand Down Expand Up @@ -145,39 +145,55 @@ internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
if (File.Exists(texPath))
{
Texture2D tex;
bool needsLoad = false;
DateTime time = File.GetLastWriteTime(texPath);
if (loadedTextures.ContainsKey(texPath))
{
tex = (Texture2D)loadedTextures[texPath]; // Reuse existing texture
tex = loadedTextures[texPath].tex; // Reuse existing texture
if (!loadedTextures[texPath].time.Equals(time))
{
needsLoad = true;
}
}
else
{
tex = new Texture2D(2, 2, TextureFormat.RGBA32, true, normalMap.Contains(propertyName));
loadedTextures.Add(texPath, tex);
loadedTextures.Add(texPath, new TextureInfo(tex, new DateTime()));
needsLoad = true;
}
if (texture != null)
{
tex.name = texture.name;
}
tex.filterMode = Settings.textureFilter.Value;
if (tex.LoadImage(File.ReadAllBytes(texPath), !Settings.normalFix.Contains(propertyName)))
if (needsLoad)
{
if (Settings.normalFix.Contains(propertyName) && tex.isReadable)
if (tex.LoadImage(File.ReadAllBytes(texPath), !Settings.normalFix.Contains(propertyName)))
{
Color[] pixels = tex.GetPixels();
for (int i = 0; i < pixels.Length; i++)
if (Settings.normalFix.Contains(propertyName) && tex.isReadable)
{
pixels[i].a = pixels[i].r;
pixels[i].r = 1f;
pixels[i].b = pixels[i].g;
Color[] pixels = tex.GetPixels();
for (int i = 0; i < pixels.Length; i++)
{
pixels[i].a = pixels[i].r;
pixels[i].r = 1f;
pixels[i].b = pixels[i].g;
}
tex.SetPixels(pixels);
}
tex.SetPixels(pixels);
VSideLoader.Logger.LogInfo("Loaded " + Path.GetFileName(texPath) + " (" + tex.width + "x" + tex.height + ") for " + material.name + "." + propertyName);
material.SetTexture(propertyName, tex);
loadedTextures[texPath].time = time;
}
else
{
VSideLoader.Logger.LogError("Failed to load " + Path.GetFileName(texPath));
}
VSideLoader.Logger.LogInfo("Loaded " + Path.GetFileName(texPath) + " (" + tex.width + "x" + tex.height + ") for " + material.name + "." + propertyName);
material.SetTexture(propertyName, tex);
}
else
{
VSideLoader.Logger.LogError("Failed to load " + Path.GetFileName(texPath));
VSideLoader.Logger.LogInfo("Reusing loaded texture " + Path.GetFileName(texPath) + " for " + material.name + "." + propertyName);
material.SetTexture(propertyName, tex);
}
}
}
Expand All @@ -189,6 +205,11 @@ internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
}
}

internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode)
{
HandleTextures(true);
}

private static Texture2D DuplicateTexture(Texture2D source)
{
// TODO: This is causing very slight 1 bit corruption
Expand Down
4 changes: 3 additions & 1 deletion VSideLoader.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="CleanShader.cs" />
<Compile Include="ConsoleUtils.cs" />
<Compile Include="DeferredShader.cs" />
<Compile Include="Settings.cs" />
<Compile Include="TextureInfo.cs" />
<Compile Include="TextureReplacement.cs" />
<Compile Include="VSideLoader.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand Down Expand Up @@ -377,4 +379,4 @@
</Reference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>

0 comments on commit 49576ee

Please sign in to comment.