#region Copyright /* -------------------------------------------------------------------------------- This source file is part of Xenocide by Project Xenocide Team For the latest info on Xenocide, see http://www.projectxenocide.com/ This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 2.5 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.5/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA. -------------------------------------------------------------------------------- */ /* * @file TextureAtlas.cs * @date Created: 2008/01/12 * @author File creator: David Teviotdale * @author Credits: none */ #endregion #region Using Statements using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Content; using Xenocide.Resources; #endregion namespace ProjectXenocide.UI.Scenes { /// /// A bitmap that contains a number of textures /// public class TextureAtlas { /// /// Ctor /// /// Width of the bitmap (in pixels) /// Height of the bitmap (in pixels) public TextureAtlas(int width, int height) { this.width = width; this.height = height; } /// /// Load/create the graphic resources needed by the terrain /// /// the display /// name of file holding the bitmap public void LoadContent(GraphicsDevice device, string filename) { bitmap = Texture2D.FromFile(device, filename); if ((bitmap.Height != height) || (bitmap.Width != width)) { throw new ArgumentException(Strings.EXCEPTION_BITMAP_WRONG_SIZE); } } /// /// Define the position of a texture in the bitmap /// /// leftmost pixel of texture (0 = left edge) /// topmost pixel of texture (0 = top edge) /// width of texture (in pixels) /// height of texture (in pixels) [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "x+1")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2233:OperationsShouldNotOverflow", MessageId = "y+1")] public void DefineTexture(int x, int y, int w, int h) { // due to "bleeding" from pixel sampler's linear filtering, // need to leave a one texel "gutter" around the textures float texWidth = (x + w - 2) / width; float texHeight = (y + h - 2) / height; textureCoords.Add(new Coord(new Vector4((x + 1) / width, (y + 1) / height, texWidth, texHeight))); } /// /// Holds UV co-ordinates of texture in atlas /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "We can handle nested types")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", Justification = "Should never compare two cells")] public struct Coord { /// /// Ctor /// /// layout is left, top, right, bottom public Coord(Vector4 data) { this.data = data; } /// /// Flip the horizontal co-ordinates /// public void FlipHorizontal() { float t = data.X; data.X = data.Z; data.Z = t; } #region Fields /// Return the UV co-ordinates of texture's Top Left corner public Vector2 LeftTop { get { return new Vector2(data.X, data.Y); } } /// Return the UV co-ordinates of texture's Bottom Left corner public Vector2 LeftBottom { get { return new Vector2(data.X, data.W); } } /// Return the UV co-ordinates of texture's Top Right corner public Vector2 RightTop { get { return new Vector2(data.Z, data.Y); } } /// Return the UV co-ordinates of texture's Bottom Right corner public Vector2 RightBottom { get { return new Vector2(data.Z, data.W); } } /// The UV co-ordinates of texture /// layout is left, top, right, bottom private Vector4 data; #endregion Fields } /// /// Construct and return the default texture atlas /// /// the display /// Default texture atlas public static TextureAtlas DefaultAtlas(GraphicsDevice device) { TextureAtlas atlas = new TextureAtlas(512, 512); atlas.LoadContent(device, @"Content\Textures\Battlescape\textureAtlas.png"); atlas.DefineTexture(0, 0, 0, 0); // dummy entry, "there is no texture" atlas.DefineTexture(384, 0, 128, 128); // floor, 4 grey tiles atlas.DefineTexture(0, 0, 1, 1); // ToDo: water atlas.DefineTexture(0, 0, 1, 1); // ToDo: X-Corp start/exit atlas.DefineTexture(0, 0, 1, 1); // ToDo: Grav Lift atlas.DefineTexture(127, 257, 128, 255); // house wall with wallpaper atlas.DefineTexture(0, 0, 1, 1); // ToDo: Door atlas.DefineTexture(0, 0, 1, 1); // ToDo: Window atlas.DefineTexture(319, 65, 64, 64); // floor, brick atlas.DefineTexture(384, 128, 128, 128); // floor, grass atlas.DefineTexture(128, 0, 128, 128); // floor, 16 blue tiles atlas.DefineTexture(0, 0, 128, 128); // shiny metal wall atlas.DefineTexture(0, 128, 128, 128); // shiny yellow wall return atlas; } #region Fields /// The co-ordinates of each texture in the bitmap public IList TextureCoords { get { return textureCoords; } } /// The bitmap holding the textures public Texture2D Bitmap { get { return bitmap; } } /// The co-ordinates of each texture in the bitmap private List textureCoords = new List(); /// Width of the bitmap (in pixels) private float width; /// Height of the bitmap (in pixels) private float height; /// The bitmap holding the textures private Texture2D bitmap; #endregion Fields } }