106 lines
2.9 KiB
C#
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);
|
|
}
|
|
} |