Represents a RGBA texture with 32 bits per pixel.
Пример #1
0
		/// <summary>Loads a texture from the specified file.</summary>
		/// <param name="file">The file that holds the texture.</param>
		/// <param name="texture">Receives the texture.</param>
		/// <returns>Whether loading the texture was successful.</returns>
		internal bool Parse(string file, out Texture texture) {
			/*
			 * Read the bitmap. This will be a bitmap of just
			 * any format, not necessarily the one that allows
			 * us to extract the bitmap data easily.
			 * */
			System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(file);
			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.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;
				bitmap.Dispose();
				/*
				 * 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);
				return true;
			} else {
				/*
				 * 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);
				bitmap.Dispose();
				CurrentHost.ReportProblem(ProblemType.InvalidOperation, "Invalid stride encountered.");
				texture = null;
				return false;
			}
		}
Пример #2
0
        /// <summary>Loads the specified texture.</summary>
        /// <param name="path">The path to the file or folder that contains the texture.</param>
        /// <param name="texture">Receives the texture.</param>
        /// <returns>Whether loading the texture was successful.</returns>
        public override bool LoadTexture(string path, out OpenBveApi.Textures.Texture texture)
        {
            byte[]   b = System.IO.File.ReadAllBytes(path);
            DDSImage d = new DDSImage(b);

            texture = d.myTexture;
            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]);
        }
Пример #4
0
		// --- apply parameters ---
		
		/// <summary>Applies parameters onto a texture.</summary>
		/// <param name="texture">The original texture.</param>
		/// <param name="parameters">The parameters, or a null reference.</param>
		/// <returns>The texture with the parameters applied.</returns>
		/// <exception cref="System.ArgumentException">Raised when the clip region is outside the texture bounds.</exception>
		/// <exception cref="System.NotSupportedException">Raised when the bits per pixel in the texture is other than 32.</exception>
		internal static Texture ApplyParameters(Texture texture, TextureParameters parameters) {
			Texture result = texture;
			if (parameters != null) {
				if (parameters.ClipRegion != null) {
					result = ExtractClipRegion(result, parameters.ClipRegion);
				}
				if (parameters.TransparentColor != null) {
					result = ApplyTransparentColor(result, parameters.TransparentColor);
				}
			}
			return result;
		}
Пример #5
0
		// --- extract clip region ---
		
		/// <summary>Extracts a clip region from a texture.</summary>
		/// <param name="texture">The original texture.</param>
		/// <param name="region">The clip region, or a null reference.</param>
		/// <returns>The texture with the extracted clip region.</returns>
		/// <exception cref="System.ArgumentException">Raised when the clip region is outside the texture bounds.</exception>
		/// <exception cref="System.NotSupportedException">Raised when the number of bits per pixel in the texture is not supported.</exception>
		internal static Texture ExtractClipRegion(Texture texture, TextureClipRegion region)
		{
		    if (region == null || region.Left == 0 && region.Top == 0 && region.Width == texture.Width && region.Height == texture.Height) {
				return texture;
			}
		    if (region.Left < 0 || region.Top < 0 || region.Width <= 0 || region.Height <= 0 || region.Left + region.Width > texture.Width || region.Top + region.Height > texture.Height) {
		        throw new ArgumentException();
		    }
		    if (texture.BitsPerPixel == 24 | texture.BitsPerPixel == 32) {
		        int width = texture.Width;
		        int height = texture.Height;
		        byte[] bytes = texture.Bytes;
		        int clipLeft = region.Left;
		        int clipTop = region.Top;
		        int clipWidth = region.Width;
		        int clipHeight = region.Height;
		        if (texture.BitsPerPixel == 24) {
		            byte[] newBytes = new byte[3 * clipWidth * clipHeight];
		            int i = 0;
		            for (int y = 0; y < clipHeight; y++) {
		                int j = 3 * width * (clipTop + y) + 3 * clipLeft;
		                for (int x = 0; x < clipWidth; x++) {
		                    newBytes[i + 0] = bytes[j + 0];
		                    newBytes[i + 1] = bytes[j + 1];
		                    newBytes[i + 2] = bytes[j + 2];
		                    i += 3;
		                    j += 3;
		                }
		            }
		            return new Texture(clipWidth, clipHeight, 24, newBytes);
		        } else {
		            byte[] newBytes = new byte[4 * clipWidth * clipHeight];
		            int i = 0;
		            for (int y = 0; y < clipHeight; y++) {
		                int j = 4 * width * (clipTop + y) + 4 * clipLeft;
		                for (int x = 0; x < clipWidth; x++) {
		                    newBytes[i + 0] = bytes[j + 0];
		                    newBytes[i + 1] = bytes[j + 1];
		                    newBytes[i + 2] = bytes[j + 2];
		                    newBytes[i + 3] = bytes[j + 3];
		                    i += 4;
		                    j += 4;
		                }
		            }
		            return new Texture(clipWidth, clipHeight, 32, newBytes);
		        }
		    }
		    throw new NotSupportedException();
		}
        // --- 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, System.Drawing.Imaging.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();
        }
Пример #8
0
 // --- apply transparent color ---
 /// <summary>Applies a transparent color onto a texture.</summary>
 /// <param name="texture">The original texture.</param>
 /// <param name="color">The transparent color, or a null reference.</param>
 /// <returns>The texture with the transparent color applied.</returns>
 /// <exception cref="System.NotSupportedException">Raised when the number of bits per pixel in the texture is not supported.</exception>
 internal static Texture ApplyTransparentColor(Texture texture, Color24? color)
 {
     if (color == null) {
         return texture;
     } else if (texture.BitsPerPixel == 32) {
         int width = texture.Width;
         int height = texture.Height;
         byte[] source = texture.Bytes;
         byte[] target = new byte[4 * width * height];
         byte r = color.Value.R;
         byte g = color.Value.G;
         byte b = color.Value.B;
         if (source[0] == r && source[1] == g && source[2] == b) {
             target[0] = 128;
             target[1] = 128;
             target[2] = 128;
             target[3] = 0;
         } else {
             target[0] = source[0];
             target[1] = source[1];
             target[2] = source[2];
             target[3] = source[3];
         }
         for (int i = 4; i < source.Length; i += 4) {
             if (source[i] == r && source[i + 1] == g && source[i + 2] == b) {
                 target[i + 0] = target[i - 4];
                 target[i + 1] = target[i - 3];
                 target[i + 2] = target[i - 2];
                 target[i + 3] = 0;
             } else {
                 target[i + 0] = source[i + 0];
                 target[i + 1] = source[i + 1];
                 target[i + 2] = source[i + 2];
                 target[i + 3] = source[i + 3];
             }
         }
         return new Texture(width, height, 32, target);
     } else {
         throw new NotSupportedException();
     }
 }
Пример #9
0
 public override bool RegisterTexture(Bitmap texture, TextureParameters parameters, out OpenBveApi.Textures.Texture handle)
 {
     handle = new Texture(texture, parameters);
     return(true);
 }
Пример #10
0
 /// <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 < Program.CurrentHost.Plugins.Length; i++)
         {
             if (Program.CurrentHost.Plugins[i].Texture != null)
             {
                 try
                 {
                     if (Program.CurrentHost.Plugins[i].Texture.CanLoadTexture(path))
                     {
                         try
                         {
                             if (Program.CurrentHost.Plugins[i].Texture.LoadTexture(path, out texture))
                             {
                                 //texture.CompatibleTransparencyMode = Interface.CurrentOptions.OldTransparencyMode;
                                 texture = texture.ApplyParameters(parameters);
                                 return(true);
                             }
                             Interface.AddMessage(MessageType.Error, false, "Plugin " + Program.CurrentHost.Plugins[i].Title + " returned unsuccessfully at LoadTexture");
                         }
                         catch (Exception ex)
                         {
                             Interface.AddMessage(MessageType.Error, false, "Plugin " + Program.CurrentHost.Plugins[i].Title + " raised the following exception at LoadTexture:" + ex.Message);
                         }
                     }
                 }
                 catch (Exception ex)
                 {
                     Interface.AddMessage(MessageType.Error, false, "Plugin " + Program.CurrentHost.Plugins[i].Title + " raised the following exception at CanLoadTexture:" + ex.Message);
                 }
             }
         }
         FileInfo f = new FileInfo(path);
         if (f.Length == 0)
         {
             Interface.AddMessage(MessageType.Error, false, "Zero-byte texture file encountered at " + path);
         }
         else
         {
             Interface.AddMessage(MessageType.Error, false, "No plugin found that is capable of loading texture " + path);
         }
     }
     else
     {
         ReportProblem(OpenBveApi.Hosts.ProblemType.PathNotFound, path);
     }
     texture = null;
     return(false);
 }
Пример #11
0
		/// <summary>Loads the specified texture.</summary>
		/// <param name="path">The path to the file or folder that contains the texture.</param>
		/// <param name="texture">Receives the texture.</param>
		/// <returns>Whether loading the texture was successful.</returns>
		public abstract bool LoadTexture(string path, out Texture texture);
        /// <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);
            }
            if (texture.BitsPerPixel != 32)
            {
                throw new NotSupportedException("The number of bits per pixel is not supported.");
            }
            OpenBveApi.Textures.TextureTransparencyType type = texture.GetTransparencyType();

            /*
             * Convert the texture into a bitmap.
             * */
            Bitmap     bitmap = new Bitmap(texture.Width, texture.Height, System.Drawing.Imaging.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, System.Drawing.Imaging.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)
                {
                    bytes[i] = bytes[i] < 128 ? (byte)0 : (byte)255;
                }
            }
            OpenBveApi.Textures.Texture result = new OpenBveApi.Textures.Texture(width, height, 32, bytes, texture.Palette);
            return(result);
        }
Пример #13
0
 /// <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 virtual bool LoadTexture(string path, TextureParameters parameters, out Texture texture)
 {
     texture = null;
     return false;
 }
Пример #14
0
		/// <summary>Loads the specified texture.</summary>
		/// <param name="path">The path to the file or folder that contains the texture.</param>
		/// <param name="texture">Receives the texture.</param>
		/// <returns>Whether loading the texture was successful.</returns>
		public override bool LoadTexture(string path, out Texture texture) {
			return Parse(path, out texture);
		}
Пример #15
0
		/// <summary>Loads the specified texture.</summary>
		/// <param name="path">The path to the file or folder that contains the texture.</param>
		/// <param name="texture">Receives the texture.</param>
		/// <returns>Whether loading the texture was successful.</returns>
		public override bool LoadTexture(string path, out Texture texture) {
			texture = LoadFromFile(path);
			return true;
		}