// --- functions --- /// <summary>Gets the texture from this origin.</summary> /// <param name="texture">Receives the texture.</param> /// <returns>Whether the texture could be obtained successfully.</returns> internal override bool GetTexture(out OpenBveApi.Textures.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. * */ if (bitmap.PixelFormat != PixelFormat.Format32bppArgb) { Bitmap compatibleBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb); Graphics graphics = 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 OpenBveApi.Textures.Texture(width, height, 32, raw); 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); }
// --- upsize texture --- /// <summary>Upsizes the specified texture to a power of two size and returns the result.</summary> /// <param name="texture">The texture.</param> /// <returns>The upsized texture, or the original if already a power of two size.</returns> /// <exception cref="System.NotSupportedException">The bits per pixel in the texture is not supported.</exception> internal static OpenBveApi.Textures.Texture UpsizeToPowerOfTwo(OpenBveApi.Textures.Texture texture) { int width = RoundUpToPowerOfTwo(texture.Width); int height = RoundUpToPowerOfTwo(texture.Height); return(Resize(texture, width, height)); }
// --- functions --- /// <summary>Gets the texture from this origin.</summary> /// <param name="texture">Receives the texture.</param> /// <returns>Whether the texture could be obtained successfully.</returns> internal override bool GetTexture(out OpenBveApi.Textures.Texture texture) { if (!Program.CurrentHost.LoadTexture(this.Path, this.Parameters, out texture)) { texture = null; return(false); } return(true); }
/// <summary>Registers a texture and returns a handle to the texture.</summary> /// <param name="texture">The texture data.</param> /// <returns>The handle to the texture.</returns> internal static Texture RegisterTexture(OpenBveApi.Textures.Texture texture) { /* * Register the texture and return the newly created handle. * */ int idx = GetNextFreeTexture(); RegisteredTextures[idx] = new Texture(texture); RegisteredTexturesCount++; return(RegisteredTextures[idx]); }
/// <summary>Registeres a texture and returns a handle to the texture.</summary> /// <param name="texture">The texture data.</param> /// <returns>The handle to the texture.</returns> internal static Texture RegisterTexture(OpenBveApi.Textures.Texture texture) { /* * Register the texture and return the newly created handle. * */ if (RegisteredTextures.Length == RegisteredTexturesCount) { Array.Resize <Texture>(ref RegisteredTextures, RegisteredTextures.Length << 1); } RegisteredTextures[RegisteredTexturesCount] = new Texture(texture); RegisteredTexturesCount++; return(RegisteredTextures[RegisteredTexturesCount - 1]); }
// --- upsize texture --- /// <summary>Resizes the specified texture to a power of two size and returns the result.</summary> /// <param name="texture">The texture.</param> /// <returns>The upsized texture, or the original if already a power of two size.</returns> /// <exception cref="System.NotSupportedException">The bits per pixel in the texture is not supported.</exception> internal static OpenBveApi.Textures.Texture ResizeToPowerOfTwo(OpenBveApi.Textures.Texture texture) { int width = RoundUpToPowerOfTwo(texture.Width); int height = RoundUpToPowerOfTwo(texture.Height); //HACK: Some routes use non-power of two textures which upscale to stupid numbers //At least round down if we're over 1024 px.... if (width != texture.Width && width > 1024) { width /= 2; } if (height != texture.Height && height > 1024) { height /= 2; } return(Resize(texture, width, height)); }
// --- save texture --- /// <summary>Saves a texture to a file.</summary> /// <param name="file">The file.</param> /// <param name="texture">The texture.</param> /// <remarks>The texture is always saved in PNG format.</remarks> internal static void SaveTexture(string file, OpenBveApi.Textures.Texture texture) { Bitmap bitmap = new Bitmap(texture.Width, texture.Height, PixelFormat.Format32bppArgb); BitmapData data = bitmap.LockBits(new Rectangle(0, 0, texture.Width, texture.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat); byte[] bytes = new byte[texture.Bytes.Length]; for (int i = 0; i < bytes.Length; i += 4) { bytes[i] = texture.Bytes[i + 2]; bytes[i + 1] = texture.Bytes[i + 1]; bytes[i + 2] = texture.Bytes[i]; bytes[i + 3] = texture.Bytes[i + 3]; } Marshal.Copy(bytes, 0, data.Scan0, texture.Bytes.Length); bitmap.UnlockBits(data); bitmap.Save(file, ImageFormat.Png); bitmap.Dispose(); }
/// <summary>Registers a texture and returns a handle to the texture.</summary> /// <param name="texture">The texture data.</param> /// <param name="parameters">The parameters that specify how to process the texture.</param> /// <param name="handle">Receives the handle to the texture.</param> /// <returns>Whether loading the texture was successful.</returns> public override bool RegisterTexture(OpenBveApi.Textures.Texture texture, OpenBveApi.Textures.TextureParameters parameters, out OpenBveApi.Textures.TextureHandle handle) { texture = texture.ApplyParameters(parameters); handle = Textures.RegisterTexture(texture); return(true); }
/// <summary>Resizes the specified texture to the specified width and height and returns the result.</summary> /// <param name="texture">The texture.</param> /// <param name="width">The new width.</param> /// <param name="height">The new height.</param> /// <returns>The resize texture, or the original if already of the specified size.</returns> /// <exception cref="System.NotSupportedException">The bits per pixel in the texture is not supported.</exception> internal static OpenBveApi.Textures.Texture Resize(OpenBveApi.Textures.Texture texture, int width, int height) { if (width == texture.Width & height == texture.Height) { return(texture); } else if (texture.BitsPerPixel != 32) { throw new NotSupportedException("The number of bits per pixel is not supported."); } else { OpenBveApi.Textures.TextureTransparencyType type = texture.GetTransparencyType(); /* * Convert the texture into a bitmap. * */ Bitmap bitmap = new Bitmap(texture.Width, texture.Height, PixelFormat.Format32bppArgb); BitmapData data = bitmap.LockBits(new Rectangle(0, 0, texture.Width, texture.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat); Marshal.Copy(texture.Bytes, 0, data.Scan0, texture.Bytes.Length); bitmap.UnlockBits(data); /* * Scale the bitmap. * */ Bitmap scaledBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); Graphics graphics = Graphics.FromImage(scaledBitmap); graphics.InterpolationMode = InterpolationMode.HighQualityBilinear; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.DrawImage(bitmap, new Rectangle(0, 0, width, height), new Rectangle(0, 0, texture.Width, texture.Height), GraphicsUnit.Pixel); graphics.Dispose(); bitmap.Dispose(); /* * Convert the bitmap into a texture. * */ data = scaledBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, scaledBitmap.PixelFormat); byte[] bytes = new byte[4 * width * height]; Marshal.Copy(data.Scan0, bytes, 0, bytes.Length); scaledBitmap.UnlockBits(data); scaledBitmap.Dispose(); /* * Ensure opaque and partially transparent * textures have valid alpha components. * */ if (type == OpenBveApi.Textures.TextureTransparencyType.Opaque) { for (int i = 3; i < bytes.Length; i += 4) { bytes[i] = 255; } } else if (type == OpenBveApi.Textures.TextureTransparencyType.Partial) { for (int i = 3; i < bytes.Length; i += 4) { if (bytes[i] < 128) { bytes[i] = 0; } else { bytes[i] = 255; } } } OpenBveApi.Textures.Texture result = new OpenBveApi.Textures.Texture(width, height, 32, bytes); return(result); } }
/// <summary>Loads a texture and returns the texture data.</summary> /// <param name="path">The path to the file or folder that contains the texture.</param> /// <param name="parameters">The parameters that specify how to process the texture.</param> /// <param name="texture">Receives the texture.</param> /// <returns>Whether loading the texture was successful.</returns> public override bool LoadTexture(string path, OpenBveApi.Textures.TextureParameters parameters, out OpenBveApi.Textures.Texture texture) { if (System.IO.File.Exists(path) || System.IO.Directory.Exists(path)) { for (int i = 0; i < Plugins.LoadedPlugins.Length; i++) { if (Plugins.LoadedPlugins[i].Texture != null) { try { if (Plugins.LoadedPlugins[i].Texture.CanLoadTexture(path)) { try { if (Plugins.LoadedPlugins[i].Texture.LoadTexture(path, out texture)) { //texture.CompatibleTransparencyMode = Interface.CurrentOptions.OldTransparencyMode; texture = texture.ApplyParameters(parameters); return(true); } Interface.AddMessage(Interface.MessageType.Error, false, "Plugin " + Plugins.LoadedPlugins[i].Title + " returned unsuccessfully at LoadTexture"); } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Error, false, "Plugin " + Plugins.LoadedPlugins[i].Title + " raised the following exception at LoadTexture:" + ex.Message); } } } catch (Exception ex) { Interface.AddMessage(Interface.MessageType.Error, false, "Plugin " + Plugins.LoadedPlugins[i].Title + " raised the following exception at CanLoadTexture:" + ex.Message); } } } Interface.AddMessage(Interface.MessageType.Error, false, "No plugin found that is capable of loading texture " + path); } else { ReportProblem(OpenBveApi.Hosts.ProblemType.PathNotFound, path); } texture = null; return(false); }
/// <summary>Creates a new texture.</summary> /// <param name="texture">The texture raw data.</param> public Texture(OpenBveApi.Textures.Texture texture) { this.Origin = new RawOrigin(texture); this.OpenGlTextures = new OpenGlTexture[] { new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture(), new OpenGlTexture() }; }
/// <summary>Resizes the specified texture to the specified width and height and returns the result.</summary> /// <param name="texture">The texture.</param> /// <param name="width">The new width.</param> /// <param name="height">The new height.</param> /// <returns>The resize texture, or the original if already of the specified size.</returns> /// <exception cref="System.NotSupportedException">The bits per pixel in the texture is not supported.</exception> internal static OpenBveApi.Textures.Texture Resize(OpenBveApi.Textures.Texture texture, int width, int height) { if (width == texture.Width & height == texture.Height) { return texture; } else if (texture.BitsPerPixel != 32) { throw new NotSupportedException("The number of bits per pixel is not supported."); } else { OpenBveApi.Textures.TextureTransparencyType type = texture.GetTransparencyType(); /* * Convert the texture into a bitmap. * */ Bitmap bitmap = new Bitmap(texture.Width, texture.Height, PixelFormat.Format32bppArgb); BitmapData data = bitmap.LockBits(new Rectangle(0, 0, texture.Width, texture.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat); Marshal.Copy(texture.Bytes, 0, data.Scan0, texture.Bytes.Length); bitmap.UnlockBits(data); /* * Scale the bitmap. * */ Bitmap scaledBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); Graphics graphics = Graphics.FromImage(scaledBitmap); graphics.InterpolationMode = InterpolationMode.HighQualityBilinear; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.DrawImage(bitmap, new Rectangle(0, 0, width, height), new Rectangle(0, 0, texture.Width, texture.Height), GraphicsUnit.Pixel); graphics.Dispose(); bitmap.Dispose(); /* * Convert the bitmap into a texture. * */ data = scaledBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, scaledBitmap.PixelFormat); byte[] bytes = new byte[4 * width * height]; Marshal.Copy(data.Scan0, bytes, 0, bytes.Length); scaledBitmap.UnlockBits(data); scaledBitmap.Dispose(); /* * Ensure opaque and partially transparent * textures have valid alpha components. * */ if (type == OpenBveApi.Textures.TextureTransparencyType.Opaque) { for (int i = 3; i < bytes.Length; i += 4) { bytes[i] = 255; } } else if (type == OpenBveApi.Textures.TextureTransparencyType.Partial) { for (int i = 3; i < bytes.Length; i += 4) { if (bytes[i] < 128) { bytes[i] = 0; } else { bytes[i] = 255; } } } OpenBveApi.Textures.Texture result = new OpenBveApi.Textures.Texture(width, height, 32, bytes); return result; } }
/// <summary>Loads all BVE4 signal or glow textures (Non animated file)</summary> /// <param name="BaseFile">The base file.</param> /// <param name="IsGlowTexture">Whether to load glow textures. If false, black is the transparent color. If true, the texture is edited according to the CSV route documentation.</param> /// <returns>All textures matching the base file.</returns> private static Textures.Texture[] LoadAllTextures(string BaseFile, bool IsGlowTexture) { string Folder = System.IO.Path.GetDirectoryName(BaseFile); if (Folder != null && !System.IO.Directory.Exists(Folder)) { return(new Textures.Texture[] { }); } string Name = System.IO.Path.GetFileNameWithoutExtension(BaseFile); Textures.Texture[] Textures = new Textures.Texture[] { }; if (Folder == null) { return(Textures); } string[] Files = System.IO.Directory.GetFiles(Folder); for (int i = 0; i < Files.Length; i++) { string a = System.IO.Path.GetFileNameWithoutExtension(Files[i]); if (a == null || Name == null) { return(Textures); } if (a.StartsWith(Name, StringComparison.OrdinalIgnoreCase)) { if (a.Length > Name.Length) { string b = a.Substring(Name.Length).TrimStart(); int j; if (int.TryParse(b, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out j)) { if (j >= 0) { string c = System.IO.Path.GetExtension(Files[i]); if (c == null) { return(Textures); } switch (c.ToLowerInvariant()) { case ".bmp": case ".gif": case ".jpg": case ".jpeg": case ".png": case ".tif": case ".tiff": if (j >= Textures.Length) { int n = Textures.Length; Array.Resize <Textures.Texture>(ref Textures, j + 1); for (int k = n; k < j; k++) { Textures[k] = null; } } if (IsGlowTexture) { OpenBveApi.Textures.Texture texture; if (Program.CurrentHost.LoadTexture(Files[i], null, out texture)) { if (texture.BitsPerPixel == 32) { byte[] bytes = texture.Bytes; InvertLightness(bytes); texture = new OpenBveApi.Textures.Texture(texture.Width, texture.Height, 32, bytes, texture.Palette); } Textures[j] = OpenBve.Textures.RegisterTexture(texture); } } else { OpenBve.Textures.RegisterTexture(Files[i], new OpenBveApi.Textures.TextureParameters(null, Color24.Black), out Textures[j]); } break; } } } } } } return(Textures); }
// load all textures /// <summary>Loads all signal or glow textures.</summary> /// <param name="BaseFile">The base file.</param> /// <param name="IsGlowTexture">Whether to load glow textures. If false, black is the transparent color. If true, the texture is edited according to the CSV route documentation.</param> /// <returns>All textures matching the base file.</returns> private static Textures.Texture[] LoadAllTextures(string BaseFile, bool IsGlowTexture) { string Folder = System.IO.Path.GetDirectoryName(BaseFile); if (!System.IO.Directory.Exists(Folder)) { return new Textures.Texture[] { }; } string Name = System.IO.Path.GetFileNameWithoutExtension(BaseFile); Textures.Texture[] Textures = new Textures.Texture[] { }; string[] Files = System.IO.Directory.GetFiles(Folder); for (int i = 0; i < Files.Length; i++) { string a = System.IO.Path.GetFileNameWithoutExtension(Files[i]); if (a.StartsWith(Name, StringComparison.OrdinalIgnoreCase)) { if (a.Length > Name.Length) { string b = a.Substring(Name.Length).TrimStart(); int j; if (int.TryParse(b, System.Globalization.NumberStyles.Integer, System.Globalization.CultureInfo.InvariantCulture, out j)) { if (j >= 0) { string c = System.IO.Path.GetExtension(Files[i]); switch (c.ToLowerInvariant()) { case ".bmp": case ".gif": case ".jpg": case ".jpeg": case ".png": case ".tif": case ".tiff": if (j >= Textures.Length) { int n = Textures.Length; Array.Resize<Textures.Texture>(ref Textures, j + 1); for (int k = n; k < j; k++) { Textures[k] = null; } } if (IsGlowTexture) { OpenBveApi.Textures.Texture texture; if (Program.CurrentHost.LoadTexture(Files[i], null, out texture)) { if (texture.BitsPerPixel == 32) { byte[] bytes = texture.Bytes; InvertLightness(bytes); texture = new OpenBveApi.Textures.Texture(texture.Width, texture.Height, 32, bytes); } Textures[j] = OpenBve.Textures.RegisterTexture(texture); } } else { OpenBve.Textures.RegisterTexture(Files[i], new OpenBveApi.Textures.TextureParameters(null, Color24.Black), out Textures[j]); } break; } } } } } } return Textures; }
/// <summary>Loads a texture and returns the texture data.</summary> /// <param name="path">The path to the file or folder that contains the texture.</param> /// <param name="parameters">The parameters that specify how to process the texture.</param> /// <param name="texture">Receives the texture.</param> /// <returns>Whether loading the texture was successful.</returns> public override bool LoadTexture(string path, OpenBveApi.Textures.TextureParameters parameters, out OpenBveApi.Textures.Texture texture) { if (System.IO.File.Exists(path) || System.IO.Directory.Exists(path)) { for (int i = 0; i < Plugins.LoadedPlugins.Length; i++) { if (Plugins.LoadedPlugins[i].TextureLoaders.Length > 0) { try { for (int l = 0; l < Plugins.LoadedPlugins[i].TextureLoaders.Length; l++) { if (Plugins.LoadedPlugins[i].TextureLoaders[l].CanLoadTexture(path)) { try { if (Plugins.LoadedPlugins[i].TextureLoaders[l].LoadTexture(path, out texture)) { texture = texture.ApplyParameters(parameters); return(true); } Debug.AddMessage(Debug.MessageType.Error, false, "Plugin " + Plugins.LoadedPlugins[i].Title + " returned unsuccessfully at LoadTexture" ); } catch (Exception ex) { Debug.AddMessage(Debug.MessageType.Error, false, "Plugin " + Plugins.LoadedPlugins[i].Title + " raised the following exception at LoadTexture:" + ex.Message ); } } } } catch (Exception ex) { Debug.AddMessage(Debug.MessageType.Error, false, "Plugin " + Plugins.LoadedPlugins[i].Title + " raised the following exception at CanLoadTexture:" + ex.Message ); } } } Debug.AddMessage(Debug.MessageType.Error, false, "No plugin found that is capable of loading texture " + path); } else { ReportProblem(OpenBveApi.Hosts.ProblemType.PathNotFound, path); } texture = null; return(false); }
// --- functions --- /// <summary>Gets the texture from this origin.</summary> /// <param name="texture">Receives the texture.</param> /// <returns>Whether the texture could be obtained successfully.</returns> internal override bool GetTexture(out OpenBveApi.Textures.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. * */ if (bitmap.PixelFormat != PixelFormat.Format32bppArgb) { Bitmap compatibleBitmap = new Bitmap(bitmap.Width, bitmap.Height, PixelFormat.Format32bppArgb); Graphics graphics = 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 OpenBveApi.Textures.Texture(width, height, 32, raw); 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; }
// --- functions --- /// <summary>Gets the texture from this origin.</summary> /// <param name="texture">Receives the texture.</param> /// <returns>Whether the texture could be obtained successfully.</returns> internal override bool GetTexture(out OpenBveApi.Textures.Texture texture) { texture = this.Texture; return(true); }
// --- constructors --- /// <summary>Creates a new raw data origin.</summary> /// <param name="texture">The texture raw data.</param> internal RawOrigin(OpenBveApi.Textures.Texture texture) { this.Texture = texture; }
// --- functions --- /// <summary>Gets the texture from this origin.</summary> /// <param name="texture">Receives the texture.</param> /// <returns>Whether the texture could be obtained successfully.</returns> internal abstract bool GetTexture(out OpenBveApi.Textures.Texture texture);
// --- constructors --- /// <summary>Creates a new raw data origin.</summary> /// <param name="texture">The texture raw data.</param> internal RawOrigin(OpenBveApi.Textures.Texture texture) { this.Texture = texture; }