Files
doom-dm/Engine/Renderer/Texture/Texture.cs
2024-12-04 22:35:04 +03:00

106 lines
2.9 KiB
C#

using System.Runtime.InteropServices;
using Engine.Asset;
using Engine.Renderer.Pixel;
using OpenTK.Graphics.OpenGL;
namespace Engine.Renderer.Texture;
public abstract class Texture<T> : OpenGlObject, ITexture<T> where T : struct, IPixel
{
public int Width
{
get => _width;
protected set
{
if (value <= 0)
throw new ArgumentException("Width must be greater than 0");
_width = value;
}
}
public int Height
{
get => _height;
protected set
{
if (value <= 0)
throw new ArgumentException("Height must be greater than 0");
_height = value;
}
}
private int _width;
private int _height;
protected Texture(int width, int height)
{
Width = width;
Height = height;
GL.CreateTextures(TextureTarget.Texture2D, 1, out int handle);
Handle = handle;
}
public void UploadPixels(int x, int y, int width, int height, T[,] pixels)
{
if (x < 0 || y < 0)
throw new ArgumentException("x and y must be greater than 0");
if (width <= 0 || height <= 0)
throw new ArgumentException("Width and height must be greater than 0");
if (x + width > Width || y + height > Height)
throw new ArgumentException("x + width and y + height must be less than width and height");
if (pixels.Length != width * height)
throw new ArgumentException("Pixels array must be of size width * height");
var format = pixels[0, 0].Format;
var type = pixels[0, 0].Type;
GL.TextureSubImage2D(Handle, 0, x, y, width, height, format, type, pixels);
}
public void ReadPixels(int x, int y, int width, int height, T[,] pixels)
{
if (x < 0 || y < 0)
throw new ArgumentException("x and y must be greater than 0");
if (width <= 0 || height <= 0)
throw new ArgumentException("Width and height must be greater than 0");
if (x + width > Width || y + height > Height)
throw new ArgumentException("x + width and y + height must be less than width and height");
if (pixels.Length != width * height)
throw new ArgumentException("Pixels array must be of size width * height");
var format = default(T).Format;
var type = default(T).Type;
GL.GetTextureSubImage(Handle, 0, x, y, 0, width, height, 1, format, type, pixels.Length * Marshal.SizeOf<T>(),
pixels);
}
internal void BindUnit(int unit)
{
GL.BindTextureUnit(unit, Handle);
}
internal override void Bind()
{
GL.BindTexture(TextureTarget.Texture2D, Handle);
}
internal override void Unbind()
{
GL.BindTexture(TextureTarget.Texture2D, 0);
}
protected override void Destroy()
{
GL.DeleteTexture(Handle);
}
}