From d3e7718b5f29f84f4dd174d880d3cfbec481b336 Mon Sep 17 00:00:00 2001 From: Colin McMillen Date: Thu, 29 Jun 2023 15:51:42 -0400 Subject: [PATCH] make a Texture object --- Program.cs | 78 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/Program.cs b/Program.cs index 24fa33b..8c65524 100644 --- a/Program.cs +++ b/Program.cs @@ -103,7 +103,7 @@ void main() { ~Shader() { if (disposedValue == false) { - Console.WriteLine("GPU Resource leak! Did you forget to call Dispose()?"); + Console.WriteLine("~Shader(): resource leak? Dispose() should be called manually."); } } @@ -122,6 +122,53 @@ void main() { } +public class Texture : IDisposable { + public int Handle; + + public Texture(string path) { + Image image = Image.Load(path); + Console.WriteLine($"{image.Width}x{image.Height}"); + //foreach (IExifValue exif in image.Metadata.ExifProfile.Values) { + // Console.WriteLine($"{exif.Tag} : {exif.GetValue()}"); + //} + byte[] pixelBytes = new byte[image.Width * image.Height * Unsafe.SizeOf()]; + image.CopyPixelDataTo(pixelBytes); + image.Dispose(); + + Handle = GL.GenTexture(); + GL.ActiveTexture(TextureUnit.Texture0); + GL.BindTexture(TextureTarget.Texture2D, Handle); + GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixelBytes); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.LinearMipmapLinear); // FIXME: is this right? + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Nearest); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToBorder); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToBorder); + float[] borderColor = { 0.0f, 0.0f, 0.0f, 1.0f }; + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, borderColor); + GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); + } + + private bool disposedValue = false; + + protected virtual void Dispose(bool disposing) { + if (!disposedValue) { + GL.DeleteTexture(Handle); + disposedValue = true; + } + } + + ~Texture() { + if (!disposedValue) { + Console.WriteLine("~Texture(): resource leak? Dispose() should be called manually."); + } + } + + public void Dispose() { + Dispose(true); + GC.SuppressFinalize(this); + } +} + public class Game : GameWindow { public Game(GameWindowSettings gwSettings, NativeWindowSettings nwSettings) : base(gwSettings, nwSettings) { } @@ -144,7 +191,7 @@ public class Game : GameWindow { int VertexBufferObject; int ElementBufferObject; int VertexArrayObject; - int texture; + Texture texture; Shader shader; Matrix4 projection; @@ -191,29 +238,8 @@ public class Game : GameWindow { GL.EnableVertexAttribArray(texCoordLocation); GL.VertexAttribPointer(texCoordLocation, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float)); - // Decode a JPEG image. - //Image image = Image.Load(@"c:\users\colin\pictures\texture.jpg"); - Image image = Image.Load(@"c:\users\colin\pictures\photos\2023\06\27\DSC_0035.jpg"); - Console.WriteLine($"{image.Width}x{image.Height}"); - //foreach (IExifValue exif in image.Metadata.ExifProfile.Values) { - // Console.WriteLine($"{exif.Tag} : {exif.GetValue()}"); - //} - byte[] pixelBytes = new byte[image.Width * image.Height * Unsafe.SizeOf()]; - image.CopyPixelDataTo(pixelBytes); - image.Dispose(); - - // TODO: put the texture into an actual class. - texture = GL.GenTexture(); - GL.ActiveTexture(TextureUnit.Texture0); - GL.BindTexture(TextureTarget.Texture2D, texture); - GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixelBytes); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.LinearMipmapLinear); // FIXME: is this right? - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Nearest); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToBorder); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToBorder); - float[] borderColor = { 0.0f, 0.0f, 0.0f, 1.0f }; - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBorderColor, borderColor); - GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); + // Load textures from JPEGs. + texture = new Texture(@"c:\users\colin\pictures\photos\2023\06\27\DSC_0035.jpg"); } protected override void OnUnload() { @@ -226,7 +252,7 @@ public class Game : GameWindow { GL.Clear(ClearBufferMask.ColorBufferBit); GL.BindVertexArray(VertexArrayObject); GL.ActiveTexture(TextureUnit.Texture0); - GL.BindTexture(TextureTarget.Texture2D, texture); + GL.BindTexture(TextureTarget.Texture2D, texture.Handle); shader.Use(); GL.DrawElements(PrimitiveType.Triangles, indices.Length, DrawElementsType.UnsignedInt, 0); SwapBuffers();