Tanoda
TextureScale.cs
Go to the documentation of this file.
1using System.Threading;
2using UnityEngine;
3
4public class TextureScale
5{
6 public class ThreadData
7 {
8 public int start;
9 public int end;
10
11 public ThreadData(int s, int e)
12 {
13 start = s;
14 end = e;
15 }
16 }
17
18 private static Color[] texColors;
19 private static Color[] newColors;
20 private static int w;
21 private static float ratioX;
22 private static float ratioY;
23 private static int w2;
24 private static int finishCount;
25 private static Mutex mutex;
26
27 public static void Point(Texture2D tex, int newWidth, int newHeight)
28 {
29 ThreadedScale(tex, newWidth, newHeight, false);
30 }
31
32 public static void Bilinear(Texture2D tex, int newWidth, int newHeight)
33 {
34 ThreadedScale(tex, newWidth, newHeight, true);
35 }
36
37 private static void ThreadedScale(Texture2D tex, int newWidth, int newHeight, bool useBilinear)
38 {
39 texColors = tex.GetPixels();
40 newColors = new Color[newWidth * newHeight];
41 if (useBilinear)
42 {
43 ratioX = 1.0f / ((float) newWidth / (tex.width - 1));
44 ratioY = 1.0f / ((float) newHeight / (tex.height - 1));
45 }
46 else
47 {
48 ratioX = (float) tex.width / newWidth;
49 ratioY = (float) tex.height / newHeight;
50 }
51
52 w = tex.width;
53 w2 = newWidth;
54 var cores = Mathf.Min(SystemInfo.processorCount, newHeight);
55 var slice = newHeight / cores;
56
57 finishCount = 0;
58 if (mutex == null) mutex = new Mutex(false);
59 if (cores > 1)
60 {
61 var i = 0;
62 ThreadData threadData;
63 for (i = 0; i < cores - 1; i++)
64 {
65 threadData = new ThreadData(slice * i, slice * (i + 1));
66 var ts = useBilinear ? BilinearScale : new ParameterizedThreadStart(PointScale);
67 var thread = new Thread(ts);
68 thread.Start(threadData);
69 }
70
71 threadData = new ThreadData(slice * i, newHeight);
72 if (useBilinear)
73 BilinearScale(threadData);
74 else
75 PointScale(threadData);
76 while (finishCount < cores) Thread.Sleep(1);
77 }
78 else
79 {
80 var threadData = new ThreadData(0, newHeight);
81 if (useBilinear)
82 BilinearScale(threadData);
83 else
84 PointScale(threadData);
85 }
86
87 tex.Resize(newWidth, newHeight);
88 tex.SetPixels(newColors);
89 tex.Apply();
90 }
91
92 public static void BilinearScale(object obj)
93 {
94 var threadData = (ThreadData) obj;
95 for (var y = threadData.start; y < threadData.end; y++)
96 {
97 var yFloor = (int) Mathf.Floor(y * ratioY);
98 var y1 = yFloor * w;
99 var y2 = (yFloor + 1) * w;
100 var yw = y * w2;
101
102 for (var x = 0; x < w2; x++)
103 {
104 var xFloor = (int) Mathf.Floor(x * ratioX);
105 var xLerp = x * ratioX - xFloor;
106 newColors[yw + x] = ColorLerpUnclamped(
107 ColorLerpUnclamped(texColors[y1 + xFloor], texColors[y1 + xFloor + 1], xLerp),
108 ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor + 1], xLerp),
109 y * ratioY - yFloor);
110 }
111 }
112
113 mutex.WaitOne();
114 finishCount++;
115 mutex.ReleaseMutex();
116 }
117
118 public static void PointScale(object obj)
119 {
120 var threadData = (ThreadData) obj;
121 for (var y = threadData.start; y < threadData.end; y++)
122 {
123 var thisY = (int) (ratioY * y) * w;
124 var yw = y * w2;
125 for (var x = 0; x < w2; x++) newColors[yw + x] = texColors[(int) (thisY + ratioX * x)];
126 }
127
128 mutex.WaitOne();
129 finishCount++;
130 mutex.ReleaseMutex();
131 }
132
133 private static Color ColorLerpUnclamped(Color c1, Color c2, float value)
134 {
135 return new Color(c1.r + (c2.r - c1.r) * value,
136 c1.g + (c2.g - c1.g) * value,
137 c1.b + (c2.b - c1.b) * value,
138 c1.a + (c2.a - c1.a) * value);
139 }
140}
UnityEngine.Color Color
Definition: TestScript.cs:32
ThreadData(int s, int e)
Definition: TextureScale.cs:11
static void BilinearScale(object obj)
Definition: TextureScale.cs:92
static void PointScale(object obj)
static void Point(Texture2D tex, int newWidth, int newHeight)
Definition: TextureScale.cs:27
static void Bilinear(Texture2D tex, int newWidth, int newHeight)
Definition: TextureScale.cs:32