|
|
using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; using System.Runtime.CompilerServices;
namespace SemiColinGames;
public class Texture : IDisposable { public int Handle; public Vector2i Size;
private static int maxHandle = -1; private bool disposedValue = false;
public Texture(Image<Rgba32> image) { Size = new Vector2i(image.Width, image.Height); byte[] pixelBytes = new byte[Size.X * Size.Y * Unsafe.SizeOf<Rgba32>()]; image.CopyPixelDataTo(pixelBytes);
Handle = GL.GenTexture(); if (Handle > maxHandle) { // Console.WriteLine("GL.GenTexture #" + Handle);
maxHandle = Handle; } GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, Handle); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, Size.X, Size.Y, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixelBytes); //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.LinearMipmapLinear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToBorder); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToBorder); float[] borderColor = { 0.0f, 0.0f, 0.0f, 1.0f }; GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, borderColor); // FIXME: should we use mipmaps?
//GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
}
protected virtual void Dispose(bool disposing) { if (!disposedValue) { GL.DeleteTexture(Handle); disposedValue = true; } }
~Texture() { if (!disposedValue) { Console.WriteLine("~Texture(): resource leak? Dispose() should be called manually."); } }
public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } }
|