From c10519f25330cea3d92f057599759f35d1df62a7 Mon Sep 17 00:00:00 2001 From: Christopher Lees Date: Mon, 24 Jul 2023 13:17:25 +0100 Subject: [PATCH 1/3] Change: Don't use bitmap when creating GLFont tables --- source/LibRender2/Text/OpenGlFont.cs | 4 +-- source/LibRender2/Text/OpenGlFontTable.cs | 26 ++++++++------- .../Textures/Textures.ByteArrayOrigin.cs | 33 ++++++++++++++----- source/OpenBveApi/Textures/Textures.cs | 6 ++-- 4 files changed, 43 insertions(+), 26 deletions(-) diff --git a/source/LibRender2/Text/OpenGlFont.cs b/source/LibRender2/Text/OpenGlFont.cs index fb0111d0d1..30a731ebaa 100644 --- a/source/LibRender2/Text/OpenGlFont.cs +++ b/source/LibRender2/Text/OpenGlFont.cs @@ -67,10 +67,8 @@ public Vector2 MeasureString(string text) { for (int i = 0; i < text.Length; i++) { - // ReSharper disable once NotAccessedVariable - Texture texture; OpenGlFontChar data; - i += GetCharacterData(text, i, out texture, out data) - 1; + i += GetCharacterData(text, i, out _, out data) - 1; width += data.TypographicSize.X; if (data.TypographicSize.Y > height) diff --git a/source/LibRender2/Text/OpenGlFontTable.cs b/source/LibRender2/Text/OpenGlFontTable.cs index 173ecb2934..503c1772e8 100644 --- a/source/LibRender2/Text/OpenGlFontTable.cs +++ b/source/LibRender2/Text/OpenGlFontTable.cs @@ -19,7 +19,7 @@ public class OpenGlFontTable : IDisposable // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable // Must remain, else will be disposed of by the GC as this is a separate assembly - private readonly Bitmap bitmap; + private readonly byte[] myBytes; /// The border around glpyhs on the font bitmap const int drawBorder = 20; /// The border used when calculating texture co-ordinates @@ -36,7 +36,7 @@ public OpenGlFontTable(Font font, int offset) * */ Vector2[] physicalSizes = new Vector2[256]; Vector2[] typographicSizes = new Vector2[256]; - bitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb); + Bitmap bitmap = new Bitmap(1, 1, PixelFormat.Format32bppArgb); Graphics graphics = Graphics.FromImage(bitmap); graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; double lineHeight = 0; @@ -120,7 +120,18 @@ public OpenGlFontTable(Font font, int offset) Characters[i] = new OpenGlFontChar(new Vector4(x0, y0, x1 - x0, y1 - y0), new Vector2(physicalSizes[i].X + 2.0 * coordinateBorder, physicalSizes[i].Y + 2.0 * coordinateBorder), typographicSizes[i]); } graphics.Dispose(); - Texture = new Texture(bitmap); + BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); + if (data.Stride == 4 * data.Width) { + /* + * Copy the data from the bitmap + * to the array in BGRA format. + */ + myBytes = new byte[data.Stride * data.Height]; + System.Runtime.InteropServices.Marshal.Copy(data.Scan0, myBytes, 0, data.Stride * data.Height); + bitmap.UnlockBits(data); + } + Texture = new Texture(bitmap.Width, bitmap.Height, 32, myBytes, null); + bitmap.Dispose(); } /// Rounds the specified value to the next-highest power of two. @@ -145,16 +156,7 @@ private static uint RoundToPowerOfTwo(uint value) public void Dispose() { - Dispose(true); GC.SuppressFinalize(this); } - - private void Dispose(bool currentlyDisposing) - { - if (currentlyDisposing) - { - bitmap.Dispose(); - } - } } } diff --git a/source/OpenBveApi/Textures/Textures.ByteArrayOrigin.cs b/source/OpenBveApi/Textures/Textures.ByteArrayOrigin.cs index 042a5a89d6..40658680fc 100644 --- a/source/OpenBveApi/Textures/Textures.ByteArrayOrigin.cs +++ b/source/OpenBveApi/Textures/Textures.ByteArrayOrigin.cs @@ -30,6 +30,21 @@ public ByteArrayOrigin(int width, int height, byte[][] bytes, double frameInterv NumberOfFrames = bytes.Length; } + /// Creates a byte array origin + /// The width of the underlying texture + /// The height of the underlying texture + /// The bytes + public ByteArrayOrigin(int width, int height, byte[] bytes) + { + Width = width; + Height = height; + TextureBytes = new[] + { + bytes + }; + NumberOfFrames = bytes.Length; + } + /// Gets the texture from this origin. /// Receives the texture. /// Whether the texture could be obtained successfully. @@ -50,9 +65,9 @@ public override bool GetTexture(out Texture texture) /// Whether the two origins are equal. public static bool operator ==(ByteArrayOrigin a, ByteArrayOrigin b) { - if (object.ReferenceEquals(a, b)) return true; - if (object.ReferenceEquals(a, null)) return false; - if (object.ReferenceEquals(b, null)) return false; + if (ReferenceEquals(a, b)) return true; + if (ReferenceEquals(a, null)) return false; + if (ReferenceEquals(b, null)) return false; if (a.FrameInterval != b.FrameInterval) return false; if (a.NumberOfFrames != b.NumberOfFrames) return false; if (a.Width != b.Width) return false; @@ -66,9 +81,9 @@ public override bool GetTexture(out Texture texture) /// Whether the two origins are unequal. public static bool operator !=(ByteArrayOrigin a, ByteArrayOrigin b) { - if (object.ReferenceEquals(a, b)) return false; - if (object.ReferenceEquals(a, null)) return true; - if (object.ReferenceEquals(b, null)) return true; + if (ReferenceEquals(a, b)) return false; + if (ReferenceEquals(a, null)) return true; + if (ReferenceEquals(b, null)) return true; if (a.FrameInterval == b.FrameInterval) return false; if (a.NumberOfFrames == b.NumberOfFrames) return false; if (a.Width == b.Width) return false; @@ -81,9 +96,9 @@ public override bool GetTexture(out Texture texture) /// Whether this instance is equal to the specified object. public override bool Equals(object obj) { - if (object.ReferenceEquals(this, obj)) return true; - if (object.ReferenceEquals(this, null)) return false; - if (object.ReferenceEquals(obj, null)) return false; + if (ReferenceEquals(this, obj)) return true; + if (ReferenceEquals(this, null)) return false; + if (ReferenceEquals(obj, null)) return false; if (!(obj is ByteArrayOrigin)) return false; if (FrameInterval == ((ByteArrayOrigin)obj).FrameInterval) return false; if (NumberOfFrames == ((ByteArrayOrigin)obj).NumberOfFrames) return false; diff --git a/source/OpenBveApi/Textures/Textures.cs b/source/OpenBveApi/Textures/Textures.cs index 6415472865..8f69637be2 100644 --- a/source/OpenBveApi/Textures/Textures.cs +++ b/source/OpenBveApi/Textures/Textures.cs @@ -1,4 +1,4 @@ -#pragma warning disable 0659, 0661 +#pragma warning disable 0659, 0661 using System; using System.Drawing; @@ -88,7 +88,9 @@ public Texture(int width, int height, int bitsPerPixel, byte[] bytes, Color24[] { throw new ArgumentException("The data bytes are not of the expected length."); } - + this.Origin = new ByteArrayOrigin(width, height, bytes); + this.MyOpenGlTextures = new OpenGlTexture[1][]; + this.MyOpenGlTextures[0] = new[] {new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture()}; this.MySize.X = width; this.MySize.Y = height; this.MyBitsPerPixel = bitsPerPixel; From e03f8ceb04f54d4cf8cd4afd272081b9d282114f Mon Sep 17 00:00:00 2001 From: Christopher Lees Date: Mon, 24 Jul 2023 16:49:46 +0100 Subject: [PATCH 2/3] Change: Remove bitmap from RouteViewer loadscreen --- source/RouteViewer/LoadingR.cs | 7 ++++--- source/RouteViewer/ProgramR.cs | 33 +++++++++++++++++++-------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/source/RouteViewer/LoadingR.cs b/source/RouteViewer/LoadingR.cs index 088d43c69e..d19d0971ec 100644 --- a/source/RouteViewer/LoadingR.cs +++ b/source/RouteViewer/LoadingR.cs @@ -57,14 +57,15 @@ internal static bool Cancel internal static bool JobAvailable; // load - internal static void Load(string RouteFile, Encoding RouteEncoding, Bitmap bitmap = null) + internal static void Load(string RouteFile, Encoding RouteEncoding, byte[] textureBytes) { // reset Game.Reset(); Program.Renderer.Loading.InitLoading(Program.FileSystem.GetDataFolder("In-game"), typeof(NewRenderer).Assembly.GetName().Version.ToString(), Interface.CurrentOptions.LoadingLogo, Interface.CurrentOptions.LoadingProgressBar); - if (bitmap != null) + if (textureBytes != null) { - Program.Renderer.Loading.SetLoadingBkg(Program.Renderer.TextureManager.RegisterTexture(bitmap, new TextureParameters(null, null))); + Texture t = new Texture(Program.Renderer.Screen.Width, Program.Renderer.Screen.Height, 32, textureBytes, null); + Program.Renderer.Loading.SetLoadingBkg(t); } // members Cancel = false; diff --git a/source/RouteViewer/ProgramR.cs b/source/RouteViewer/ProgramR.cs index 79afda4247..1c53d2a84e 100644 --- a/source/RouteViewer/ProgramR.cs +++ b/source/RouteViewer/ProgramR.cs @@ -27,6 +27,7 @@ using OpenBveApi.Colors; using OpenBveApi.Hosts; using OpenBveApi.Objects; +using Buffer = System.Buffer; using ButtonState = OpenTK.Input.ButtonState; namespace RouteViewer @@ -179,7 +180,7 @@ internal static void Main(string[] args) } // load route - internal static bool LoadRoute(Bitmap bitmap = null) { + internal static bool LoadRoute(byte[] textureBytes = null) { if (string.IsNullOrEmpty(CurrentRouteFile)) { return false; @@ -189,7 +190,7 @@ internal static bool LoadRoute(Bitmap bitmap = null) { try { Encoding encoding = TextEncoding.GetSystemEncodingFromFile(CurrentRouteFile); - Loading.Load(CurrentRouteFile, encoding, bitmap); + Loading.Load(CurrentRouteFile, encoding, textureBytes); result = true; } catch (Exception ex) { MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Hand); @@ -381,25 +382,33 @@ internal static void keyDownEvent(object sender, KeyboardKeyEventArgs e) { return; } + byte[] textureBytes = {}; if (CurrentRouteFile != null && CurrentlyLoading == false) { - - Bitmap bitmap = null; CurrentlyLoading = true; Renderer.OptionInterface = false; if (!Interface.CurrentOptions.LoadingBackground) { Renderer.RenderScene(0.0); currentGameWindow.SwapBuffers(); - bitmap = new Bitmap(Renderer.Screen.Width, Renderer.Screen.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); - BitmapData bData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); - GL.ReadPixels(0, 0, Renderer.Screen.Width, Renderer.Screen.Height, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bData.Scan0); - bitmap.UnlockBits(bData); - bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); + textureBytes = new byte[Renderer.Screen.Width * Renderer.Screen.Height * 4]; + GL.ReadPixels(0, 0, Renderer.Screen.Width, Renderer.Screen.Height, OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, textureBytes); + // GL.ReadPixels is reversed for what it wants as a texture, so we've got to flip it + byte[] tmp = new byte[Renderer.Screen.Width * 4]; // temp row + int currentLine = 0; + while (currentLine < Renderer.Screen.Height / 2) + { + int start = currentLine * Renderer.Screen.Width * 4; + int flipStart = (Renderer.Screen.Height - currentLine - 1) * Renderer.Screen.Width * 4; + Buffer.BlockCopy(textureBytes, start, tmp, 0, Renderer.Screen.Width * 4); + Buffer.BlockCopy(textureBytes, flipStart, textureBytes, start, Renderer.Screen.Width * 4); + Buffer.BlockCopy(tmp, 0, textureBytes, flipStart, Renderer.Screen.Width * 4); + currentLine++; + } } Renderer.Reset(); CameraAlignment a = Renderer.Camera.Alignment; - if (LoadRoute(bitmap)) + if (LoadRoute(textureBytes)) { Renderer.Camera.Alignment = a; Program.Renderer.CameraTrackFollower.UpdateAbsolute(-1.0, true, false); @@ -416,10 +425,6 @@ internal static void keyDownEvent(object sender, KeyboardKeyEventArgs e) } CurrentlyLoading = false; Renderer.OptionInterface = true; - if (bitmap != null) - { - bitmap.Dispose(); - } GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce; GC.Collect(); From 12184fe268323b5f7bdb85893853dc6fe3b7af03 Mon Sep 17 00:00:00 2001 From: Christopher Lees Date: Wed, 26 Jul 2023 09:48:58 +0100 Subject: [PATCH 3/3] WIP removal of BitmapOrigin --- source/LibRender2/Textures/TextureManager.cs | 48 -------- source/ObjectViewer/Hosts.cs | 6 - source/OpenBVE/Game/Menu/Menu.Route.cs | 11 +- source/OpenBVE/Game/Menu/Menu.SingleMenu.cs | 8 +- source/OpenBVE/Game/Menu/Menu.cs | 10 +- source/OpenBVE/Game/RouteInfoOverlay.cs | 16 ++- source/OpenBVE/Game/Timetable.cs | 7 +- source/OpenBVE/System/Host.cs | 6 - .../OpenBveApi/Objects/Helpers/MeshBuilder.cs | 4 +- source/OpenBveApi/OpenBveApi.csproj | 1 - source/OpenBveApi/System/Hosts.cs | 12 +- .../Textures/Textures.BitmapOrigin.cs | 110 ------------------ .../Textures/Textures.TextureOrigin.cs | 12 -- source/OpenBveApi/Textures/Textures.cs | 21 +--- .../Train/XML/TrainXmlParser.CarNode.cs | 2 +- source/RouteViewer/System/Host.cs | 13 +-- 16 files changed, 51 insertions(+), 236 deletions(-) delete mode 100644 source/OpenBveApi/Textures/Textures.BitmapOrigin.cs diff --git a/source/LibRender2/Textures/TextureManager.cs b/source/LibRender2/Textures/TextureManager.cs index 2a38d4b385..e4b9d80a16 100644 --- a/source/LibRender2/Textures/TextureManager.cs +++ b/source/LibRender2/Textures/TextureManager.cs @@ -146,54 +146,6 @@ public Texture RegisterTexture(Texture texture) return RegisteredTextures[idx]; } - /// Registers a texture and returns a handle to the texture. - /// The bitmap that contains the texture. - /// The parameters that specify how to process the texture. - /// The handle to the texture. - /// Be sure not to dispose of the bitmap after calling this function. - public Texture RegisterTexture(Bitmap bitmap, TextureParameters parameters) - { - /* - * Register the texture and return the newly created handle. - * */ - int idx = GetNextFreeTexture(); - RegisteredTextures[idx] = new Texture(bitmap, parameters); - RegisteredTexturesCount++; - return RegisteredTextures[idx]; - } - - /// Registers a texture and returns a handle to the texture. - /// The bitmap that contains the texture. - /// The handle to the texture. - /// Be sure not to dispose of the bitmap after calling this function. - public Texture RegisterTexture(Bitmap bitmap) - { - /* - * Register the texture and return the newly created handle. - * */ - int idx = GetNextFreeTexture(); - RegisteredTextures[idx] = new Texture(bitmap); - RegisteredTexturesCount++; - return RegisteredTextures[idx]; - } - - /// Registers a texture and returns a handle to the texture. - /// The bitmap that contains the texture. - /// A second bitmap containing the alpha channel for this texture - /// The handle to the texture. - /// Be sure not to dispose of the bitmap after calling this function. - public Texture RegisterTexture(Bitmap bitmap, Bitmap alpha) - { - /* - * Register the texture and return the newly created handle. - * */ - int idx = GetNextFreeTexture(); - RegisteredTextures[idx] = new Texture(bitmap); - RegisteredTexturesCount++; - return RegisteredTextures[idx]; - } - - // --- load texture --- /// Loads the specified texture into OpenGL if not already loaded. diff --git a/source/ObjectViewer/Hosts.cs b/source/ObjectViewer/Hosts.cs index 0b76876a4c..9f537fa774 100644 --- a/source/ObjectViewer/Hosts.cs +++ b/source/ObjectViewer/Hosts.cs @@ -162,12 +162,6 @@ public override bool RegisterTexture(string path, TextureParameters parameters, return false; } - public override bool RegisterTexture(Bitmap texture, TextureParameters parameters, out Texture handle) - { - handle = new Texture(texture, parameters); - return true; - } - /// Registers a texture and returns a handle to the texture. /// The texture data. /// The parameters that specify how to process the texture. diff --git a/source/OpenBVE/Game/Menu/Menu.Route.cs b/source/OpenBVE/Game/Menu/Menu.Route.cs index 362184001a..d93372fa06 100644 --- a/source/OpenBVE/Game/Menu/Menu.Route.cs +++ b/source/OpenBVE/Game/Menu/Menu.Route.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Drawing; +using System.Drawing.Imaging; using System.IO; using System.Text; using LibRender2.Primitives; @@ -13,6 +14,7 @@ using OpenBveApi.Textures; using RouteManager2; using Path = OpenBveApi.Path; +using Rectangle = System.Drawing.Rectangle; namespace OpenBve { @@ -62,7 +64,14 @@ private static void packageWorkerThread_completed(object sender, RunWorkerComple { if (currentPackage != null) { - routePictureBox.Texture = new Texture(new Bitmap(currentPackage.PackageImage)); + if (currentPackage.PackageImage is Bitmap bitmap) + { + BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); + byte[] bytes = new byte[data.Stride * data.Height]; + System.Runtime.InteropServices.Marshal.Copy(data.Scan0, bytes, 0, data.Stride * data.Height); + bitmap.UnlockBits(data); + routePictureBox.Texture = new Texture(bitmap.Width, bitmap.Height, 32, bytes, null); + } routeDescriptionBox.Text = currentPackage.Description; packagePreview = false; } diff --git a/source/OpenBVE/Game/Menu/Menu.SingleMenu.cs b/source/OpenBVE/Game/Menu/Menu.SingleMenu.cs index 7c7cd77747..03a8abd689 100644 --- a/source/OpenBVE/Game/Menu/Menu.SingleMenu.cs +++ b/source/OpenBVE/Game/Menu/Menu.SingleMenu.cs @@ -1,6 +1,7 @@ using System; using System.ComponentModel; using System.Drawing; +using System.Drawing.Imaging; using System.IO; using DavyKager; using OpenBveApi.Graphics; @@ -221,7 +222,12 @@ public SingleMenu(MenuType menuType, int data = 0, double MaxWidth = 0) if (icon != null) { Texture t; - Program.CurrentHost.RegisterTexture(icon.ToBitmap(), new TextureParameters(null, null), out t); + Bitmap b = icon.ToBitmap(); + BitmapData bd = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat); + byte[] bytes = new byte[bd.Stride * bd.Height]; + System.Runtime.InteropServices.Marshal.Copy(bd.Scan0, bytes, 0, bd.Stride * bd.Height); + b.UnlockBits(bd); + t = new Texture(b.Width, b.Height, 32, bytes, null); iconCache.Add(ext, t); Items[totalEntries].Icon = t; } diff --git a/source/OpenBVE/Game/Menu/Menu.cs b/source/OpenBVE/Game/Menu/Menu.cs index 982d07660c..9801cafefe 100644 --- a/source/OpenBVE/Game/Menu/Menu.cs +++ b/source/OpenBVE/Game/Menu/Menu.cs @@ -3,6 +3,7 @@ using OpenBveApi.Interface; using System; using System.Drawing; +using System.Drawing.Imaging; using System.IO; using System.Text; using System.Windows.Forms; @@ -17,6 +18,7 @@ using OpenTK; using TrainManager; using Path = OpenBveApi.Path; +using Rectangle = System.Drawing.Rectangle; using Vector2 = OpenBveApi.Math.Vector2; namespace OpenBve @@ -627,9 +629,13 @@ internal void ProcessCommand(Translations.Command cmd, double timeElapsed) return; } routeDescriptionBox.Text = currentPackage.Description; - if (currentPackage.PackageImage != null) + if (currentPackage.PackageImage is Bitmap bitmap) { - routePictureBox.Texture = new Texture(currentPackage.PackageImage as Bitmap); + BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); + byte[] bytes = new byte[data.Stride * data.Height]; + System.Runtime.InteropServices.Marshal.Copy(data.Scan0, bytes, 0, data.Stride * data.Height); + bitmap.UnlockBits(data); + routePictureBox.Texture = new Texture(bitmap.Width, bitmap.Height, 32, bytes, null); } else { diff --git a/source/OpenBVE/Game/RouteInfoOverlay.cs b/source/OpenBVE/Game/RouteInfoOverlay.cs index 6e4fc5b555..fa21661faa 100644 --- a/source/OpenBVE/Game/RouteInfoOverlay.cs +++ b/source/OpenBVE/Game/RouteInfoOverlay.cs @@ -1,4 +1,6 @@ -using OpenBveApi.Colors; +using System.Drawing; +using System.Drawing.Imaging; +using OpenBveApi.Colors; using OpenTK.Graphics.OpenGL; using OpenBveApi.Textures; using OpenBveApi.Interface; @@ -110,14 +112,22 @@ private void setState(state newState) case state.map: if (mapImage == null) { - mapImage = new Texture(Program.CurrentRoute.Information.RouteMap); + BitmapData data = Program.CurrentRoute.Information.RouteMap.LockBits(new Rectangle(0, 0, Program.CurrentRoute.Information.RouteMap.Width, Program.CurrentRoute.Information.RouteMap.Height), ImageLockMode.ReadOnly, Program.CurrentRoute.Information.RouteMap.PixelFormat); + byte[] bytes = new byte[data.Stride * data.Height]; + System.Runtime.InteropServices.Marshal.Copy(data.Scan0, bytes, 0, data.Stride * data.Height); + Program.CurrentRoute.Information.RouteMap.UnlockBits(data); + mapImage = new Texture(Program.CurrentRoute.Information.RouteMap.Width, Program.CurrentRoute.Information.RouteMap.Height, 32, bytes, null); mapSize = new Vector2(Program.CurrentRoute.Information.RouteMap.Width, Program.CurrentRoute.Information.RouteMap.Height); } break; case state.gradient: if (gradientImage == null) { - gradientImage = new Texture(Program.CurrentRoute.Information.GradientProfile); + BitmapData data = Program.CurrentRoute.Information.GradientProfile.LockBits(new Rectangle(0, 0, Program.CurrentRoute.Information.GradientProfile.Width, Program.CurrentRoute.Information.GradientProfile.Height), ImageLockMode.ReadOnly, Program.CurrentRoute.Information.GradientProfile.PixelFormat); + byte[] bytes = new byte[data.Stride * data.Height]; + System.Runtime.InteropServices.Marshal.Copy(data.Scan0, bytes, 0, data.Stride * data.Height); + Program.CurrentRoute.Information.GradientProfile.UnlockBits(data); + gradientImage = new Texture(Program.CurrentRoute.Information.GradientProfile.Width, Program.CurrentRoute.Information.GradientProfile.Height, 32, bytes, null); gradientSize = new Vector2(Program.CurrentRoute.Information.GradientProfile.Width, Program.CurrentRoute.Information.GradientProfile.Height); } break; diff --git a/source/OpenBVE/Game/Timetable.cs b/source/OpenBVE/Game/Timetable.cs index 7590b2575f..4191d697d9 100644 --- a/source/OpenBVE/Game/Timetable.cs +++ b/source/OpenBVE/Game/Timetable.cs @@ -1,5 +1,6 @@ using System; using System.Drawing; +using System.Drawing.Imaging; using OpenBveApi; using OpenBveApi.Runtime; using OpenBveApi.Textures; @@ -494,7 +495,11 @@ internal void RenderData(ref Texture timetableTexture) { // create texture g.Dispose(); - timetableTexture = Program.Renderer.TextureManager.RegisterTexture(b); + BitmapData data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat); + byte[] bytes = new byte[data.Stride * data.Height]; + System.Runtime.InteropServices.Marshal.Copy(data.Scan0, bytes, 0, data.Stride * data.Height); + b.UnlockBits(data); + timetableTexture = new Texture(b.Width, b.Height, 32, bytes, null); } } } diff --git a/source/OpenBVE/System/Host.cs b/source/OpenBVE/System/Host.cs index 77d37a5103..85f0e2e510 100644 --- a/source/OpenBVE/System/Host.cs +++ b/source/OpenBVE/System/Host.cs @@ -196,12 +196,6 @@ public override bool RegisterTexture(Texture texture, TextureParameters paramete return true; } - public override bool RegisterTexture(Bitmap texture, TextureParameters parameters, out Texture handle) - { - handle = new Texture(texture, parameters); - return true; - } - // --- sound --- /// Loads a sound and returns the sound data. diff --git a/source/OpenBveApi/Objects/Helpers/MeshBuilder.cs b/source/OpenBveApi/Objects/Helpers/MeshBuilder.cs index 0178ce7b9e..4284c8486a 100644 --- a/source/OpenBveApi/Objects/Helpers/MeshBuilder.cs +++ b/source/OpenBveApi/Objects/Helpers/MeshBuilder.cs @@ -90,7 +90,7 @@ public void Apply(ref StaticObject Object, bool EnableHacks = false, bool Ignore Object.Mesh.Materials[mm + i].TransparentColor = Materials[i].TransparentColor; if (Materials[i].DaytimeTexture != null || Materials[i].Text != null) { - Textures.Texture tday; + Textures.Texture tday = null; if (Materials[i].Text != null) { Bitmap bitmap = null; @@ -100,7 +100,7 @@ public void Apply(ref StaticObject Object, bool EnableHacks = false, bool Ignore } Bitmap texture = TextOverlay.AddTextToBitmap(bitmap, Materials[i].Text, Materials[i].Font, 12, Materials[i].BackgroundColor, Materials[i].TextColor, Materials[i].TextPadding); - currentHost.RegisterTexture(texture, new TextureParameters(null, new Color24(Materials[i].TransparentColor.R, Materials[i].TransparentColor.G, Materials[i].TransparentColor.B)), out tday); + //currentHost.RegisterTexture(texture, new TextureParameters(null, new Color24(Materials[i].TransparentColor.R, Materials[i].TransparentColor.G, Materials[i].TransparentColor.B)), out tday); } else { diff --git a/source/OpenBveApi/OpenBveApi.csproj b/source/OpenBveApi/OpenBveApi.csproj index 171883ac48..bc431c8000 100644 --- a/source/OpenBveApi/OpenBveApi.csproj +++ b/source/OpenBveApi/OpenBveApi.csproj @@ -253,7 +253,6 @@ Textures.cs - diff --git a/source/OpenBveApi/System/Hosts.cs b/source/OpenBveApi/System/Hosts.cs index a588a58bfd..9a64075bbb 100644 --- a/source/OpenBveApi/System/Hosts.cs +++ b/source/OpenBveApi/System/Hosts.cs @@ -238,17 +238,7 @@ public virtual bool RegisterTexture(Textures.Texture texture, TextureParameters handle = null; return false; } - - /// Registers a texture and returns a handle to the texture. - /// The texture data. - /// The parameters that specify how to process the texture. - /// Receives the handle to the texture. - /// Whether loading the texture was successful. - public virtual bool RegisterTexture(Bitmap texture, TextureParameters parameters, out Textures.Texture handle) { - handle = null; - return false; - } - + /// Loads a sound and returns the sound data. /// The path to the file or folder that contains the sound. /// Receives the sound. diff --git a/source/OpenBveApi/Textures/Textures.BitmapOrigin.cs b/source/OpenBveApi/Textures/Textures.BitmapOrigin.cs deleted file mode 100644 index d33ca8ddde..0000000000 --- a/source/OpenBveApi/Textures/Textures.BitmapOrigin.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System.Drawing; -using System.Drawing.Imaging; -using OpenBveApi.Colors; - -namespace OpenBveApi.Textures -{ - /// Represents a System.Drawing.Bitmap where the texture can be loaded from. - public class BitmapOrigin : TextureOrigin - { - /// The bitmap. - public readonly Bitmap Bitmap; - /// The texture parameters to be applied when loading the texture to OpenGL - public readonly TextureParameters Parameters; - - // --- constructors --- - /// Creates a new bitmap origin. - /// The bitmap. - public BitmapOrigin(Bitmap bitmap) - { - this.Bitmap = bitmap; - } - - /// Creates a new bitmap origin. - /// The bitmap. - /// The texture parameters - public BitmapOrigin(Bitmap bitmap, TextureParameters parameters) - { - this.Bitmap = bitmap; - this.Parameters = parameters; - } - - // --- functions --- - /// Gets the texture from this origin. - /// Receives the texture. - /// Whether the texture could be obtained successfully. - public override bool GetTexture(out Texture texture) - { - Bitmap bitmap = this.Bitmap; - Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); - /* - * If the bitmap format is not already 32-bit BGRA, - * then convert it to 32-bit BGRA. - * */ - Color24[] p = null; - if (bitmap.PixelFormat != PixelFormat.Format32bppArgb && bitmap.PixelFormat != PixelFormat.Format24bppRgb) - { - /* Only store the color palette data for - * textures using a restricted palette - * With a large number of textures loaded at - * once, this can save a decent chunk of memory - * */ - p = new Color24[bitmap.Palette.Entries.Length]; - for (int i = 0; i < bitmap.Palette.Entries.Length; i++) - { - p[i] = bitmap.Palette.Entries[i]; - } - } - - if (bitmap.PixelFormat != PixelFormat.Format32bppArgb) - { - Bitmap compatibleBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb); - System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(compatibleBitmap); - graphics.DrawImage(bitmap, rect, rect, GraphicsUnit.Pixel); - graphics.Dispose(); - bitmap = compatibleBitmap; - } - - /* - * Extract the raw bitmap data. - * */ - BitmapData data = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat); - if (data.Stride == 4 * data.Width) - { - /* - * Copy the data from the bitmap - * to the array in BGRA format. - * */ - byte[] raw = new byte[data.Stride * data.Height]; - System.Runtime.InteropServices.Marshal.Copy(data.Scan0, raw, 0, data.Stride * data.Height); - bitmap.UnlockBits(data); - int width = bitmap.Width; - int height = bitmap.Height; - /* - * Change the byte order from BGRA to RGBA. - * */ - for (int i = 0; i < raw.Length; i += 4) - { - byte temp = raw[i]; - raw[i] = raw[i + 2]; - raw[i + 2] = temp; - } - - texture = new Texture(width, height, 32, raw, p); - texture = texture.ApplyParameters(this.Parameters); - return true; - } - - /* - * The stride is invalid. This indicates that the - * CLI either does not implement the conversion to - * 32-bit BGRA correctly, or that the CLI has - * applied additional padding that we do not - * support. - * */ - bitmap.UnlockBits(data); - texture = null; - return false; - } - } -} diff --git a/source/OpenBveApi/Textures/Textures.TextureOrigin.cs b/source/OpenBveApi/Textures/Textures.TextureOrigin.cs index 5ddacc9781..ea62563f44 100644 --- a/source/OpenBveApi/Textures/Textures.TextureOrigin.cs +++ b/source/OpenBveApi/Textures/Textures.TextureOrigin.cs @@ -29,10 +29,6 @@ public abstract class TextureOrigin { return (PathOrigin)a == (PathOrigin)b; } - if (a is BitmapOrigin && b is BitmapOrigin) - { - return (BitmapOrigin)a == (BitmapOrigin)b; - } if (a is RawOrigin && b is RawOrigin) { return (RawOrigin)a == (RawOrigin)b; @@ -59,10 +55,6 @@ public abstract class TextureOrigin { return (PathOrigin)a != (PathOrigin)b; } - if (a is BitmapOrigin && b is BitmapOrigin) - { - return (BitmapOrigin)a != (BitmapOrigin)b; - } if (a is RawOrigin && b is RawOrigin) { return (RawOrigin)a != (RawOrigin)b; @@ -88,10 +80,6 @@ public override bool Equals(object obj) { return (PathOrigin)this != (PathOrigin)obj; } - if (this is BitmapOrigin && obj is BitmapOrigin) - { - return (BitmapOrigin)this != (BitmapOrigin)obj; - } if (this is RawOrigin && obj is RawOrigin) { return (RawOrigin)this != (RawOrigin)obj; diff --git a/source/OpenBveApi/Textures/Textures.cs b/source/OpenBveApi/Textures/Textures.cs index 8f69637be2..0df4fe8d49 100644 --- a/source/OpenBveApi/Textures/Textures.cs +++ b/source/OpenBveApi/Textures/Textures.cs @@ -152,26 +152,7 @@ public Texture(string path, TextureParameters parameters, Hosts.HostInterface cu this.MyOpenGlTextures[0] = new[] {new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture()}; } - - /// Creates a new texture. - /// The System.Drawing.Bitmap that contains the texture. - public Texture(Bitmap bitmap) - { - this.Origin = new BitmapOrigin(bitmap); - this.MyOpenGlTextures = new OpenGlTexture[1][]; - this.MyOpenGlTextures[0] = new[] {new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture()}; - } - - /// Creates a new texture. - /// The System.Drawing.Bitmap that contains the texture. - /// The parameters that specify how to process the texture. - public Texture(Bitmap bitmap, TextureParameters parameters) - { - this.Origin = new BitmapOrigin(bitmap, parameters); - this.MyOpenGlTextures = new OpenGlTexture[1][]; - this.MyOpenGlTextures[0] = new[] {new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture()}; - } - + /// Creates a new texture. /// The texture raw data. public Texture(Texture texture) diff --git a/source/Plugins/Train.OpenBve/Train/XML/TrainXmlParser.CarNode.cs b/source/Plugins/Train.OpenBve/Train/XML/TrainXmlParser.CarNode.cs index 0a26b8184c..7341fcfeac 100644 --- a/source/Plugins/Train.OpenBve/Train/XML/TrainXmlParser.CarNode.cs +++ b/source/Plugins/Train.OpenBve/Train/XML/TrainXmlParser.CarNode.cs @@ -554,7 +554,7 @@ private void ParseCarNode(XmlNode Node, string fileName, int Car, ref TrainBase * done after the end of the loop * */ //Assign interior view - if (interiorFile != String.Empty) + if (!string.IsNullOrEmpty(interiorFile)) { if (interiorFile.ToLowerInvariant().EndsWith(".xml")) { diff --git a/source/RouteViewer/System/Host.cs b/source/RouteViewer/System/Host.cs index 17ffe6ad93..b6acef59ef 100644 --- a/source/RouteViewer/System/Host.cs +++ b/source/RouteViewer/System/Host.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Drawing; using System.IO; using OpenBveApi; using OpenBveApi.Hosts; @@ -204,12 +203,6 @@ public override bool RegisterTexture(Texture texture, TextureParameters paramete return true; } - public override bool RegisterTexture(Bitmap texture, TextureParameters parameters, out Texture handle) - { - handle = new Texture(texture, parameters); - return true; - } - // --- sound --- /// Loads a sound and returns the sound data. @@ -366,15 +359,13 @@ public override bool LoadObject(string path, System.Text.Encoding Encoding, out obj.OptimizeObject(false, Interface.CurrentOptions.ObjectOptimizationBasicThreshold, true); Object = obj; - StaticObject staticObject = Object as StaticObject; - if (staticObject != null) + if (Object is StaticObject staticObject) { StaticObjectCache.Add(ValueTuple.Create(path, false), staticObject); return true; } - AnimatedObjectCollection aoc = Object as AnimatedObjectCollection; - if (aoc != null) + if (Object is AnimatedObjectCollection aoc) { AnimatedObjectCollectionCache.Add(path, aoc); }