Dashboard/Quik.OpenTK/OpenGLTexture.cs

134 lines
4.7 KiB
C#

using System;
using OpenTK.Graphics.OpenGL4;
namespace Quik.OpenTK
{
public class OpenGLTexture : QuikTexture
{
public int TextureId { get; private set; }
private OpenGLTextureManager Manager { get; }
private int _width;
private int _height;
private bool _mipmaps;
internal OpenGLTexture(OpenGLTextureManager manager, QuikImageFormat format, QuikVec2 size, bool mipmaps)
{
Manager = manager;
_mipmaps = mipmaps;
_width = (int)size.X;
_height = (int)size.Y;
TextureId = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, TextureId);
GL.TexParameter(
TextureTarget.Texture2D,
TextureParameterName.TextureMinFilter,
(int) (mipmaps ? TextureMinFilter.LinearMipmapNearest : TextureMinFilter.Linear));
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexImage2D(
TextureTarget.Texture2D,
0,
(PixelInternalFormat)GetGlImageFormat(format),
Width, Height, 0,
PixelFormat.Rgba, PixelType.UnsignedByte,
IntPtr.Zero);
}
~OpenGLTexture()
{
Dispose(false);
}
/// <inheritdoc />
public override bool Equals(QuikTexture other) =>
other is OpenGLTexture && ((OpenGLTexture)other).TextureId == TextureId;
private bool _isDisposed = false;
protected override void Dispose(bool disposing)
{
if (_isDisposed) return;
Manager?.Reclaim(this);
_isDisposed = true;
}
/// <inheritdoc />
public override int Width => _width;
/// <inheritdoc />
public override int Height => _height;
/// <inheritdoc />
public override bool Mipmaps => _mipmaps;
/// <inheritdoc />
public override void Image(IntPtr data, QuikImageFormat format, QuikVec2 size, int level, int alignment = 4)
{
GL.BindTexture(TextureTarget.Texture2D, TextureId);
GL.PixelStore(PixelStoreParameter.UnpackAlignment, alignment);
GL.TexSubImage2D(TextureTarget.Texture2D, level, 0, 0, Width, Height, GetGlImageFormat(format), GetGlDataFormat(format), data);
}
/// <inheritdoc />
public override void SubImage(IntPtr data, QuikImageFormat format, QuikRectangle location, int level, int alignment = 4)
{
GL.BindTexture(TextureTarget.Texture2D, TextureId);
GL.PixelStore(PixelStoreParameter.UnpackAlignment, alignment);
GL.TexSubImage2D(
TextureTarget.Texture2D,
level,
(int)location.Left,
(int)location.Bottom,
(int)location.Size.X,
(int)location.Size.Y,
GetGlImageFormat(format),
GetGlDataFormat(format),
data);
}
/// <inheritdoc />
public override void GenerateMipMaps()
{
GL.BindTexture(TextureTarget.Texture2D, TextureId);
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
}
private static PixelFormat GetGlImageFormat(QuikImageFormat format)
{
switch (format)
{
case QuikImageFormat.RedF: case QuikImageFormat.RedU8:
return PixelFormat.Red;
case QuikImageFormat.RgbF: case QuikImageFormat.RgbU8:
return PixelFormat.Rgb;
case QuikImageFormat.RgbaF: case QuikImageFormat.RgbaU8:
return PixelFormat.Rgba;
case QuikImageFormat.AlphaF: case QuikImageFormat.AlphaU8:
return PixelFormat.Alpha;
default:
throw new ArgumentOutOfRangeException();
}
}
private static PixelType GetGlDataFormat(QuikImageFormat format)
{
switch (format)
{
case QuikImageFormat.RedF:
case QuikImageFormat.RgbaF:
case QuikImageFormat.RgbF:
case QuikImageFormat.AlphaF:
return PixelType.Float;
case QuikImageFormat.RedU8:
case QuikImageFormat.RgbaU8:
case QuikImageFormat.RgbU8:
case QuikImageFormat.AlphaU8:
return PixelType.UnsignedByte;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}