v0.1
This commit is contained in:
125
Subsurface/Source/Utils/TextureLoader.cs
Normal file
125
Subsurface/Source/Utils/TextureLoader.cs
Normal file
@@ -0,0 +1,125 @@
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Color = Microsoft.Xna.Framework.Color;
|
||||
using System;
|
||||
|
||||
namespace Subsurface
|
||||
{
|
||||
/// <summary>
|
||||
/// Based on http://jakepoz.com/jake_poznanski__background_load_xna.html
|
||||
/// </summary>
|
||||
public class TextureLoader
|
||||
{
|
||||
static TextureLoader()
|
||||
{
|
||||
BlendColorBlendState = new BlendState
|
||||
{
|
||||
ColorDestinationBlend = Blend.Zero,
|
||||
ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue,
|
||||
AlphaDestinationBlend = Blend.Zero,
|
||||
AlphaSourceBlend = Blend.SourceAlpha,
|
||||
ColorSourceBlend = Blend.SourceAlpha
|
||||
};
|
||||
|
||||
BlendAlphaBlendState = new BlendState
|
||||
{
|
||||
ColorWriteChannels = ColorWriteChannels.Alpha,
|
||||
AlphaDestinationBlend = Blend.Zero,
|
||||
ColorDestinationBlend = Blend.Zero,
|
||||
AlphaSourceBlend = Blend.One,
|
||||
ColorSourceBlend = Blend.One
|
||||
};
|
||||
}
|
||||
|
||||
public TextureLoader(GraphicsDevice graphicsDevice, bool needsBmp = false)
|
||||
{
|
||||
_graphicsDevice = graphicsDevice;
|
||||
_needsBmp = needsBmp;
|
||||
_spriteBatch = new SpriteBatch(_graphicsDevice);
|
||||
}
|
||||
|
||||
public Texture2D FromFile(string path, bool preMultiplyAlpha = true)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (Stream fileStream = File.OpenRead(path))
|
||||
return FromStream(fileStream, preMultiplyAlpha);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Loading texture ''"+path+"'' failed!", e);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Texture2D FromStream(Stream stream, bool preMultiplyAlpha = true)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
if (_needsBmp)
|
||||
{
|
||||
// Load image using GDI because Texture2D.FromStream doesn't support BMP
|
||||
using (Image image = Image.FromStream(stream))
|
||||
{
|
||||
// Now create a MemoryStream which will be passed to Texture2D after converting to PNG internally
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
image.Save(ms, ImageFormat.Png);
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
texture = Texture2D.FromStream(_graphicsDevice, ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = Texture2D.FromStream(_graphicsDevice, stream);
|
||||
}
|
||||
|
||||
if (preMultiplyAlpha)
|
||||
{
|
||||
// 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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
private static readonly BlendState BlendColorBlendState;
|
||||
private static readonly BlendState BlendAlphaBlendState;
|
||||
|
||||
private readonly GraphicsDevice _graphicsDevice;
|
||||
private readonly SpriteBatch _spriteBatch;
|
||||
private readonly bool _needsBmp;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user