134 lines
4.7 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
} |