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.
 
 

62 lines
2.1 KiB

using System;
using System.IO;
using gaemstone.ECS;
using gaemstone.Flecs;
using Silk.NET.OpenGL;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using static gaemstone.Client.Components.RenderingComponents;
using static gaemstone.Client.Systems.Windowing;
using Texture = gaemstone.Client.Components.ResourceComponents.Texture;
namespace gaemstone.Client.Systems;
[Module]
[DependsOn<gaemstone.Client.Components.RenderingComponents>]
[DependsOn<gaemstone.Client.Components.ResourceComponents>]
[DependsOn<gaemstone.Client.Systems.Windowing>]
public class TextureManager
{
[Observer<ObserverEvent.OnSet>]
public static void OnCanvasSet(Canvas canvas)
{
var GL = 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(0xFF);
GL.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba,
1, 1, 0, PixelFormat.Rgba, PixelType.UnsignedByte, in pixel[0]);
}
[System]
public static void LoadTextureWhenDefined(
[Game] Canvas canvas, EntityRef entity,
Texture _1, [Not] TextureHandle _2)
{
var path = entity.GetFullPath();
using var stream = Resources.GetStream(path);
var handle = CreateFromStream(canvas.GL, stream);
entity.Set(handle);
}
private static TextureHandle CreateFromStream(GL GL, Stream stream)
{
var target = TextureTarget.Texture2D;
var handle = GL.GenTexture();
GL.BindTexture(target, handle);
var image = Image.Load<Rgba32>(stream);
ref var origin = ref image.Frames[0].PixelBuffer[0, 0];
GL.TexImage2D(target, 0, (int)PixelFormat.Rgba,
(uint)image.Width, (uint)image.Height, 0,
PixelFormat.Rgba, PixelType.UnsignedByte, origin);
GL.TexParameter(target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
GL.TexParameter(target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
GL.BindTexture(target, 0);
return new(target, handle);
}
}