Пример #1
0
        public TextureLumpInfo(TextureByteIndexPaletteWithMipmaps texture)
        {
            if (texture.Name.Length > NameLength - 1)
            {
                throw new ArgumentOutOfRangeException("texture");
            }

            char[] name = new char[NameLength];
            for (int i = 0; i < texture.Name.Length; i++)
            {
                name[i] = texture.Name[i];
            }

            this.Width  = (uint)texture.Width;
            this.Height = (uint)texture.Height;

            this.MipmapOffsets = new uint[MipmapOffsetsLength];
        }
Пример #2
0
        /// <summary>
        /// Load texture (with mipmaps) of this TextureLumpInfo.
        /// </summary>
        /// <param name="reader">Source stream.</param>
        /// <param name="texture_offset">Offset of this TextureLumpInfo in source stream.</param>
        public TextureByteIndexPaletteWithMipmaps LoadTexture(BinaryReader reader, long texture_offset = 0)
        {
            reader.BaseStream.Position = texture_offset + this.MipmapOffsets[0];

            // Indices to main texture (mipmap[0])
            byte[] indices = reader.ReadBytes((int)(this.Width * this.Height));

            // Loading color palette (after last mipmap)
            int last_mipmap_index = this.MipmapOffsets.Length - 1;

            reader.BaseStream.Position = (long)texture_offset + this.MipmapOffsets[last_mipmap_index] + ((this.Width / (int)Math.Pow(2, last_mipmap_index)) * (this.Height / (int)Math.Pow(2, last_mipmap_index))) + 2;
            Color[] palette = new Color[256];
            for (int p = 0; p < palette.Length; p++)
            {
                byte r = reader.ReadByte();
                byte g = reader.ReadByte();
                byte b = reader.ReadByte();

                palette[p] = new Color(r / 255f, g / 255f, b / 255f);
            }
            // Last index is transparent
            if (palette[255].r == 0 && palette[255].g == 0 && palette[255].b == 1f)
            {
                palette[255] = new Color(0, 0, 0, 0);
            }

            // Texture instance (with main texture and color palette)
            var texture = new TextureByteIndexPaletteWithMipmaps(this.Name_s, (int)this.Width, (int)this.Height, indices, palette);

            // Adding mipmaps to texture instance
            // mipmap[1] is first mipmap (0 is main texture)
            // Each mipmap has half dimensions then previous one
            for (int mipmap_level = 1; mipmap_level < this.MipmapOffsets.Length; mipmap_level++)
            {
                reader.BaseStream.Position = (long)texture_offset + this.MipmapOffsets[mipmap_level];

                int width  = (int)(this.Width / Math.Pow(2, mipmap_level));
                int height = (int)(this.Height / Math.Pow(2, mipmap_level));

                texture.AddMipmap(mipmap_level, reader.ReadBytes(width * height));
            }

            return(texture);
        }
Пример #3
0
        /// <summary>
        /// Save texture data.
        /// This should be run after saving the TextureLumpInfo
        /// </summary>
        /// <param name="writer">Output stream.</param>
        /// <param name="texture">Texture to save. Only transparent color can be palette[255] and must be R=0,G=0,B=255.</param>
        public static void SaveTexture(BinaryWriter writer, TextureByteIndexPaletteWithMipmaps texture)
        {
            // All MipMaps (including main texture)
            for (int m = 0; m < TextureLumpInfo.MipmapOffsetsLength; m++)
            {
                writer.Write(texture.GetMipmap(m));
                writer.Flush();
            }

            writer.Write((ushort)0);//2 dummy bytes
            writer.Flush();

            // Color palette
            {
                // Used colors in palette
                for (int p = 0; p < texture.Palette.Length; p++)
                {
                    var c = texture.Palette[p];
                    writer.Write((byte)(c.r * 255));                  //R
                    writer.Write((byte)(c.g * 255));                  //G
                    writer.Write((byte)(c.b * 255));                  //B
                }

                // Unused colors in palette
                for (int p = texture.Palette.Length; p < 255; p++)
                {
                    writer.Write(0); //R
                    writer.Write(0); //G
                    writer.Write(0); //B
                }

                // Transparent blue if unused
                if (texture.Palette.Length < 255)
                {
                    // Index: 255
                    writer.Write(0);   //R
                    writer.Write(0);   //G
                    writer.Write(255); //B
                }
            }
            writer.Flush();
        }