Unstable 1.1.14.0
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using Barotrauma.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Barotrauma.IO;
|
||||
using Lidgren.Network;
|
||||
using Color = Microsoft.Xna.Framework.Color;
|
||||
|
||||
@@ -45,155 +44,117 @@ namespace Barotrauma
|
||||
|
||||
private static byte[] CompressDxt5(byte[] data, int width, int height)
|
||||
{
|
||||
using (System.IO.MemoryStream mstream = new System.IO.MemoryStream())
|
||||
{
|
||||
for (int y = 0; y < height; y += 4)
|
||||
var output = new byte[width * height];
|
||||
Parallel.For(
|
||||
fromInclusive: 0,
|
||||
toExclusive: width * height / 16,
|
||||
i =>
|
||||
{
|
||||
for (int x = 0; x < width; x += 4)
|
||||
{
|
||||
int offset = x * 4 + y * 4 * width;
|
||||
CompressDxt5Block(data, offset, width, mstream);
|
||||
}
|
||||
}
|
||||
return mstream.ToArray();
|
||||
}
|
||||
int i4 = i * 4;
|
||||
int inputOffset = (i4 % width + (i4 / width) * 4 * width) * 4;
|
||||
int outputOffset = i * 16;
|
||||
CompressDxt5Block(data, inputOffset, width, output, outputOffset);
|
||||
});
|
||||
return output;
|
||||
}
|
||||
|
||||
private static void CompressDxt5Block(byte[] data, int offset, int width, System.IO.Stream output)
|
||||
private static void CompressDxt5Block(byte[] data, int inputOffset, int width, byte[] output, int outputOffset)
|
||||
{
|
||||
int r1 = 255, g1 = 255, b1 = 255, a1 = 255;
|
||||
int r2 = 0, g2 = 0, b2 = 0, a2 = 0;
|
||||
|
||||
//determine the two colors to interpolate between:
|
||||
//color 1 represents lowest luma, color 2 represents highest luma
|
||||
// Determine the two colors to interpolate between:
|
||||
// color 1 represents lowest luma, color 2 represents highest luma.
|
||||
// Luma is also used to determine which color on the palette
|
||||
// most closely resembles each pixel to compress, so we
|
||||
// cache our calculations here.
|
||||
int y1 = 255000;
|
||||
int y2 = 0;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int pixelOffset = offset + (4 * ((i % 4) + (width * (i >> 2))));
|
||||
int r, g, b, a;
|
||||
r = data[pixelOffset + 0];
|
||||
g = data[pixelOffset + 1];
|
||||
b = data[pixelOffset + 2];
|
||||
a = data[pixelOffset + 3];
|
||||
if (r * 299 + g * 587 + b * 114 < r1 * 299 + g1 * 587 + b1 * 114)
|
||||
int pixelOffset = inputOffset + (4 * ((i % 4) + (width * (i >> 2))));
|
||||
int r = data[pixelOffset + 0];
|
||||
int g = data[pixelOffset + 1];
|
||||
int b = data[pixelOffset + 2];
|
||||
int a = data[pixelOffset + 3];
|
||||
int y = r * 299 + g * 587 + b * 114;
|
||||
if (y < y1)
|
||||
{
|
||||
r1 = r; g1 = g; b1 = b;
|
||||
r1 = r; g1 = g; b1 = b; y1 = y;
|
||||
}
|
||||
if (r * 299 + g * 587 + b * 114 > r2 * 299 + g2 * 587 + b2 * 114)
|
||||
if (y > y2)
|
||||
{
|
||||
r2 = r; g2 = g; b2 = b;
|
||||
r2 = r; g2 = g; b2 = b; y2 = y;
|
||||
}
|
||||
if (a < a1) { a1 = a; }
|
||||
if (a > a2) { a2 = a; }
|
||||
}
|
||||
|
||||
//convert the colors to rgb565 (16-bit rgb)
|
||||
int r1_565 = (r1 * 0x1f) / 0xff; if (r1_565 > 0x1f) { r1_565 = 0x1f; }
|
||||
int g1_565 = (g1 * 0x3f) / 0xff; if (g1_565 > 0x3f) { g1_565 = 0x3f; }
|
||||
int b1_565 = (b1 * 0x1f) / 0xff; if (b1_565 > 0x1f) { b1_565 = 0x1f; }
|
||||
int r1_565 = r1 >> (8 - 5);
|
||||
int g1_565 = g1 >> (8 - 6);
|
||||
int b1_565 = b1 >> (8 - 5);
|
||||
|
||||
int r2_565 = (r2 * 0x1f) / 0xff; if (r2_565 > 0x1f) { r2_565 = 0x1f; }
|
||||
int g2_565 = (g2 * 0x3f) / 0xff; if (g2_565 > 0x3f) { g2_565 = 0x3f; }
|
||||
int b2_565 = (b2 * 0x1f) / 0xff; if (b2_565 > 0x1f) { b2_565 = 0x1f; }
|
||||
int r2_565 = r2 >> (8 - 5);
|
||||
int g2_565 = g2 >> (8 - 6);
|
||||
int b2_565 = b2 >> (8 - 5);
|
||||
|
||||
//luma is also used to determine which color on the palette
|
||||
//most closely resembles each pixel to compress, so we
|
||||
//calculate this here
|
||||
int y1 = r1 * 299 + g1 * 587 + b1 * 114;
|
||||
int y2 = r2 * 299 + g2 * 587 + b2 * 114;
|
||||
|
||||
byte[] newData = new byte[16];
|
||||
for (int i = 0; i < 16; i++)
|
||||
int y2y1Diff = y2 - y1;
|
||||
if (y2y1Diff > 0 || a1 < a2)
|
||||
{
|
||||
int pixelOffset = offset + (4 * ((i % 4) + (width * (i >> 2))));
|
||||
int r, g, b, a;
|
||||
r = data[pixelOffset + 0];
|
||||
g = data[pixelOffset + 1];
|
||||
b = data[pixelOffset + 2];
|
||||
a = data[pixelOffset + 3];
|
||||
|
||||
if (a1 < a2)
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
a -= a1;
|
||||
a = (a * 0x7) / (a2 - a1);
|
||||
if (a > 0x7) { a = 0x7; }
|
||||
int pixelOffset = inputOffset + (4 * ((i % 4) + (width * (i >> 2))));
|
||||
int r = data[pixelOffset + 0];
|
||||
int g = data[pixelOffset + 1];
|
||||
int b = data[pixelOffset + 2];
|
||||
|
||||
switch (a)
|
||||
if (a1 < a2)
|
||||
{
|
||||
case 0:
|
||||
a = 1;
|
||||
break;
|
||||
case 1:
|
||||
a = 7;
|
||||
break;
|
||||
case 2:
|
||||
a = 6;
|
||||
break;
|
||||
case 3:
|
||||
a = 5;
|
||||
break;
|
||||
case 4:
|
||||
a = 4;
|
||||
break;
|
||||
case 5:
|
||||
a = 3;
|
||||
break;
|
||||
case 6:
|
||||
a = 2;
|
||||
break;
|
||||
case 7:
|
||||
a = 0;
|
||||
break;
|
||||
int a = data[pixelOffset + 3];
|
||||
a -= a1;
|
||||
a = (a * 0x7) / (a2 - a1);
|
||||
if (a < 0x7)
|
||||
{
|
||||
a = a switch
|
||||
{
|
||||
0 => 1,
|
||||
1 => 7,
|
||||
_ => 8 - a
|
||||
};
|
||||
NetBitWriter.WriteByte((byte)a, 3, output, (outputOffset * 8) + 16 + (i * 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a = 0;
|
||||
}
|
||||
|
||||
NetBitWriter.WriteUInt32((uint)a, 3, newData, 16 + (i * 3));
|
||||
if (y2y1Diff <= 0) { continue; }
|
||||
|
||||
int y = r * 299 + g * 587 + b * 114;
|
||||
|
||||
int max = y2 - y1;
|
||||
int diffY = y - y1;
|
||||
|
||||
int paletteIndex;
|
||||
if (diffY < max / 4)
|
||||
{
|
||||
paletteIndex = 0;
|
||||
int y = r * 299 + g * 587 + b * 114;
|
||||
int diffY = y - y1;
|
||||
int paletteIndex = (diffY * 4) / y2y1Diff;
|
||||
paletteIndex = paletteIndex switch
|
||||
{
|
||||
0 => 0,
|
||||
1 => 2,
|
||||
2 => 3,
|
||||
_ => 1
|
||||
};
|
||||
output[outputOffset + 12 + (i / 4)] |= (byte)(paletteIndex << (2 * (i % 4)));
|
||||
}
|
||||
else if (diffY < max / 2)
|
||||
{
|
||||
paletteIndex = 2;
|
||||
}
|
||||
else if (diffY < max * 3 / 4)
|
||||
{
|
||||
paletteIndex = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
paletteIndex = 1;
|
||||
}
|
||||
newData[12 + (i / 4)] |= (byte)(paletteIndex << (2 * (i % 4)));
|
||||
}
|
||||
|
||||
newData[0] = (byte)a2;
|
||||
newData[1] = (byte)a1;
|
||||
output[outputOffset + 0] = (byte)a2;
|
||||
output[outputOffset + 1] = (byte)a1;
|
||||
|
||||
newData[9] = (byte)((r1_565 << 3) | (g1_565 >> 3));
|
||||
newData[8] = (byte)((g1_565 << 5) | b1_565);
|
||||
newData[11] = (byte)((r2_565 << 3) | (g2_565 >> 3));
|
||||
newData[10] = (byte)((g2_565 << 5) | b2_565);
|
||||
|
||||
output.Write(newData, 0, 16);
|
||||
output[outputOffset + 9] = (byte)((r1_565 << 3) | (g1_565 >> 3));
|
||||
output[outputOffset + 8] = (byte)((g1_565 << 5) | b1_565);
|
||||
output[outputOffset + 11] = (byte)((r2_565 << 3) | (g2_565 >> 3));
|
||||
output[outputOffset + 10] = (byte)((g2_565 << 5) | b2_565);
|
||||
}
|
||||
|
||||
public static Texture2D FromFile(string path, bool compress = true, bool mipmap = false)
|
||||
{
|
||||
using (FileStream fileStream = File.OpenRead(path))
|
||||
{
|
||||
return FromStream(fileStream, path, compress, mipmap);
|
||||
}
|
||||
using FileStream fileStream = File.OpenRead(path);
|
||||
return FromStream(fileStream, path, compress, mipmap);
|
||||
}
|
||||
|
||||
public static Texture2D FromStream(System.IO.Stream stream, string path = null, bool compress = true, bool mipmap = false)
|
||||
|
||||
Reference in New Issue
Block a user