2
0

TilemapSampleComponent.cs 6.8 KB

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