using System.Drawing; using System.IO; using OpenTK.Graphics.OpenGL; using OpenTK.Graphics; using System; namespace RecrownedGTK.Graphics { /// /// Represents the texture for any given vertice. /// Contains bytes that form the texture. /// public class TextureData : IDisposable { private bool disposed; int handle; public readonly int width, height; public TextureWrapMode textureWrapModeWidth, textureWrapModeHeight; public Color4 borderColor; public TextureMinFilter textureMinFilter; public TextureMagFilter textureMagFilter; /// /// Generates a texture data with a png. /// /// A path to a texture represented in PNG format. public TextureData(string path) { int width; int height; byte[] textureData = LoadPNG(path, out width, out height); GenerateTexture(textureData, width, height); } /// /// Generates a texture using a byte array of the texture data. /// /// The byte array representing the texture. /// The width of the texture. /// The height of the texture. public TextureData(byte[] textureData, int width, int height) { textureWrapModeHeight = TextureWrapMode.ClampToBorder; textureWrapModeWidth = TextureWrapMode.ClampToBorder; textureMinFilter = TextureMinFilter.LinearMipmapLinear; textureMagFilter = TextureMagFilter.Linear; this.width = width; this.height = height; GenerateTexture(textureData, width, height); } /// ///Load PNG data to this texture representation. /// /// Decodes the PNG into a byte array to be stored. /// /// The path to the PNG file to be represented. /// Outputs the width of the PNG file. /// Outputs the height of the PNG file. /// A byte array representing the PNG. private byte[] LoadPNG(string path, out int width, out int height) { byte[] textureData = null; using (FileStream file = new FileStream(path, FileMode.Open)) { using (Bitmap bitmap = new Bitmap(file)) { ImageConverter converter = new ImageConverter(); textureData = (byte[]) converter.ConvertTo(bitmap, typeof(byte[])); width = bitmap.Width; height = bitmap.Height; } } return textureData; } /// /// Generates a texture in the OpenGL context. /// /// Byte array representing the texture. /// Width of the texture. /// Height of the texture. private void GenerateTexture(byte[] textureData, int width, int height) { if (handle != 0) throw new InvalidOperationException("This texture data already holds a texture."); handle = GL.GenTexture(); Use(); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, textureData); GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); } /// /// Binds the OpenGL texture. /// internal void Use() { GL.BindTexture(TextureTarget.Texture2D, handle); } /// /// Removes texture data from memory. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposed) return; if (disposing) { } GL.BindTexture(TextureTarget.Texture2D, 0); GL.DeleteTexture(handle); disposed = true; } ~TextureData() { Dispose(false); } } }