-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTextureUtil.cs
156 lines (140 loc) · 5.82 KB
/
TextureUtil.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
using ColossalFramework.UI;
using System;
using System.IO;
using System.Reflection;
using UnityEngine;
namespace ZoneInfo
{
/// <summary>
/// utilities for getting textures (i.e. images)
/// </summary>
/// <remarks>logic adapated from TMPE mod</remarks>
public static class TextureUtil
{
/// <summary>
/// get an embedded image resource from the DLL
/// </summary>
public static Texture2D GetDllResource(string resourceName, int width, int height)
{
try
{
// get the assembly
Assembly assembly = Assembly.GetExecutingAssembly();
if (assembly == null)
{
LogUtil.LogError($"Error getting DLL resource [{resourceName}]: unable to get executing assembly.");
return null;
}
// get the resource stream
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
LogUtil.LogError($"Error getting DLL resource [{resourceName}]: unable to get resource stream.");
return null;
}
// get the resource from the resource stream
using (MemoryStream ms = new MemoryStream())
{
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, bytesRead);
}
byte[] resource = ms.ToArray();
// load the resource into a new texture
Texture2D texture = new Texture2D(width, height, TextureFormat.ARGB32, false);
if (!texture.LoadImage(resource))
{
LogUtil.LogError($"Error getting DLL resource [{resourceName}]: unable to load image into texture.");
return null;
}
// return the texture
return texture;
}
}
}
catch (Exception ex)
{
LogUtil.LogException(ex);
return null;
}
}
/// <summary>
/// generate an atlas from a 1-dimensional resource arranged horizontally
/// </summary>
public static UITextureAtlas GenerateAtlasFromHorizontalResource(string atlasName, Texture2D texture, int numSprites, string[] spriteNames)
{
return GenerateAtlasFrom2DResource(atlasName, texture, numSprites, 1, spriteNames);
}
/// <summary>
/// generate an atlas from a 2-dimensional resource
/// images are obtained from the texture across (x) then down (y)
/// </summary>
public static UITextureAtlas GenerateAtlasFrom2DResource(string atlasName, Texture2D texture, int numX, int numY, string[] spriteNames)
{
// check arguments
if (spriteNames.Length != numX * numY)
{
throw new ArgumentException($"Number of sprite names [{spriteNames.Length}] does not match dimensions: x={numX} y={numY}.");
}
// create a new atlas
UITextureAtlas atlas = ScriptableObject.CreateInstance<UITextureAtlas>();
if (atlas == null)
{
LogUtil.LogError($"Unable to create new atlas.");
return null;
}
atlas.name = atlasName;
atlas.padding = 0;
// initialize the material
Shader shader = Shader.Find("UI/Default UI Shader");
if (shader != null)
{
atlas.material = new Material(shader);
}
atlas.material.mainTexture = texture;
// compute sprite width and height
int spriteWidth = Mathf.RoundToInt(texture.width / (float)numX);
int spriteHeight = Mathf.RoundToInt(texture.height / (float)numY);
// loop over the X
int k = 0;
for (int i = 0; i < numX; ++i)
{
// compute X position
float x = i / (float)numX;
// loop over the Y
for (int j = 0; j < numY; ++j)
{
// compute Y position
float y = j / (float)numY;
// create a new sprite
UITextureAtlas.SpriteInfo sprite = new UITextureAtlas.SpriteInfo
{
name = spriteNames[k],
region = new Rect(
x,
y,
spriteWidth / (float)texture.width,
spriteHeight / (float)texture.height)
};
// set the sprite texture by copying the appropriate pixels from the resource texture
Texture2D spriteTexture = new Texture2D(spriteWidth, spriteHeight);
spriteTexture.SetPixels(
texture.GetPixels(
(int)(texture.width * sprite.region.x),
(int)(texture.height * sprite.region.y),
spriteWidth,
spriteHeight));
sprite.texture = spriteTexture;
// add the sprite to the atlas
atlas.AddSprite(sprite);
++k;
}
}
// return the new atlas
return atlas;
}
}
}