Game1.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. using System;
  2. using System.IO;
  3. using Microsoft.Xna.Framework;
  4. using Microsoft.Xna.Framework.Graphics;
  5. using Microsoft.Xna.Framework.Input;
  6. using tainicom.Aether.Graphics;
  7. using tainicom.Aether.Shaders;
  8. namespace Samples.Atlas
  9. {
  10. public class Game1 : Microsoft.Xna.Framework.Game
  11. {
  12. GraphicsDeviceManager graphics;
  13. SpriteBatch spriteBatch;
  14. SpriteFont font;
  15. KeyboardState previousKeyboardState;
  16. int mipLevel = 4;
  17. bool showAtlas = false;
  18. bool useGenerateBitmap = true;
  19. bool useMipmapPerSprite = true;
  20. Rectangle atlasSize = new Rectangle(0, 0, 1024, 512);
  21. RenderTarget2D rt;
  22. Tilemap tilemapMipmapPerSprite;
  23. Tilemap tilemapMipmap;
  24. Tilemap tilemapNoMipmap;
  25. public Game1()
  26. {
  27. graphics = new GraphicsDeviceManager(this);
  28. Content.RootDirectory = "Content";
  29. graphics.PreferredBackBufferWidth = atlasSize.Width;
  30. graphics.PreferredBackBufferHeight = atlasSize.Height;
  31. }
  32. protected override void LoadContent()
  33. {
  34. spriteBatch = new SpriteBatch(GraphicsDevice);
  35. font = Content.Load<SpriteFont>("font");
  36. rt = new RenderTarget2D(GraphicsDevice, atlasSize.Width, atlasSize.Height);
  37. // Load tilemap
  38. tilemapMipmapPerSprite = Content.Load<Tilemap>("tilemapMipmapPerSprite");
  39. tilemapMipmap = Content.Load<Tilemap>("tilemapMipmap");
  40. tilemapNoMipmap = Content.Load<Tilemap>("tilemapNoMipmap");
  41. #if DEBUG
  42. using (var fs = File.Create("tilemapNoMipmapAtlas.png"))
  43. tilemapNoMipmap.TextureAtlas.SaveAsPng(fs, tilemapNoMipmap.TextureAtlas.Width, tilemapNoMipmap.TextureAtlas.Height);
  44. using (var fs = File.Create("tilemapMipmapAtlas.png"))
  45. tilemapNoMipmap.TextureAtlas.SaveAsPng(fs, tilemapMipmap.TextureAtlas.Width, tilemapNoMipmap.TextureAtlas.Height);
  46. #endif
  47. }
  48. /// <param name="gameTime">Provides a snapshot of timing values.</param>
  49. protected override void Update(GameTime gameTime)
  50. {
  51. KeyboardState keyState = Keyboard.GetState();
  52. GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
  53. if (keyState.IsKeyDown(Keys.Escape) || gamePadState.Buttons.Back == ButtonState.Pressed)
  54. Exit();
  55. if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
  56. useMipmapPerSprite = !useMipmapPerSprite;
  57. if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
  58. useGenerateBitmap = !useGenerateBitmap;
  59. if (keyState.IsKeyDown(Keys.F3) && !previousKeyboardState.IsKeyDown(Keys.F3))
  60. showAtlas = !showAtlas;
  61. if (keyState.IsKeyDown(Keys.OemPlus) && !previousKeyboardState.IsKeyDown(Keys.OemPlus) && mipLevel < 10)
  62. mipLevel++;
  63. if (keyState.IsKeyDown(Keys.Add) && !previousKeyboardState.IsKeyDown(Keys.Add) && mipLevel < 10)
  64. mipLevel++;
  65. if (keyState.IsKeyDown(Keys.OemMinus) && !previousKeyboardState.IsKeyDown(Keys.OemMinus) && mipLevel > 0)
  66. mipLevel--;
  67. if (keyState.IsKeyDown(Keys.Subtract) && !previousKeyboardState.IsKeyDown(Keys.Subtract) && mipLevel > 0)
  68. mipLevel--;
  69. previousKeyboardState = keyState;
  70. base.Update(gameTime);
  71. }
  72. protected override void Draw(GameTime gameTime)
  73. {
  74. GraphicsDevice.BlendState = BlendState.Opaque;
  75. GraphicsDevice.DepthStencilState = DepthStencilState.Default;
  76. GraphicsDevice.SetRenderTarget(rt);
  77. GraphicsDevice.Clear(Color.Black);
  78. var currentTilemap = (useGenerateBitmap)
  79. ? (useMipmapPerSprite ? tilemapMipmapPerSprite : tilemapMipmap)
  80. : (tilemapNoMipmap);
  81. int mipLevel2 = (int)Math.Pow(2, mipLevel);
  82. var mipSize = atlasSize;
  83. mipSize.Width /= mipLevel2;
  84. mipSize.Height /= mipLevel2;
  85. if (showAtlas)
  86. {
  87. spriteBatch.Begin();
  88. spriteBatch.Draw(currentTilemap.TextureAtlas, mipSize, Color.White);
  89. spriteBatch.End();
  90. }
  91. else
  92. {
  93. DrawTilemap(gameTime, currentTilemap, mipSize);
  94. }
  95. GraphicsDevice.SetRenderTarget(null);
  96. GraphicsDevice.Clear(Color.CornflowerBlue);
  97. spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null);
  98. spriteBatch.Draw(rt, atlasSize, mipSize, Color.White);
  99. spriteBatch.End();
  100. spriteBatch.Begin();
  101. spriteBatch.DrawString(font, String.Format("[F1] MipmapPerSprite - ({0})", useMipmapPerSprite ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
  102. spriteBatch.DrawString(font, String.Format("[F2] GenerateMipmap - ({0})", useGenerateBitmap ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
  103. spriteBatch.DrawString(font, String.Format("[F3] {0}", showAtlas? "Show Tilemap" : "Show Atlas"), new Vector2(20, 60), Color.White);
  104. spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(20, 80), Color.White);
  105. spriteBatch.End();
  106. base.Draw(gameTime);
  107. }
  108. private void DrawTilemap(GameTime gameTime, Tilemap tilemap, Rectangle mipSize)
  109. {
  110. // setup tilemapEffect
  111. var viewport = GraphicsDevice.Viewport;
  112. Matrix projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1);
  113. Matrix halfPixelOffset = Matrix.Identity;
  114. #if XNA
  115. halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);
  116. #endif
  117. tilemap.Effect.Projection = halfPixelOffset * projection;
  118. // Draw tilemap
  119. spriteBatch.Begin(0, BlendState.AlphaBlend, SamplerState.PointWrap, null, null, tilemap.Effect);
  120. spriteBatch.Draw(tilemap.TextureMap, mipSize, Color.White);
  121. spriteBatch.End();
  122. }
  123. }
  124. }