2f107db...5202af9
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Color = Microsoft.Xna.Framework.Color;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -48,7 +49,7 @@ namespace Barotrauma
|
||||
var texture = Texture2D.FromStream(_graphicsDevice, fileStream);
|
||||
if (preMultiplyAlpha)
|
||||
{
|
||||
PreMultiplyAlpha(texture);
|
||||
PreMultiplyAlpha(ref texture);
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
@@ -66,7 +67,7 @@ namespace Barotrauma
|
||||
try
|
||||
{
|
||||
var texture = Texture2D.FromStream(_graphicsDevice, fileStream);
|
||||
PreMultiplyAlpha(texture);
|
||||
PreMultiplyAlpha(ref texture);
|
||||
return texture;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -76,37 +77,40 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private static void PreMultiplyAlpha(Texture2D texture)
|
||||
private static void PreMultiplyAlpha(ref Texture2D texture)
|
||||
{
|
||||
// Setup a render target to hold our final texture which will have premulitplied alpha values
|
||||
using (RenderTarget2D renderTarget = new RenderTarget2D(_graphicsDevice, texture.Width, texture.Height))
|
||||
UInt32[] data = new UInt32[texture.Width * texture.Height];
|
||||
texture.GetData(data);
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
Viewport viewportBackup = _graphicsDevice.Viewport;
|
||||
_graphicsDevice.SetRenderTarget(renderTarget);
|
||||
_graphicsDevice.Clear(Color.Black);
|
||||
|
||||
// Multiply each color by the source alpha, and write in just the color values into the final texture
|
||||
_spriteBatch.Begin(SpriteSortMode.Immediate, BlendColorBlendState);
|
||||
_spriteBatch.Draw(texture, texture.Bounds, Color.White);
|
||||
_spriteBatch.End();
|
||||
|
||||
// Now copy over the alpha values from the source texture to the final one, without multiplying them
|
||||
_spriteBatch.Begin(SpriteSortMode.Immediate, BlendAlphaBlendState);
|
||||
_spriteBatch.Draw(texture, texture.Bounds, Color.White);
|
||||
_spriteBatch.End();
|
||||
|
||||
// Release the GPU back to drawing to the screen
|
||||
_graphicsDevice.SetRenderTarget(null);
|
||||
_graphicsDevice.Viewport = viewportBackup;
|
||||
|
||||
// Store data from render target because the RenderTarget2D is volatile
|
||||
Color[] data = new Color[texture.Width * texture.Height];
|
||||
renderTarget.GetData(data);
|
||||
|
||||
// Unset texture from graphic device and set modified data back to it
|
||||
_graphicsDevice.Textures[0] = null;
|
||||
texture.SetData(data);
|
||||
uint a = (data[i] & 0xff000000) >> 24;
|
||||
if (a == 0)
|
||||
{
|
||||
data[i] = 0;
|
||||
continue;
|
||||
}
|
||||
else if (a == uint.MaxValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
uint r = (data[i] & 0x00ff0000) >> 16;
|
||||
uint g = (data[i] & 0x0000ff00) >> 8;
|
||||
uint b = (data[i] & 0x000000ff);
|
||||
// Monogame 3.7 needs the line below.
|
||||
a *= a; a /= 255;
|
||||
b *= a; b /= 255;
|
||||
g *= a; g /= 255;
|
||||
r *= a; r /= 255;
|
||||
data[i] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
//not sure why this is needed, but it seems to cut the memory usage of the game almost in half
|
||||
//GetData/SetData might be leaking memory?
|
||||
int width = texture.Width; int height = texture.Height;
|
||||
texture.Dispose();
|
||||
texture = new Texture2D(_graphicsDevice, width, height);
|
||||
texture.SetData(data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user