diff --git a/Assets/MaterialAsset.cs b/Assets/MaterialAsset.cs index 8931179..493dafb 100644 --- a/Assets/MaterialAsset.cs +++ b/Assets/MaterialAsset.cs @@ -36,7 +36,7 @@ public virtual void Render(GLContext control, GLTransform transform, ShaderProgr } public virtual void Render(GLContext control, ShaderProgram shader, GenericPickableMesh mesh) - { + { } @@ -69,7 +69,7 @@ public void CreateMaterialRender(GLContext control, GenericPickableMesh mesh, //Render material data onto a textured sphere Render(control, shader, mesh); - + GL.Enable(EnableCap.Blend); GL.BlendFuncSeparate( BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha, @@ -93,13 +93,10 @@ public void CreateMaterialRender(GLContext control, GenericPickableMesh mesh, GL.UseProgram(0); GL.BindTexture(TextureTarget.Texture2D, 0); - var thumbnail = frameBuffer.ReadImagePixels(true); - //Dispose frame buffer frameBuffer.Dispose(); frameBuffer.DisposeRenderBuffer(); - this.Thumbnail = thumbnail; thumbnailUpdated?.Invoke(this, EventArgs.Empty); } @@ -110,7 +107,7 @@ private void DrawSphere(GLContext control) private void DrawPlane(GLContext control) { - + } public virtual void Dispose() @@ -125,4 +122,4 @@ public enum RenderObject Plane, } } -} +} \ No newline at end of file diff --git a/Assets/TextureAsset.cs b/Assets/TextureAsset.cs index 2b03e98..f797c08 100644 --- a/Assets/TextureAsset.cs +++ b/Assets/TextureAsset.cs @@ -15,15 +15,7 @@ public class TextureAsset : AssetBase /// /// The rendered texture instance used to display the texture in OpenGL. /// - public GLTexture RenderableTex { get; set; } - - public static System.Drawing.Bitmap CreateTextureRender(GLContext control, GLTexture renderableTex, int width = 50, int height = 50) - { - TextureAsset texture = new TextureAsset(); - texture.RenderableTex = renderableTex; - texture.CreateTextureRender(control, null, width, height); - return texture.Thumbnail; - } + public virtual GLTexture RenderableTex { get; set; } public void CreateTextureRender(GLContext control, EventHandler thumbnailUpdate, int width = 50, int height = 50) { @@ -48,14 +40,12 @@ public void CreateTextureRender(GLContext control, EventHandler thumbnailUpdate, GL.BindTexture(TextureTarget.Texture2D, 0); var thumbnail = frameBuffer.ReadImagePixels(true); - thumbnail.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY); //Dispose frame buffer frameBuffer.Dispose(); frameBuffer.DisposeRenderBuffer(); - this.Thumbnail = thumbnail; thumbnailUpdate?.Invoke(this, EventArgs.Empty); } } -} +} \ No newline at end of file diff --git a/Camera/Camera.cs b/Camera/Camera.cs index 9e9be85..cd5eddc 100644 --- a/Camera/Camera.cs +++ b/Camera/Camera.cs @@ -371,6 +371,28 @@ public void RotateFromLookat(Vector3 eye, Vector3 target, Vector3 up) RotationZ = rot.Z; } + public void SetLookAt(Vector3 eyePosition, Vector3 targetPosition, Vector3? up = null) + { + up ??= Vector3.UnitY; + + Vector3 direction = (eyePosition - targetPosition).Normalized(); + RotationX = MathF.Asin(direction.Y); + RotationY = -MathF.Atan2(direction.X, direction.Z); + RotationZ = 0f; + + if (cameraMode == CameraMode.Inspect) + { + TargetPosition = targetPosition; + TargetDistance = (eyePosition - targetPosition).Length; + } + else + { + TargetPosition = eyePosition; + TargetDistance = 0f; + } + UpdateMatrices(); + } + /// /// Rotates the camera from a given eye and target position. /// @@ -480,7 +502,7 @@ public Vector3 GetViewPostion() { return pos + InverseRotationMatrix.Row2 * dist; } - public Vector3 GetLookAtPostion(float dist = 1.0f) + public Vector3 GetLookAtPosition(float dist = 1000f) { //Get the eye direction and subtract from the camera position return GetViewPostion() - InverseRotationMatrix.Row2 * dist; diff --git a/Drawing/Viewer/Floor/DrawableSolidFloor.cs b/Drawing/Viewer/Floor/DrawableSolidFloor.cs index af983be..425351d 100644 --- a/Drawing/Viewer/Floor/DrawableSolidFloor.cs +++ b/Drawing/Viewer/Floor/DrawableSolidFloor.cs @@ -38,7 +38,7 @@ public DrawableSolidFloor() : base(Vertices, PrimitiveType.TriangleStrip) public void SetImage(string filePath) { if (System.IO.File.Exists(filePath)) - Texture = GLTexture2D.FromBitmap(new Bitmap(filePath)); + Texture = GLTexture2D.FromBitmap(filePath); } public void Draw(GLContext control, Pass pass) diff --git a/GLFrameworkEngine.csproj b/GLFrameworkEngine.csproj index aab13da..6f5ce7b 100644 --- a/GLFrameworkEngine.csproj +++ b/GLFrameworkEngine.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + net6.0 AnyCPU;x64;x86 @@ -24,7 +24,7 @@ - + diff --git a/ImageSharp/ImageSharpExtension.cs b/ImageSharp/ImageSharpExtension.cs new file mode 100644 index 0000000..d0defee --- /dev/null +++ b/ImageSharp/ImageSharpExtension.cs @@ -0,0 +1,20 @@ +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Advanced; +using System.Linq; +using System.Runtime.InteropServices; + +namespace GLFrameworkEngine.ImageSharp +{ + public static class ImageSharpExtension + { + public static byte[] GetSourceInBytes(this Image image) + { + var _IMemoryGroup = image.GetPixelMemoryGroup(); + var data = _IMemoryGroup.SelectMany(row => MemoryMarshal.AsBytes(row.Span).ToArray()) + .ToArray(); + + return data; + } + } +} diff --git a/Objects/Framebuffer/FrameBufferReading.cs b/Objects/Framebuffer/FrameBufferReading.cs index 92409f2..dbd7c83 100644 --- a/Objects/Framebuffer/FrameBufferReading.cs +++ b/Objects/Framebuffer/FrameBufferReading.cs @@ -2,9 +2,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Drawing; using System.Runtime.InteropServices; using OpenTK.Graphics.OpenGL; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using Toolbox.Core.Imaging; +using GLFrameworkEngine.ImageSharp; namespace GLFrameworkEngine { @@ -18,14 +22,13 @@ public byte[] ReadImageData(bool saveAlpha = false, ReadBufferMode bufferMode = byte[] pixels = ReadPixels(Width, Height, imageSize, bufferMode, saveAlpha); var bitmap = GetBitmap(Width, Height, pixels); - // Adjust for differences in the origin point. - var data = Toolbox.Core.Imaging.BitmapExtension.ImageToByte(bitmap); + var data = bitmap.GetSourceInBytes(); bitmap.Dispose(); return data; } - public System.Drawing.Bitmap ReadImagePixels(bool saveAlpha = false, ReadBufferMode bufferMode = ReadBufferMode.ColorAttachment0) + public Image ReadImagePixels(bool saveAlpha = false, ReadBufferMode bufferMode = ReadBufferMode.ColorAttachment0) { int imageSize = Width * Height * 4; @@ -34,11 +37,12 @@ public System.Drawing.Bitmap ReadImagePixels(bool saveAlpha = false, ReadBufferM var bitmap = GetBitmap(Width, Height, pixels); // Adjust for differences in the origin point. - bitmap.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY); + bitmap.Mutate(x => x.RotateFlip(RotateMode.None, FlipMode.Vertical)); + return bitmap; } - private static byte[] ReadPixels(int width, int height, int imageSizeInBytes, ReadBufferMode bufferMode, bool saveAlpha) + private static byte[] ReadPixels(int width, int height, int imageSizeInBytes, ReadBufferMode bufferMode, bool saveAlpha) { byte[] pixels = new byte[imageSizeInBytes]; @@ -64,15 +68,10 @@ private static void SetAlphaToWhite(int width, int height, int pixelSizeInBytes, } } - public static Bitmap GetBitmap(int width, int height, byte[] imageData) + public static Image GetBitmap(int width, int height, byte[] imageData) { - Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - - System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly, bmp.PixelFormat); - Marshal.Copy(imageData, 0, bmpData.Scan0, imageData.Length); - - bmp.UnlockBits(bmpData); - return bmp; + BitmapExtension.ConvertBgraToRgba(imageData); + return Image.LoadPixelData(imageData, width, height); } } -} +} \ No newline at end of file diff --git a/Objects/Texture/DepthCascadeTexture.cs b/Objects/Texture/DepthCascadeTexture.cs new file mode 100644 index 0000000..794e577 --- /dev/null +++ b/Objects/Texture/DepthCascadeTexture.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Mail; +using System.Text; +using System.Threading.Tasks; +using OpenTK.Graphics.OpenGL; + +namespace GLFrameworkEngine +{ + public class DepthCascadeTexture : GLTexture, IFramebufferAttachment + { + public DepthCascadeTexture(int width, int height, int count, PixelInternalFormat pixelInternalFormat) + : base() + { + Target = TextureTarget.Texture2DArray; + PixelInternalFormat = pixelInternalFormat; + PixelFormat = PixelFormat.DepthComponent; + PixelType = PixelType.Float; + Width = width; + Height = height; + ArrayCount = count; + + // Set texture settings. + Bind(); + + GL.TexImage3D(Target, 0, PixelInternalFormat, + Width, Height, ArrayCount, 0, + PixelFormat, PixelType, IntPtr.Zero); + + MagFilter = TextureMagFilter.Nearest; + MinFilter = TextureMinFilter.Nearest; + + // Use white for values outside the depth map's border. + WrapS = TextureWrapMode.ClampToBorder; + WrapT = TextureWrapMode.ClampToBorder; + UpdateParameters(); + + GL.TexParameter(Target, TextureParameterName.TextureCompareMode, (int)TextureCompareMode.None); + GL.TexParameter(Target, TextureParameterName.TextureBorderColor, new float[] { 1, 1, 1, 1 }); + // GL.TexParameter(Target, TextureParameterName.TextureCompareFunc, (int)All.Lequal); + + Unbind(); + } + + public override void Attach(FramebufferAttachment attachment, Framebuffer target) + { + target.Bind(); + GL.FramebufferTextureLayer(target.Target, attachment, ID, 0, 0); + } + + public void AttachDepth(Framebuffer target, int layer) + { + target.Bind(); + GL.FramebufferTextureLayer(target.Target, FramebufferAttachment.DepthAttachment, ID, 0, layer); + } + } +} diff --git a/Objects/Texture/GLFormatHelper.cs b/Objects/Texture/GLFormatHelper.cs index c6eb5a8..1675c76 100644 --- a/Objects/Texture/GLFormatHelper.cs +++ b/Objects/Texture/GLFormatHelper.cs @@ -36,16 +36,20 @@ public static int CalculateImageSize(int width, int height, InternalFormat forma static readonly Dictionary PixelFormatList = new Dictionary { { TexFormat.RG11B10_FLOAT, new PixelFormatInfo(All.R11fG11fB10f, PixelFormat.Rgb, PixelType.UnsignedInt10F11F11FRev) }, - { TexFormat.RGBA8_UNORM, new PixelFormatInfo(All.Rgba, PixelFormat.Bgra, PixelType.UnsignedByte) }, - { TexFormat.RGBA8_SRGB, new PixelFormatInfo(All.SrgbAlpha, PixelFormat.Bgra, PixelType.UnsignedByte) }, + { TexFormat.RGBA16_FLOAT, new PixelFormatInfo(All.Rgba16f, PixelFormat.Rgba, PixelType.HalfFloat) }, + + { TexFormat.RGBA8_UNORM, new PixelFormatInfo(All.Rgba, PixelFormat.Rgba, PixelType.UnsignedByte) }, + { TexFormat.RGBA8_SRGB, new PixelFormatInfo(All.SrgbAlpha, PixelFormat.Rgba, PixelType.UnsignedByte) }, { TexFormat.RGBA32_FLOAT, new PixelFormatInfo(All.Rgba32f, PixelFormat.Rgba, PixelType.Float) }, { TexFormat.R8_UNORM, new PixelFormatInfo(All.R8, PixelFormat.Red, PixelType.UnsignedByte) }, { TexFormat.RG8_UNORM, new PixelFormatInfo(All.Rg8, PixelFormat.Rg, PixelType.UnsignedByte) }, { TexFormat.RG8_SNORM, new PixelFormatInfo(All.Rg8Snorm, PixelFormat.Rg, PixelType.Byte) }, { TexFormat.RG8_UINT, new PixelFormatInfo(All.Rg8ui, PixelFormat.RgInteger, PixelType.UnsignedByte) }, { TexFormat.RG8_SINT, new PixelFormatInfo(All.Rg8i, PixelFormat.RgInteger, PixelType.Byte) }, - { TexFormat.RG16_FLOAT, new PixelFormatInfo(All.Rg16, PixelFormat.Rg, PixelType.HalfFloat) }, + { TexFormat.RG16_FLOAT, new PixelFormatInfo(All.Rg16f, PixelFormat.Rg, PixelType.HalfFloat) }, + { TexFormat.RG16_UNORM, new PixelFormatInfo(All.R16, PixelFormat.Rg, PixelType.UnsignedShort) }, { TexFormat.RGB565_UNORM, new PixelFormatInfo( All.Rgb565, PixelFormat.Rgb, PixelType.UnsignedShort565Reversed) }, + { TexFormat.RGB9E5_SHAREDEXP, new PixelFormatInfo( All.Rgb9E5, PixelFormat.Rgb, PixelType.UnsignedInt5999Rev) }, }; static readonly Dictionary InternalFormatList = new Dictionary diff --git a/Objects/Texture/GLTexture.cs b/Objects/Texture/GLTexture.cs index 619033a..abdf3a0 100644 --- a/Objects/Texture/GLTexture.cs +++ b/Objects/Texture/GLTexture.cs @@ -3,7 +3,11 @@ using System.Linq; using System.Threading.Tasks; using OpenTK.Graphics.OpenGL; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp; using Toolbox.Core; +using static System.Net.Mime.MediaTypeNames; +using static Toolbox.Core.STGenericTexture; namespace GLFrameworkEngine { @@ -40,8 +44,11 @@ public int ArrayCount public PixelFormat PixelFormat { get; internal set; } public PixelType PixelType { get; internal set; } + public List SubTextures = new List(); + public GLTexture() : base(GL.GenTexture()) { + Bind(); Target = TextureTarget.Texture2D; WrapS = TextureWrapMode.ClampToEdge; WrapT = TextureWrapMode.ClampToEdge; @@ -55,6 +62,40 @@ public GLTexture() : base(GL.GenTexture()) GL.TexParameter(Target, TextureParameterName.TextureMaxLod, 14); UpdateParameters(); + + Unbind(); + } + + public void Clear() + { + GL.ClearTexImage(ID, 0, this.PixelFormat, this.PixelType, IntPtr.Zero); + } + + public void SetFilter(TextureMinFilter minFilter, TextureMagFilter magFilter) + { + GL.TexParameter(Target, TextureParameterName.TextureMinFilter, (int)minFilter); + GL.TexParameter(Target, TextureParameterName.TextureMagFilter, (int)magFilter); + } + + public void MipRange(int min, int max, float lod = 0) + { + GL.TexParameter(Target, TextureParameterName.TextureLodBias, lod); + GL.TexParameter(Target, TextureParameterName.TextureMinLod, min); + GL.TexParameter(Target, TextureParameterName.TextureMaxLod, max); + } + + public byte[] GetBytes(int level = 0) + { + int mipWidth = (int)(Width * Math.Pow(0.5, level)); + int mipHeight = (int)(Height * Math.Pow(0.5, level)); + + byte[] outputRaw = new byte[mipWidth * mipHeight * 4]; + + Bind(); + GL.GetTexImage(this.Target, level, + PixelFormat.Rgba, PixelType.UnsignedByte, outputRaw); + + return outputRaw; } public void GenerateMipmaps() { @@ -105,6 +146,8 @@ public static GLTexture FromGenericTexture(STGenericTexture texture, ImageParame return GLTexture3D.FromGeneric(texture, parameters); case STSurfaceType.TextureCube: return GLTextureCube.FromGeneric(texture, parameters); + case STSurfaceType.TextureCube_Array: + return GLTextureCubeArray.FromGeneric(texture, parameters); default: return GLTexture2D.FromGeneric(texture, parameters); } @@ -134,11 +177,8 @@ public void LoadImage(STGenericTexture texture, ImageParameters parameters) if (texture.IsASTC() || parameters.FlipY) loadAsBitmap = true; - int numMips = 1; - for (int mipLevel = 0; mipLevel < numMips; mipLevel++) + void PushImageData(byte[] surface, int mipLevel, int depthLevel) { - var surface = GetTextureBuffer(texture, mipLevel); - if (loadAsBitmap || parameters.UseSoftwareDecoder) { var rgbaData = texture.GetDecodedSurface(0, mipLevel); @@ -148,17 +188,38 @@ public void LoadImage(STGenericTexture texture, ImageParameters parameters) var formatInfo = GLFormatHelper.ConvertPixelFormat(TexFormat.RGBA8_UNORM); if (texture.IsSRGB) formatInfo.InternalFormat = PixelInternalFormat.Srgb8Alpha8; - GLTextureDataLoader.LoadImage(Target, width, height, depth, formatInfo, rgbaData, mipLevel); + if (loadAsBitmap) + formatInfo.Format = PixelFormat.Bgra; + + GLTextureDataLoader.LoadImage(Target, width, height, depthLevel, formatInfo, rgbaData, mipLevel); } else if (texture.IsBCNCompressed()) { var internalFormat = GLFormatHelper.ConvertCompressedFormat(format, true); - GLTextureDataLoader.LoadCompressedImage(Target, width, height, depth, internalFormat, surface, mipLevel); + GLTextureDataLoader.LoadCompressedImage(Target, width, height, depthLevel, internalFormat, surface, mipLevel); } else { var formatInfo = GLFormatHelper.ConvertPixelFormat(format); - GLTextureDataLoader.LoadImage(Target, width, height, depth, formatInfo, surface, mipLevel); + GLTextureDataLoader.LoadImage(Target, width, height, depthLevel, formatInfo, surface, mipLevel); + } + } + + int numMips = 1; + for (int mipLevel = 0; mipLevel < numMips; mipLevel++) + { + if (this.Target == TextureTarget.TextureCubeMap) + { + for (int j = 0; j < texture.ArrayCount; j++) + { + var data = texture.GetDeswizzledSurface(j, mipLevel); + PushImageData(data, mipLevel, j); + } + } + else + { + var surface = GetTextureBuffer(texture, mipLevel); + PushImageData(surface, mipLevel, depth); } } @@ -194,7 +255,7 @@ public static bool IsPower2(int width, int height) { return IsPow2(width) && IsPow2(height); } - public virtual System.Drawing.Bitmap ToBitmap(bool saveAlpha = false) + public virtual Image ToBitmap(bool saveAlpha = true) { return null; } @@ -230,5 +291,46 @@ private static byte[] FlipVertical(int Width, int Height, byte[] Input) } return FlippedOutput; } + + //for track studio array fix + public unsafe static GLTexture ToArrayCopy(GLTexture texture) + { + var dest_format = PixelInternalFormat.Rgba; + + texture.Bind(); + + //Src + byte[] buffer = new byte[texture.Width * texture.Height * 4]; + GL.GetTexImage(texture.Target, 0, PixelFormat.Rgba, PixelType.UnsignedByte, buffer); + + //Use srgb if enabled + if (texture.PixelInternalFormat == PixelInternalFormat.SrgbAlpha) + dest_format = PixelInternalFormat.SrgbAlpha; + + + GLTexture tex = new GLTexture(); + tex.Target = TextureTarget.Texture2DArray; + tex.Width = texture.Width; + tex.Height = texture.Height; + tex.MinFilter = texture.MinFilter; + tex.MagFilter = texture.MagFilter; + tex.PixelInternalFormat = dest_format; + tex.PixelFormat = PixelFormat.Rgba; + tex.PixelType = PixelType.UnsignedByte; + + //Dst + tex.Bind(); + + //Copy + GL.TexImage3D(tex.Target, 0, tex.PixelInternalFormat, tex.Width, tex.Height, 1, 0, + tex.PixelFormat, tex.PixelType, buffer); + + GL.GenerateMipmap((GenerateMipmapTarget)tex.Target); + + //unbind + tex.Unbind(); + + return tex; + } } } diff --git a/Objects/Texture/GLTexture2D.cs b/Objects/Texture/GLTexture2D.cs index d0e7298..180542e 100644 --- a/Objects/Texture/GLTexture2D.cs +++ b/Objects/Texture/GLTexture2D.cs @@ -3,8 +3,13 @@ using System.Linq; using System.Threading.Tasks; using OpenTK.Graphics.OpenGL; -using System.Drawing; using Toolbox.Core; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using Toolbox.Core.IO; +using Toolbox.Core.Imaging; +using GLFrameworkEngine.ImageSharp; namespace GLFrameworkEngine { @@ -15,6 +20,36 @@ public GLTexture2D() : base() Target = TextureTarget.Texture2D; } + public static GLTexture2D CreateUncompressedTextureWithMipmaps(int width, int height, int mipCount, + PixelInternalFormat format = PixelInternalFormat.Rgba8, + PixelFormat pixelFormat = PixelFormat.Rgba, + PixelType pixelType = PixelType.UnsignedByte) + { + GLTexture2D texture = new GLTexture2D(); + texture.PixelInternalFormat = format; + texture.PixelFormat = pixelFormat; + texture.PixelType = pixelType; + texture.Width = width; texture.Height = height; + texture.Target = TextureTarget.Texture2D; + texture.MagFilter = TextureMagFilter.Linear; + texture.MinFilter = TextureMinFilter.LinearMipmapLinear; + texture.MipCount = mipCount; + texture.Bind(); + + GL.TexParameter(texture.Target, TextureParameterName.TextureBaseLevel, 0); + GL.TexParameter(texture.Target, TextureParameterName.TextureMaxLevel, texture.MipCount); + + GL.TexParameter(texture.Target, TextureParameterName.TextureLodBias, 0); + GL.TexParameter(texture.Target, TextureParameterName.TextureMinLod, 0); + GL.TexParameter(texture.Target, TextureParameterName.TextureMaxLod, texture.MipCount); + + texture.AllocateMipmaps(); + + texture.UpdateParameters(); + texture.Unbind(); + return texture; + } + public static GLTexture2D CreateUncompressedTexture(int width, int height, PixelInternalFormat format = PixelInternalFormat.Rgba8, PixelFormat pixelFormat = PixelFormat.Rgba, @@ -37,7 +72,45 @@ public static GLTexture2D CreateUncompressedTexture(int width, int height, return texture; } - public static GLTexture2D CreateWhiteTexture(int width, int height) + public void Resize(int width, int height) + { + Width = width; + Height = height; + + Bind(); + + GL.TexImage2D(Target, 0, PixelInternalFormat, + Width, Height, + 0, PixelFormat, PixelType, IntPtr.Zero); + + if (MipCount > 1) + AllocateMipmaps(); + + Unbind(); + } + + private void AllocateMipmaps() + { + if (MipCount == 1) + return; + + for (int i = 0; i < MipCount; i++) + { + int mwidth = Math.Max(1, (int)Width >> i); + int mheight = Math.Max(1, (int)Height >> i); + + GL.TexImage2D(Target, i, PixelInternalFormat, + mwidth, mheight, 0, PixelFormat, PixelType, IntPtr.Zero); + } + GenerateMipmaps(); + } + + public static GLTexture2D CreateBlackTexture(int width = 4, int height = 4) + { + return CreateUncompressedTexture(width, height); + } + + public static GLTexture2D CreateWhiteTexture(int width = 4, int height = 4) { GLTexture2D texture = new GLTexture2D(); texture.PixelInternalFormat = PixelInternalFormat.Rgba8; @@ -90,6 +163,44 @@ public static GLTexture2D CreateConstantColorTexture(int width, int height, byte return texture; } + public static GLTexture2D CreateRGBATexture(byte[] buffer, int width, int height) + { + GLTexture2D texture = new GLTexture2D(); + texture.PixelInternalFormat = PixelInternalFormat.Rgba; + texture.PixelFormat = PixelFormat.Rgba; + texture.PixelType = PixelType.UnsignedByte; + texture.Width = width; texture.Height = height; + texture.Target = TextureTarget.Texture2D; + texture.Bind(); + + GL.TexImage2D(TextureTarget.Texture2D, 0, texture.PixelInternalFormat, + texture.Width, texture.Height, + 0, texture.PixelFormat, texture.PixelType, buffer); + + texture.UpdateParameters(); + texture.Unbind(); + return texture; + } + + public static GLTexture2D CreateFloatRGBA32Texture(int width, int height, float[] buffer) + { + GLTexture2D texture = new GLTexture2D(); + texture.PixelInternalFormat = PixelInternalFormat.Rgba32f; + texture.PixelFormat = PixelFormat.Rgba; + texture.PixelType = PixelType.Float; + texture.Width = width; texture.Height = height; + texture.Target = TextureTarget.Texture2D; + texture.Bind(); + + GL.TexImage2D(TextureTarget.Texture2D, 0, texture.PixelInternalFormat, + texture.Width, texture.Height, + 0, texture.PixelFormat, texture.PixelType, buffer); + + texture.UpdateParameters(); + texture.Unbind(); + return texture; + } + public static GLTexture2D CreateFloat32Texture(int width, int height, float[] buffer) { GLTexture2D texture = new GLTexture2D(); @@ -123,21 +234,21 @@ public static GLTexture2D FromGeneric(STGenericTexture texture, ImageParameters public static GLTexture2D FromBitmap(string imageFile) { - Bitmap image = (Bitmap)Bitmap.FromStream(System.IO.File.OpenRead(imageFile)); + var image = Image.Load(imageFile); return FromBitmap(image); } - public static GLTexture2D FromBitmap(byte[] imageFile, int width, int height) { - Bitmap image = (Bitmap)Bitmap.FromStream(new System.IO.MemoryStream(imageFile)); - image = Toolbox.Core.Imaging.BitmapExtension.Resize(image, width, height); + var image = Image.Load(imageFile); + image.Mutate(x => x.Resize(width, height)); return FromBitmap(image); } public static GLTexture2D FromBitmap(byte[] imageFile, bool isLinear = true) { - Bitmap image = (Bitmap)Bitmap.FromStream(new System.IO.MemoryStream(imageFile)); + var image = Image.Load(imageFile); + GLTexture2D texture = new GLTexture2D(); texture.Target = TextureTarget.Texture2D; @@ -160,7 +271,7 @@ public static GLTexture2D FromBitmap(byte[] imageFile, bool isLinear = true) return texture; } - public static GLTexture2D FromBitmap(Bitmap image) + public static GLTexture2D FromBitmap(Image image) { GLTexture2D texture = new GLTexture2D(); texture.Target = TextureTarget.Texture2D; @@ -169,17 +280,14 @@ public static GLTexture2D FromBitmap(Bitmap image) return texture; } - public void LoadImage(Bitmap image) + public void LoadImage(Image image) { Bind(); - System.Drawing.Imaging.BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), - System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + var rgba = image.GetSourceInBytes(); - GL.TexImage2D(Target, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0, - PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); - - image.UnlockBits(data); + GL.TexImage2D(Target, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, + PixelFormat.Rgba, PixelType.UnsignedByte, rgba); image.Dispose(); @@ -198,6 +306,16 @@ public void LoadImage(byte[] image) Unbind(); } + public void SetData(T[] data) where T : struct + { + Bind(); + + GL.TexImage2D(Target, 0, this.PixelInternalFormat, Width, Height, 0, + this.PixelFormat, this.PixelType, data); + + Unbind(); + } + public void Reload(int width, int height, T[] data) where T : struct { Bind(); @@ -212,22 +330,10 @@ public System.IO.Stream ToStream(bool saveAlpha = false) { var stream = new System.IO.MemoryStream(); var bmp = ToBitmap(saveAlpha); - bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Png); + bmp.SaveAsPng(stream); return stream; } - public byte[] GetBytes(int level = 0) - { - int mipWidth = (int)(Width * Math.Pow(0.5, level)); - int mipHeight = (int)(Height * Math.Pow(0.5, level)); - - byte[] outputRaw = new byte[mipWidth * mipHeight * 4]; - GL.GetTexImage(this.Target, level, - PixelFormat.Bgra, PixelType.UnsignedByte, outputRaw); - - return outputRaw; - } - public override void SaveDDS(string fileName) { List surfaces = new List(); @@ -277,33 +383,22 @@ public void Save(string fileName, bool saveAlpha = false) Bind(); var bmp = ToBitmap(saveAlpha); - bmp.Save(fileName + ".png"); + bmp.Save(fileName); Unbind(); } - public override System.Drawing.Bitmap ToBitmap(bool saveAlpha = true) + public override Image ToBitmap(bool saveAlpha = true) { Bind(); - var bmp = new System.Drawing.Bitmap(Width, Height); - - System.Drawing.Imaging.BitmapData data = - bmp.LockBits(new System.Drawing.Rectangle(0, 0, Width, Height), - System.Drawing.Imaging.ImageLockMode.WriteOnly, - saveAlpha ? - System.Drawing.Imaging.PixelFormat.Format32bppArgb - : - System.Drawing.Imaging.PixelFormat.Format24bppRgb); - - GL.ReadPixels(0, 0, Width, Height, saveAlpha ? PixelFormat.Bgra : PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0); - bmp.UnlockBits(data); + byte[] data = GetBytes(0); - bmp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY); + var image = Image.LoadPixelData(data, Width, Height); Unbind(); - return bmp; + return image; } } } diff --git a/Objects/Texture/GLTexture2DArray.cs b/Objects/Texture/GLTexture2DArray.cs index e6c371a..1f4c886 100644 --- a/Objects/Texture/GLTexture2DArray.cs +++ b/Objects/Texture/GLTexture2DArray.cs @@ -3,8 +3,11 @@ using System.Linq; using System.Threading.Tasks; using OpenTK.Graphics.OpenGL; -using System.Drawing; using Toolbox.Core; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; +using System.Net.Mail; +using GLFrameworkEngine.ImageSharp; namespace GLFrameworkEngine { @@ -89,6 +92,20 @@ public static GLTexture2DArray CreateUncompressedTexture(int width, int height, return texture; } + public void Resize(int width, int height) + { + Width = width; + Height = height; + + Bind(); + + GL.TexImage3D(Target, 0, PixelInternalFormat, + Width, Height, ArrayCount, 0, + PixelFormat, PixelType, IntPtr.Zero); + + Unbind(); + } + public static GLTexture2DArray CreateConstantColorTexture(int width, int height, int count, byte R, byte G, byte B, byte A) { GLTexture2DArray texture = new GLTexture2DArray(); @@ -129,7 +146,7 @@ public static GLTexture2DArray FromGeneric(STGenericTexture texture, ImageParame return glTexture; } - public static GLTexture2DArray FromDDS(DDS dds) + public static GLTexture2DArray FromDDS(DDS dds, bool flip = false) { GLTexture2DArray texture = new GLTexture2DArray(); texture.Width = (int)dds.Width; texture.Height = (int)dds.Height; @@ -155,7 +172,7 @@ public static GLTexture2DArray FromDDS(DDS dds) for (int i = 0; i < dds.ArrayCount; i++) { var data = dds.GetDecodedSurface(i, j); - if (i == 0 || i == 1) + if (flip) data = FlipHorizontal(mipWidth, mipHeight, data); levels.Add(data); @@ -281,7 +298,7 @@ public static GLTexture2DArray FromDDS(DDS[] dds, bool flipY = false) return texture; } - public static GLTexture2DArray FromBitmap(Bitmap image) + public static GLTexture2DArray FromBitmap(Image image) { GLTexture2DArray texture = new GLTexture2DArray(); texture.Width = image.Width; texture.Height = image.Height; @@ -316,42 +333,49 @@ public void LoadImage(int width, int height, TexFormat format, byte[] data) } } - public void InsertImage(byte[] buffer, int level = 0) + public void InsertImage(T[] rgba, int level = 0) where T : struct { Bind(); - GL.TexSubImage3D(Target, 0, 0, 0, level, this.Width, this.Height, 1, - this.PixelFormat, this.PixelType, buffer); + GL.TexSubImage3D(Target, 0, 0, 0, level, Width, Height, 1, + PixelFormat, PixelType, rgba); Unbind(); } - public void InsertImage(Bitmap image, int level = 0) + public void InsertImage(byte[] rgba, int level = 0) { Bind(); - System.Drawing.Imaging.BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), - System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + GL.TexSubImage3D(Target, 0, 0, 0, level, Width, Height, 1, + OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, rgba); - GL.TexSubImage3D(Target, 0, 0, 0, level, this.Width, this.Height, 1, - this.PixelFormat, this.PixelType, data.Scan0); + Unbind(); + } - image.UnlockBits(data); + public void InsertImage(Image image, int level = 0) + { + if (image.Width != this.Width || image.Height != this.Height) + throw new Exception(); + + Bind(); + + var rgba = image.GetSourceInBytes(); + + GL.TexSubImage3D(Target, 0, 0, 0, level, image.Width, image.Height, 1, + this.PixelFormat, this.PixelType, rgba); Unbind(); } - public void LoadImage(Bitmap image, int level = 0, int count = 1) + public void LoadImage(Image image, int level = 0, int count = 1) { Bind(); - System.Drawing.Imaging.BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), - System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); + var rgba = image.GetSourceInBytes(); - GL.TexImage3D(Target, level, PixelInternalFormat.Rgba, data.Width, data.Height, count, 0, - OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); - - image.UnlockBits(data); + GL.TexImage3D(Target, level, PixelInternalFormat.Rgba, image.Width, image.Height, count, 0, + OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, rgba); GL.GenerateMipmap(GenerateMipmapTarget.Texture2DArray); @@ -372,7 +396,7 @@ public System.IO.Stream ToStream(bool saveAlpha = false) { var stream = new System.IO.MemoryStream(); var bmp = ToBitmap(saveAlpha); - bmp.Save(stream, System.Drawing.Imaging.ImageFormat.Png); + bmp.SaveAsPng(stream); return stream; } @@ -385,7 +409,7 @@ public void Save(string fileName, bool saveAlpha = false) GL.GetTextureSubImage(this.ID, 0, 0, 0, i, Width, Height, 1, PixelFormat.Bgra, PixelType.UnsignedByte, output.Length, output); - var bitmap = BitmapImageHelper.CreateBitmap(output, Width, Height); + var bitmap = Image.LoadPixelData(output, Width, Height); bitmap.Save(fileName + $"_{i}.png"); } Unbind(); @@ -422,7 +446,7 @@ public override void SaveDDS(string fileName) dds.MainHeader.MipCount = (uint)this.MipCount; dds.MainHeader.PitchOrLinearSize = (uint)surfaces[0].mipmaps[0].Length; - dds.SetFlags(TexFormat.RGBA8_UNORM, false, true); + dds.SetFlags(TexFormat.RGBA8_UNORM, ArrayCount > 1, false); if (dds.IsDX10) { @@ -435,6 +459,8 @@ public override void SaveDDS(string fileName) dds.Save(fileName, surfaces); + surfaces.Clear(); + Unbind(); } } diff --git a/Objects/Texture/GLTexture3D.cs b/Objects/Texture/GLTexture3D.cs index 99956ff..4da46ac 100644 --- a/Objects/Texture/GLTexture3D.cs +++ b/Objects/Texture/GLTexture3D.cs @@ -3,8 +3,10 @@ using System.Linq; using System.Threading.Tasks; using OpenTK.Graphics.OpenGL; -using System.Drawing; using Toolbox.Core; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Processing; namespace GLFrameworkEngine { @@ -50,6 +52,56 @@ public static GLTexture3D FromGeneric(STGenericTexture texture, ImageParameters return glTexture; } + public override void SaveDDS(string fileName) + { + List surfaces = new List(); + + Bind(); + + for (int i = 0; i < this.Depth; i++) + { + var surface = new STGenericTexture.Surface(); + surfaces.Add(surface); + + for (int m = 0; m < this.MipCount; m++) + { + int mipWidth = (int)(Width * Math.Pow(0.5, m)); + int mipHeight = (int)(Height * Math.Pow(0.5, m)); + + byte[] outputRaw = new byte[mipWidth * mipHeight * 4]; + + GL.GetTextureSubImage(this.ID, m, 0, 0, i, Width, Height, 1, + PixelFormat.Rgba, PixelType.UnsignedByte, outputRaw.Length, outputRaw); + + surface.mipmaps.Add(outputRaw); + } + } + + + var dds = new DDS(); + dds.MainHeader.Width = (uint)this.Width; + dds.MainHeader.Height = (uint)this.Height; + dds.MainHeader.Depth = 1; + dds.MainHeader.MipCount = (uint)this.MipCount; + dds.MainHeader.PitchOrLinearSize = (uint)surfaces[0].mipmaps[0].Length; + dds.ArrayCount = (uint)this.Depth; + + dds.SetFlags(TexFormat.RGBA8_UNORM, true, false); + + if (dds.IsDX10) + { + if (dds.Dx10Header == null) + dds.Dx10Header = new DDS.DX10Header(); + + dds.Dx10Header.ResourceDim = 3; + dds.Dx10Header.ArrayCount = (uint)this.Depth; + } + + dds.Save(fileName, surfaces); + + Unbind(); + } + public void Save(string fileName) { Bind(); @@ -60,17 +112,19 @@ public void Save(string fileName) Unbind(); } - public override System.Drawing.Bitmap ToBitmap(bool saveAlpha = true) + public override Image ToBitmap(bool saveAlpha = true) { Bind(); byte[] data = new byte[Width * Height * Depth * 4]; GL.GetTexImage(Target, 0, PixelFormat.Bgra, PixelType.UnsignedByte, data); + var image = Image.LoadPixelData(data, Width * Depth, Height); + image.Mutate(x => x.RotateFlip(RotateMode.None, FlipMode.Vertical)); + Unbind(); - return Toolbox.Core.Imaging.BitmapExtension.CreateBitmap( - data, Width * Depth, Height); + return image; } } } diff --git a/Objects/Texture/GLTextureCube.cs b/Objects/Texture/GLTextureCube.cs index 168018d..32f9ce2 100644 --- a/Objects/Texture/GLTextureCube.cs +++ b/Objects/Texture/GLTextureCube.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Threading.Tasks; using OpenTK.Graphics.OpenGL; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; using Toolbox.Core; namespace GLFrameworkEngine @@ -29,7 +31,9 @@ public static GLTextureCube CreateEmptyCubemap(int size, texture.WrapR = TextureWrapMode.ClampToEdge; texture.WrapS = TextureWrapMode.ClampToEdge; texture.WrapT = TextureWrapMode.ClampToEdge; - texture.MinFilter = TextureMinFilter.LinearMipmapLinear; + texture.MinFilter = TextureMinFilter.Linear; + if (texture.MipCount > 1) + texture.MinFilter = TextureMinFilter.LinearMipmapLinear; texture.MagFilter = TextureMagFilter.Linear; texture.MipCount = numMips; @@ -258,8 +262,8 @@ public void Save(string fileName) Bind(); var decomp = GetDecompressedRawImageData(0); - var bitmap = BitmapImageHelper.CreateBitmap(decomp, Width, Height * 6); - bitmap.Save(fileName); + var bitmap = Image.LoadPixelData(decomp, Width, Height * 6); + bitmap.SaveAsPng(fileName); Unbind(); } diff --git a/Objects/Texture/GLTextureCubeArray.cs b/Objects/Texture/GLTextureCubeArray.cs index 3d978ae..b3a8e9d 100644 --- a/Objects/Texture/GLTextureCubeArray.cs +++ b/Objects/Texture/GLTextureCubeArray.cs @@ -3,6 +3,8 @@ using System.Linq; using System.Threading.Tasks; using OpenTK.Graphics.OpenGL; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.PixelFormats; using Toolbox.Core; namespace GLFrameworkEngine @@ -25,7 +27,9 @@ public static GLTextureCubeArray CreateEmptyCubemap(int size, int arrayCount, in texture.PixelInternalFormat = pixelInternalFormat; texture.Width = size; texture.Height = size; texture.Target = TextureTarget.TextureCubeMapArray; - texture.MinFilter = TextureMinFilter.LinearMipmapLinear; + texture.MinFilter = TextureMinFilter.Linear; + if (texture.MipCount > 1) + texture.MinFilter = TextureMinFilter.LinearMipmapLinear; texture.MagFilter = TextureMagFilter.Linear; texture.MipCount = mipCount; texture.ArrayCount = arrayCount; @@ -40,8 +44,8 @@ public static GLTextureCubeArray CreateEmptyCubemap(int size, int arrayCount, in int mipWidth = (int)(texture.Width * Math.Pow(0.5, mip)); int mipHeight = (int)(texture.Height * Math.Pow(0.5, mip)); - GL.TexImage3D(texture.Target, 0, texture.PixelInternalFormat, - mipWidth, mipHeight, texture.ArrayCount * 6, mip, + GL.TexImage3D(texture.Target, mip, texture.PixelInternalFormat, + mipWidth, mipHeight, texture.ArrayCount * 6, 0, texture.PixelFormat, texture.PixelType, IntPtr.Zero); } @@ -53,7 +57,7 @@ public static GLTextureCubeArray CreateEmptyCubemap(int size, int arrayCount, in public static GLTextureCubeArray FromGeneric(STGenericTexture texture, ImageParameters parameters) { GLTextureCubeArray glTexture = new GLTextureCubeArray(); - glTexture.Target = TextureTarget.Texture2D; + glTexture.Target = TextureTarget.TextureCubeMapArray; glTexture.Width = (int)texture.Width; glTexture.Height = (int)texture.Height; glTexture.LoadImage(texture, parameters); @@ -168,8 +172,8 @@ public void Save(string fileName) //Remove alpha output = SetImageData(output, true, true); - var bitmap = BitmapImageHelper.CreateBitmap(output, Width, Height); - bitmap.Save(fileName + $"_{i}.png"); + var bitmap = Image.LoadPixelData(output, Width, Height); + bitmap.SaveAsPng(fileName + $"_{i}.png"); } Unbind(); } diff --git a/Objects/Texture/GLTextureDataLoader.cs b/Objects/Texture/GLTextureDataLoader.cs index e4d234a..deaf395 100644 --- a/Objects/Texture/GLTextureDataLoader.cs +++ b/Objects/Texture/GLTextureDataLoader.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Drawing.Imaging; -using System.Drawing; using OpenTK.Graphics.OpenGL; namespace GLFrameworkEngine @@ -23,6 +21,9 @@ public static void LoadCompressedImage(TextureTarget target, int width, int heig case TextureTarget.TextureCubeMapArray: LoadCompressedImage3D(target, mipLevel, depth, width, height, format, data); break; + case TextureTarget.TextureCubeMap: + LoadCompressedImageCubemap2D(mipLevel, depth, width, height, format, data); + break; } } @@ -39,6 +40,9 @@ public static void LoadImage(TextureTarget target, int width, int height, case TextureTarget.TextureCubeMapArray: LoadImage3D(target, mipLevel, depth, width, height, format, data); break; + case TextureTarget.TextureCubeMap: + LoadImageCubemap2D(mipLevel, depth, width, height, format, data); + break; } } @@ -66,25 +70,12 @@ public static void LoadImageCubemap(TextureTarget target, int width, int height, } } - public static void LoadImage(TextureTarget target, int width, int height, - int depth, GLFormatHelper.PixelFormatInfo format, Bitmap bitmap, int mipLevel = 0) + static void LoadCompressedImageCube(int face, int mipLevel, int width, int height, InternalFormat format, byte[] data) { - BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), - ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - - switch (target) - { - case TextureTarget.Texture2D: - LoadImage2D(mipLevel, width, height, format, data.Scan0); - break; - case TextureTarget.Texture2DArray: - case TextureTarget.Texture3D: - case TextureTarget.TextureCubeMapArray: - LoadImage3D(target, mipLevel, depth, width, height, format, data.Scan0); - break; - } + int imageSize = GLFormatHelper.CalculateImageSize(width, height, format); - bitmap.UnlockBits(data); + GL.CompressedTexImage2D(TextureTarget.TextureCubeMapPositiveX + face, mipLevel, + format, width, height, 0, imageSize, data); } static void LoadCompressedImage2D(int mipLevel, int width, int height, InternalFormat format, byte[] data) diff --git a/RenderToTexture/IconModelRenderer.cs b/RenderToTexture/IconModelRenderer.cs index 51c9d40..65aeb27 100644 --- a/RenderToTexture/IconModelRenderer.cs +++ b/RenderToTexture/IconModelRenderer.cs @@ -2,12 +2,12 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Drawing; using GLFrameworkEngine; using OpenTK.Graphics.OpenGL; using OpenTK.Graphics; using OpenTK; using Toolbox.Core; +using SixLabors.ImageSharp; namespace GLFrameworkEngine { @@ -22,9 +22,9 @@ public class IconModelRenderer static float CameraRotationY = 0; static float CameraDistance = 0; - public static Bitmap[] CreateRender(IGraphicsContext context, IEnumerable drawables, int width = 32, int height = 32) + public static Image[] CreateRender(IGraphicsContext context, IEnumerable drawables, int width = 32, int height = 32) { - List textures = new List(); + List textures = new List(); Framebuffer = new Framebuffer(FramebufferTarget.Framebuffer, width, height); @@ -79,7 +79,7 @@ public static Bitmap[] CreateRender(IGraphicsContext context, IEnumerable FindSelectableObjects(IEnumerable obj if (obj is IEditModeObject && ((IEditModeObject)obj).EditMode) { foreach (var ob in ((IEditModeObject)obj).Selectables) + { + if (ob is IDrawable && !((IDrawable)ob).IsVisible) + continue; + + if (ob is RenderablePathPoint && !((RenderablePathPoint)ob).IsVisible) + continue; + transformables.Add(ob); + } } if (obj is ISelectableContainer) { foreach (var ob in ((ISelectableContainer)obj).Selectables) + { + if (ob is IDrawable && !((IDrawable)ob).IsVisible) + continue; + + if (ob is RenderablePathPoint && !((RenderablePathPoint)ob).IsVisible) + continue; + transformables.Add(ob); + } } if (obj is ITransformableObject) transformables.Add((ITransformableObject)obj); diff --git a/Shaders/ShaderProgram.cs b/Shaders/ShaderProgram.cs index 87ab710..74aeb36 100644 --- a/Shaders/ShaderProgram.cs +++ b/Shaders/ShaderProgram.cs @@ -28,6 +28,8 @@ public class ShaderProgram : IDisposable //Check if the shader was linked public bool LinkSucessful = false; + public Dictionary UniformTypeInfo = new Dictionary(); + // This isn't in OpenTK's enums for some reason. // https://www.khronos.org/registry/OpenGL/api/GL/glcorearb.h private static readonly int GL_PROGRAM_BINARY_MAX_LENGTH = 0x8741; @@ -255,6 +257,9 @@ private void LoadUniorms(int program) if (string.IsNullOrEmpty(name)) continue; + if (!UniformTypeInfo.ContainsKey(name)) + UniformTypeInfo.Add(name, type); + int location = GL.GetUniformLocation(program, name); // Overwrite existing vertex attributes. uniforms[name] = location;