You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
2.8 KiB
76 lines
2.8 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.IO; |
|
using gaemstone.ECS; |
|
using Silk.NET.OpenGL; |
|
using SixLabors.ImageSharp; |
|
using SixLabors.ImageSharp.PixelFormats; |
|
using Size = System.Drawing.Size; |
|
|
|
namespace gaemstone.Client; |
|
|
|
public static class TextureManager |
|
{ |
|
private static readonly Dictionary<Texture, TextureInfo> _byTexture = new(); |
|
private static readonly Dictionary<string, TextureInfo> _bySourceFile = new(); |
|
|
|
public static void Initialize(Universe universe) |
|
{ |
|
var GL = universe.Lookup<Game>().Get<Windowing.Canvas>().GL; |
|
// Upload single-pixel white texture into texture slot 0, so when |
|
// "no" texture is bound, we can still use the texture sampler. |
|
GL.BindTexture(TextureTarget.Texture2D, 0); |
|
Span<byte> pixel = stackalloc byte[4]; |
|
pixel.Fill(255); |
|
GL.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba, |
|
1, 1, 0, PixelFormat.Rgba, PixelType.UnsignedByte, in pixel[0]); |
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); |
|
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); |
|
} |
|
|
|
public static Texture Load(Universe universe, string name) |
|
{ |
|
using var stream = Resources.GetStream(name); |
|
return CreateFromStream(universe, stream, name); |
|
} |
|
|
|
public static Texture CreateFromStream(Universe universe, Stream stream, string? sourceFile = null) |
|
{ |
|
var GL = universe.Lookup<Game>().Get<Windowing.Canvas>().GL; |
|
var texture = new Texture(TextureTarget.Texture2D, GL.GenTexture()); |
|
GL.BindTexture(texture.Target, texture.Handle); |
|
|
|
var image = Image.Load<Rgba32>(stream); |
|
ref var origin = ref image.Frames[0].PixelBuffer[0, 0]; |
|
|
|
GL.TexImage2D(texture.Target, 0, (int)PixelFormat.Rgba, |
|
(uint)image.Width, (uint)image.Height, 0, |
|
PixelFormat.Rgba, PixelType.UnsignedByte, origin); |
|
GL.TexParameter(texture.Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); |
|
GL.TexParameter(texture.Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); |
|
|
|
var info = new TextureInfo(texture, sourceFile, new(image.Width, image.Height)); |
|
_byTexture.Add(texture, info); |
|
if (sourceFile != null) _bySourceFile.Add(sourceFile, info); |
|
|
|
GL.BindTexture(texture.Target, 0); |
|
return texture; |
|
} |
|
|
|
|
|
public static TextureInfo? Lookup(Texture texture) |
|
=> _byTexture.TryGetValue(texture, out var value) ? value : null; |
|
|
|
public static TextureInfo? Lookup(string sourceFile) |
|
=> _bySourceFile.TryGetValue(sourceFile, out var value) ? value : null; |
|
} |
|
|
|
public class TextureInfo |
|
{ |
|
public Texture Texture { get; } |
|
public string? SourceFile { get; } |
|
public Size Size { get; } |
|
|
|
public TextureInfo(Texture texture, string? sourceFile, Size size) |
|
=> (Texture, SourceFile, Size) = (texture, sourceFile, size); |
|
}
|
|
|