#region usings using System.Drawing; using System.Drawing.Imaging; using OpenTK.Graphics.OpenGL4; using SM.OGL.Texture; using PixelFormat = System.Drawing.Imaging.PixelFormat; #endregion namespace SM.Base.Textures { /// /// Texture that can be drawn to an object. /// public class Texture : TextureBase { static HintMode _hintMode; /// /// Defines the texture quailty. /// It won't change already compiled textures! /// public static HintMode TextureQuality { get => _hintMode; set { _hintMode = value; GL.Hint(HintTarget.TextureCompressionHint, value); } } private int? _height; private int? _width; public int UnpackAlignment = 4; /// /// Decides if the bitmap will automatically dispose itself. /// public bool AutoDispose = false; /// /// The texture as bitmap. /// public Bitmap Map; /// /// Empty constructor /// protected Texture() { } /// /// Creates a texture with only the map. /// Sets the filter to Linear and WrapMode to Repeat. /// /// The map public Texture(Bitmap map) : this(map, TextureMinFilter.Linear, TextureWrapMode.Repeat) { } /// /// Creates the texture. /// /// The texture map /// The filter /// The wrap mode public Texture(Bitmap map, TextureMinFilter filter, TextureWrapMode wrapMode) { Map = map; Aspect = (float) map.Width / map.Height; Filter = filter; WrapMode = wrapMode; } /// public override int Width { get => _width ?? Map.Width; protected set => _width = value; } /// public override int Height { get => _height ?? Map.Height; protected set => _height = value; } /// /// Aspect ratio of Width and Height of the texture /// public float Aspect { get; } /// public override void Compile() { base.Compile(); _id = GenerateTexture(Map, Filter, WrapMode, AutoDispose, UnpackAlignment); } /// public override void Dispose() { base.Dispose(); GL.DeleteTexture(this); } /// /// Generates a OpenGL-texture. /// /// The texture as bitmap /// The filter /// The wrap mode /// Auto dispose of the bitmap? Default: false /// public static int GenerateTexture(Bitmap map, TextureMinFilter filter, TextureWrapMode wrapMode, bool dispose = false, int unpackAlignment = 4) { var id = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, id); GL.PixelStore(PixelStoreParameter.UnpackAlignment, unpackAlignment); var data = map.LockBits(new Rectangle(0, 0, map.Width, map.Height), ImageLockMode.ReadOnly, map.PixelFormat); var transparenz = map.PixelFormat == PixelFormat.Format32bppArgb; GL.TexImage2D(TextureTarget.Texture2D, 0, transparenz ? PixelInternalFormat.CompressedRgba : PixelInternalFormat.CompressedRgb, data.Width, data.Height, 0, transparenz ? OpenTK.Graphics.OpenGL4.PixelFormat.Bgra : OpenTK.Graphics.OpenGL4.PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) filter); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) filter); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) wrapMode); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) wrapMode); GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); GL.BindTexture(TextureTarget.Texture2D, 0); map.UnlockBits(data); if (dispose) map.Dispose(); return id; } /// /// Converts a bitmap to a texture. /// public static implicit operator Texture(Bitmap map) { return new Texture(map); } } }