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

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);
}