Browse Source

Samples DrawableGameComponent

Nick Kastellanos 2 years ago
parent
commit
682a0af987
36 changed files with 1004 additions and 622 deletions
  1. 195 0
      Samples/Animation/AnimationSampleComponent.cs
  2. 5 140
      Samples/Animation/SampleGame.cs
  3. 1 0
      Samples/Animation/Samples.Animation.DESKTOPGL.NET6.csproj
  4. 1 0
      Samples/Animation/Samples.Animation.WINDOWS.NET6.csproj
  5. 1 0
      Samples/Animation/Samples.Animation.WINDOWS.csproj
  6. 2 1
      Samples/Animation/Samples.Animation.XNA.csproj
  7. 154 0
      Samples/Atlas/AtlasSampleComponent.cs
  8. 9 96
      Samples/Atlas/SampleGame.cs
  9. 1 0
      Samples/Atlas/Samples.Atlas.DESKTOPGL.NET6.csproj
  10. 1 0
      Samples/Atlas/Samples.Atlas.WINDOWS.NET6.csproj
  11. 1 0
      Samples/Atlas/Samples.Atlas.WINDOWS.csproj
  12. 2 1
      Samples/Atlas/Samples.Atlas.XNA.csproj
  13. 168 0
      Samples/Deferred/DeferredSampleComponent.cs
  14. 5 124
      Samples/Deferred/SampleGame.cs
  15. 1 0
      Samples/Deferred/Samples.Deferred.DESKTOPGL.NET6.csproj
  16. 1 0
      Samples/Deferred/Samples.Deferred.WINDOWS.NET6.csproj
  17. 1 0
      Samples/Deferred/Samples.Deferred.WINDOWS.csproj
  18. 2 1
      Samples/Deferred/Samples.Deferred.XNA.csproj
  19. 116 0
      Samples/FXAA/FXAASampleComponent.cs
  20. 4 70
      Samples/FXAA/SampleGame.cs
  21. 1 0
      Samples/FXAA/Samples.FXAA.DESKTOPGL.NET6.csproj
  22. 1 0
      Samples/FXAA/Samples.FXAA.WINDOWS.NET6.csproj
  23. 1 0
      Samples/FXAA/Samples.FXAA.WINDOWS.csproj
  24. 2 1
      Samples/FXAA/Samples.FXAA.XNA.csproj
  25. 135 0
      Samples/SLMC/SLMCSampleComponent.cs
  26. 6 77
      Samples/SLMC/SampleGame.cs
  27. 1 0
      Samples/SLMC/Samples.SLMC.DESKTOPGL.NET6.csproj
  28. 1 0
      Samples/SLMC/Samples.SLMC.WINDOWS.NET6.csproj
  29. 1 0
      Samples/SLMC/Samples.SLMC.WINDOWS.csproj
  30. 2 1
      Samples/SLMC/Samples.SLMC.XNA.csproj
  31. 8 109
      Samples/Tilemap/SampleGame.cs
  32. 1 0
      Samples/Tilemap/Samples.Tilemaps.DESKTOPGL.NET6.csproj
  33. 1 0
      Samples/Tilemap/Samples.Tilemaps.WINDOWS.NET6.csproj
  34. 1 0
      Samples/Tilemap/Samples.Tilemaps.WINDOWS.csproj
  35. 2 1
      Samples/Tilemap/Samples.Tilemaps.XNA.csproj
  36. 169 0
      Samples/Tilemap/TilemapSampleComponent.cs

+ 195 - 0
Samples/Animation/AnimationSampleComponent.cs

@@ -0,0 +1,195 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using nkast.Aether.Animation;
+using nkast.Aether.Shaders.Components;
+
+
+namespace Samples.Animation
+{
+    internal class AnimationSampleComponent : DrawableGameComponent
+    {
+        enum DrawMode : int
+        {
+            GPU,
+            CPU,
+        }
+
+        ContentManager Content;
+        SpriteBatch spriteBatch;
+        SpriteFont font;
+        InfiniteGridComponent grid;
+
+        Model _model_CPU;
+        Model _model_GPU;
+        Animations _animations;
+        DrawMode drawMode = DrawMode.GPU;
+
+        KeyboardState prevKeyboardState;
+
+        public AnimationSampleComponent(Game game) : base(game)
+        {
+        }
+
+        /// <summary>Initializes the component. Used to load non-graphical resources.</summary>
+        public override void Initialize()
+        {
+            Content = new ContentManager(Game.Services, "Content");
+
+            base.Initialize();
+        }
+
+        /// <summary>Load graphical resources needed by this component.</summary>
+        protected override void LoadContent()
+        {
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            font = Content.Load<SpriteFont>("font");
+
+            grid = new InfiniteGridComponent(GraphicsDevice, Content);
+            grid.Initialize();
+
+            _model_CPU = Content.Load<Model>("Dude/dude");
+            _model_GPU = Content.Load<Model>("Dude/dude_GPU");
+
+            _animations = _model_CPU.GetAnimations(); // Animation Data are the same between the two models
+            var clip = _animations.Clips["Take 001"];
+            _animations.SetClip(clip);
+        }
+
+        /// <summary>Unload graphical resources needed by this component.</summary>
+        protected override void UnloadContent()
+        {
+            Content.Unload();
+        }
+
+        /// <summary>Update the component.</summary>
+        /// <param name="gameTime">GameTime of the Game.</param>
+        public override void Update(GameTime gameTime)
+        {
+            var keyboardState = Keyboard.GetState();
+            var gamePadState = GamePad.GetState(PlayerIndex.One);
+
+            if ((keyboardState.IsKeyDown(Keys.Space) && prevKeyboardState.IsKeyUp(Keys.Space)) || gamePadState.Buttons.A == ButtonState.Pressed)
+            {
+                int drawModesCount = Enum.GetValues(drawMode.GetType()).Length;
+                drawMode = (DrawMode)(((int)drawMode + 1) % drawModesCount);
+            }
+
+            prevKeyboardState = keyboardState;
+
+            _animations.Update(gameTime.ElapsedGameTime, true, Matrix.Identity);
+
+        }
+
+        private Vector3 Position = Vector3.Zero;
+        private float Zoom = 100f;
+        private float RotationY = 0.0f;
+        private float RotationX = 0.0f;
+        private Matrix gameWorldRotation = Matrix.Identity;
+
+
+        Stopwatch sw = new Stopwatch();
+        double msecMin = double.MaxValue;
+        double msecMax = 0;
+        double avg = 0;
+        double acc = 0;
+        int c;
+
+        /// <summary>Draw this component.</summary>
+        /// <param name="gameTime">The time elapsed since the last call to Draw.</param>
+        public override void Draw(GameTime gameTime)
+        {
+
+            float aspectRatio = GraphicsDevice.Viewport.AspectRatio;
+            Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 0.01f, 500.0f);
+            Matrix view = Matrix.CreateLookAt(
+                new Vector3(0.0f, 35.0f, -Zoom),
+                new Vector3(0.0f, 35.0f, 0),
+                Vector3.Up);
+
+            // Draw Grid
+            grid.Projection = projection;
+            grid.View = view;
+            //grid.EditMatrix = Matrix.Identity; // XY plane
+            grid.EditMatrix = Matrix.CreateFromAxisAngle(Vector3.UnitX, MathHelper.ToRadians(-90)); // XZ plane
+            grid.Draw(gameTime);
+
+            GraphicsDevice.BlendState = BlendState.Opaque;
+            GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
+            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
+            GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
+
+            Model m = _model_CPU;
+            if (drawMode == DrawMode.CPU)
+                m = _model_CPU;
+            else if (drawMode == DrawMode.GPU)
+                m = _model_GPU;
+
+            Matrix[] transforms = new Matrix[m.Bones.Count];
+            m.CopyAbsoluteBoneTransformsTo(transforms);
+
+            sw.Reset();
+            sw.Start();
+            foreach (ModelMesh mesh in m.Meshes)
+            {
+                foreach (var part in mesh.MeshParts)
+                {
+                    if (drawMode == DrawMode.CPU)
+                        ((BasicEffect)part.Effect).SpecularColor = Vector3.Zero;
+                    else if (drawMode == DrawMode.GPU)
+                        ((SkinnedEffect)part.Effect).SpecularColor = Vector3.Zero;
+                    ConfigureEffectMatrices((IEffectMatrices)part.Effect, Matrix.Identity, view, projection);
+                    ConfigureEffectLighting((IEffectLights)part.Effect);
+
+                    if (drawMode == DrawMode.CPU)
+                        part.UpdateVertices(_animations.AnimationTransforms); // animate vertices on CPU
+                    else if (drawMode == DrawMode.GPU)
+                        ((SkinnedEffect)part.Effect).SetBoneTransforms(_animations.AnimationTransforms);// animate vertices on GPU
+                }
+                mesh.Draw();
+            }
+            sw.Stop();
+
+            double msec = sw.Elapsed.TotalMilliseconds;
+            msecMin = Math.Min(msecMin, msec);
+            if (avg != 0)
+                msecMax = Math.Max(msecMax, msec);
+            acc += msec; c++;
+            if (c > 60 * 2)
+            {
+                avg = acc / c;
+                acc = c = 0;
+            }
+
+            spriteBatch.Begin();
+            spriteBatch.DrawString(font, "Draw Mode: " + drawMode, new Vector2(32, 32), Color.White);
+            spriteBatch.DrawString(font, msec.ToString("#0.000", CultureInfo.InvariantCulture) + "ms", new Vector2(32, GraphicsDevice.Viewport.Height - 130), Color.White);
+            spriteBatch.DrawString(font, avg.ToString("#0.000", CultureInfo.InvariantCulture) + "ms (avg)", new Vector2(32, GraphicsDevice.Viewport.Height - 100), Color.White);
+            spriteBatch.DrawString(font, msecMin.ToString("#0.000", CultureInfo.InvariantCulture) + "ms (min)", new Vector2(32, GraphicsDevice.Viewport.Height - 70), Color.White);
+            spriteBatch.DrawString(font, msecMax.ToString("#0.000", CultureInfo.InvariantCulture) + "ms (max)", new Vector2(32, GraphicsDevice.Viewport.Height - 40), Color.White);
+            spriteBatch.End();
+        }
+
+        private void ConfigureEffectMatrices(IEffectMatrices effect, Matrix world, Matrix view, Matrix projection)
+        {
+            effect.World = world;
+            effect.View = view;
+            effect.Projection = projection;
+        }
+
+        private void ConfigureEffectLighting(IEffectLights effect)
+        {
+            effect.EnableDefaultLighting();
+            effect.DirectionalLight0.Direction = Vector3.Backward;
+            effect.DirectionalLight0.Enabled = true;
+            effect.DirectionalLight1.Enabled = false;
+            effect.DirectionalLight2.Enabled = false;
+        }
+    }
+}

+ 5 - 140
Samples/Animation/SampleGame.cs

@@ -1,38 +1,23 @@
 using System;
-using System.Diagnostics;
-using System.Globalization;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Input;
-using nkast.Aether.Animation;
-using nkast.Aether.Shaders.Components;
 
 namespace Samples.Animation
 {
-    enum DrawMode : int
-    {
-        GPU,
-        CPU,
-    }
-
     public class SampleGame : Game
     {
         GraphicsDeviceManager graphics;
-        SpriteBatch spriteBatch;
-        SpriteFont font;
-        InfiniteGridComponent grid;
-
-        Model _model_CPU;
-        Model _model_GPU;
-        Animations _animations;
-        DrawMode drawMode = DrawMode.GPU;
 
-        KeyboardState prevKeyboardState;
+        AnimationSampleComponent _animationSampleComponent;
 
         public SampleGame()
         {
             graphics = new GraphicsDeviceManager(this);
             Content.RootDirectory = "Content";
+
+            _animationSampleComponent = new AnimationSampleComponent(this);
+            Components.Add(_animationSampleComponent);
         }
 
         protected override void Initialize()
@@ -42,18 +27,6 @@ namespace Samples.Animation
 
         protected override void LoadContent()
         {
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-            font = Content.Load<SpriteFont>("font");
-
-            grid = new InfiniteGridComponent(GraphicsDevice, Content);
-            grid.Initialize();
-                        
-            _model_CPU = Content.Load<Model>("Dude/dude");
-            _model_GPU = Content.Load<Model>("Dude/dude_GPU");
-
-            _animations = _model_CPU.GetAnimations(); // Animation Data are the same between the two models
-            var clip = _animations.Clips["Take 001"];
-            _animations.SetClip(clip);
         }
 
         protected override void UnloadContent()
@@ -69,124 +42,16 @@ namespace Samples.Animation
             if (keyboardState.IsKeyDown(Keys.Escape) || gamePadState.Buttons.Back == ButtonState.Pressed)
                 this.Exit();
 
-            if ((keyboardState.IsKeyDown(Keys.Space) && prevKeyboardState.IsKeyUp(Keys.Space)) || gamePadState.Buttons.A == ButtonState.Pressed)
-            {
-                int drawModesCount = Enum.GetValues(drawMode.GetType()).Length;
-                drawMode = (DrawMode)(((int)drawMode + 1) % drawModesCount);
-            }
-
-            prevKeyboardState = keyboardState;
-
-            _animations.Update(gameTime.ElapsedGameTime, true, Matrix.Identity);
-
             base.Update(gameTime);
         }
 
-        private Vector3 Position = Vector3.Zero;
-        private float Zoom = 100f;
-        private float RotationY = 0.0f;
-        private float RotationX = 0.0f;
-        private Matrix gameWorldRotation = Matrix.Identity;
-
-
-        Stopwatch sw = new Stopwatch();
-        double msecMin = double.MaxValue;
-        double msecMax = 0;
-        double avg = 0;
-        double acc = 0;
-        int c;
-
         protected override void Draw(GameTime gameTime)
         {
+            GraphicsDevice.SetRenderTarget(null);
             GraphicsDevice.Clear(Color.Black);
-
-            float aspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;
-            Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), aspectRatio, 0.01f, 500.0f);
-            Matrix view = Matrix.CreateLookAt(
-                new Vector3(0.0f, 35.0f, -Zoom),
-                new Vector3(0.0f, 35.0f, 0), 
-                Vector3.Up);
-
-            // Draw Grid
-            grid.Projection = projection;
-            grid.View = view;
-            //grid.EditMatrix = Matrix.Identity; // XY plane
-            grid.EditMatrix = Matrix.CreateFromAxisAngle(Vector3.UnitX, MathHelper.ToRadians(-90)); // XZ plane
-            grid.Draw(gameTime);
-
-            GraphicsDevice.BlendState = BlendState.Opaque;
-            GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
-            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
-            GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
-
-            Model m = _model_CPU;
-            if (drawMode == DrawMode.CPU)
-                m = _model_CPU;
-            else if (drawMode == DrawMode.GPU)
-                m = _model_GPU;
-
-            Matrix[] transforms = new Matrix[m.Bones.Count];
-            m.CopyAbsoluteBoneTransformsTo(transforms);
-
-            sw.Reset();
-            sw.Start();
-            foreach (ModelMesh mesh in m.Meshes)
-            {
-                foreach (var part in mesh.MeshParts)
-                {
-                    if (drawMode == DrawMode.CPU)
-                        ((BasicEffect)part.Effect).SpecularColor = Vector3.Zero;
-                    else if (drawMode == DrawMode.GPU)
-                        ((SkinnedEffect)part.Effect).SpecularColor = Vector3.Zero;                        
-                    ConfigureEffectMatrices((IEffectMatrices)part.Effect, Matrix.Identity, view, projection);
-                    ConfigureEffectLighting((IEffectLights)part.Effect);
-                    
-                    if (drawMode == DrawMode.CPU)
-                        part.UpdateVertices(_animations.AnimationTransforms); // animate vertices on CPU
-                    else if (drawMode == DrawMode.GPU)
-                        ((SkinnedEffect)part.Effect).SetBoneTransforms(_animations.AnimationTransforms);// animate vertices on GPU
-                }
-                mesh.Draw();
-            }
-            sw.Stop();
-
-            double msec = sw.Elapsed.TotalMilliseconds;
-            msecMin = Math.Min(msecMin, msec);
-            if(avg != 0 )
-                msecMax = Math.Max(msecMax, msec);
-            acc += msec; c++;
-            if(c>60*2)
-            {
-                avg = acc/c;
-                acc = c = 0;
-            }
-
-            spriteBatch.Begin();
-            spriteBatch.DrawString(font, "Draw Mode: " + drawMode, new Vector2(32, 32), Color.White);
-            spriteBatch.DrawString(font, msec.ToString("#0.000",CultureInfo.InvariantCulture) + "ms", new Vector2(32, GraphicsDevice.Viewport.Height - 130), Color.White);
-            spriteBatch.DrawString(font, avg.ToString("#0.000",CultureInfo.InvariantCulture) + "ms (avg)", new Vector2(32, GraphicsDevice.Viewport.Height - 100), Color.White);
-            spriteBatch.DrawString(font, msecMin.ToString("#0.000",CultureInfo.InvariantCulture) + "ms (min)", new Vector2(32, GraphicsDevice.Viewport.Height - 70), Color.White);
-            spriteBatch.DrawString(font, msecMax.ToString("#0.000",CultureInfo.InvariantCulture) + "ms (max)", new Vector2(32, GraphicsDevice.Viewport.Height - 40), Color.White);
-            spriteBatch.End();
             
             base.Draw(gameTime);
         }
 
-        private void ConfigureEffectMatrices(IEffectMatrices effect, Matrix world, Matrix view, Matrix projection)
-        {
-            effect.World = world;
-            effect.View = view;
-            effect.Projection = projection;
-        }
-
-        private void ConfigureEffectLighting(IEffectLights effect)
-        {
-            effect.EnableDefaultLighting();
-            effect.DirectionalLight0.Direction = Vector3.Backward;
-            effect.DirectionalLight0.Enabled = true;
-            effect.DirectionalLight1.Enabled = false;
-            effect.DirectionalLight2.Enabled = false;
-        }
-
     }
 }

+ 1 - 0
Samples/Animation/Samples.Animation.DESKTOPGL.NET6.csproj

@@ -24,6 +24,7 @@
     <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="AnimationSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 1 - 0
Samples/Animation/Samples.Animation.WINDOWS.NET6.csproj

@@ -25,6 +25,7 @@
     <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="AnimationSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 1 - 0
Samples/Animation/Samples.Animation.WINDOWS.csproj

@@ -43,6 +43,7 @@
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="AnimationSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 2 - 1
Samples/Animation/Samples.Animation.XNA.csproj

@@ -67,8 +67,9 @@
     <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Program.cs" />
+    <Compile Include="AnimationSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
+    <Compile Include="Program.cs" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs" />

+ 154 - 0
Samples/Atlas/AtlasSampleComponent.cs

@@ -0,0 +1,154 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using nkast.Aether.Graphics;
+
+namespace Samples.Atlas
+{
+    internal class AtlasSampleComponent : DrawableGameComponent
+    {
+        GraphicsDeviceManager graphics;
+        ContentManager Content;
+        SpriteBatch spriteBatch;
+        SpriteFont font;
+
+        KeyboardState previousKeyboardState;
+
+        int mipLevel = 4;
+        bool showAtlas = false;
+        bool useGenerateBitmap = true;
+        bool useMipmapPerSprite = true;
+        RenderTarget2D rt;
+
+        Rectangle atlasSize = new Rectangle(0, 0, 1024, 512);
+        
+        TextureAtlas atlasMipmapPerSprite;
+        TextureAtlas atlasMipmap;
+        TextureAtlas atlasNoMipmap;
+
+        public AtlasSampleComponent(Game game, GraphicsDeviceManager graphics) : base(game)
+        {
+            this.graphics = graphics;
+        }
+
+        /// <summary>Initializes the component. Used to load non-graphical resources.</summary>
+        public override void Initialize()
+        {
+            Content = new ContentManager(Game.Services, "Content");
+
+            base.Initialize();
+        }
+
+        /// <summary>Load graphical resources needed by this component.</summary>
+        protected override void LoadContent()
+        {
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            font = Content.Load<SpriteFont>("font");
+            rt = new RenderTarget2D(GraphicsDevice, atlasSize.Width, atlasSize.Height);
+
+            // Load Atlas
+            atlasMipmapPerSprite = Content.Load<TextureAtlas>("atlasMipmapPerSprite");
+            atlasMipmap = Content.Load<TextureAtlas>("atlasMipmap");
+            atlasNoMipmap = Content.Load<TextureAtlas>("atlasNoMipmap");
+            
+            graphics.PreferredBackBufferWidth = atlasSize.Width;
+            graphics.PreferredBackBufferHeight = atlasSize.Height;
+            graphics.ApplyChanges();
+        }
+
+        /// <summary>Unload graphical resources needed by this component.</summary>
+        protected override void UnloadContent()
+        {
+            Content.Unload();
+        }
+
+        /// <summary>Update the component.</summary>
+        /// <param name="gameTime">GameTime of the Game.</param>
+        public override void Update(GameTime gameTime)
+        {
+            KeyboardState keyState = Keyboard.GetState();
+            GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
+
+            if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
+                useMipmapPerSprite = !useMipmapPerSprite;
+            if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
+                useGenerateBitmap = !useGenerateBitmap;
+            if (keyState.IsKeyDown(Keys.F3) && !previousKeyboardState.IsKeyDown(Keys.F3))
+                showAtlas = !showAtlas;
+            if (keyState.IsKeyDown(Keys.OemPlus) && !previousKeyboardState.IsKeyDown(Keys.OemPlus) && mipLevel < 10)
+                mipLevel++;
+            if (keyState.IsKeyDown(Keys.Add) && !previousKeyboardState.IsKeyDown(Keys.Add) && mipLevel < 10)
+                mipLevel++;
+            if (keyState.IsKeyDown(Keys.OemMinus) && !previousKeyboardState.IsKeyDown(Keys.OemMinus) && mipLevel > 0)
+                mipLevel--;
+            if (keyState.IsKeyDown(Keys.Subtract) && !previousKeyboardState.IsKeyDown(Keys.Subtract) && mipLevel > 0)
+                mipLevel--;
+
+            previousKeyboardState = keyState;
+        }
+
+        private void DrawSprites(GameTime gameTime, SpriteBatch spriteBatch, TextureAtlas atlas)
+        {
+            var sprite18 = atlas.Sprites["18"];
+            spriteBatch.Draw(sprite18, new Vector2(128, 128), Color.White);
+
+            var spriteMushroom_2 = atlas.Sprites["Mushroom_2"];
+            spriteBatch.Draw(spriteMushroom_2, new Vector2(256 + 128, 128), Color.White);
+
+            var sprite10 = atlas.Sprites["10"];
+            spriteBatch.Draw(sprite10, new Vector2(512, 128), Color.White);
+        }
+
+        /// <summary>Draw this component.</summary>
+        /// <param name="gameTime">The time elapsed since the last call to Draw.</param>
+        public override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice.BlendState = BlendState.Opaque;
+            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
+
+            int mipLevel2 = (int)Math.Pow(2, mipLevel);
+            var mipSize = atlasSize;
+            mipSize.Width /= mipLevel2;
+            mipSize.Height /= mipLevel2;
+
+            GraphicsDevice.SetRenderTarget(rt);
+            GraphicsDevice.Clear(Color.Black);
+
+            var currentAtlas = (useGenerateBitmap) ? (useMipmapPerSprite ? atlasMipmapPerSprite : atlasMipmap) : atlasNoMipmap;
+
+            if (showAtlas)
+            {
+                spriteBatch.Begin();
+                spriteBatch.Draw(currentAtlas.Texture, mipSize, Color.White);
+                spriteBatch.End();
+            }
+            else
+            {
+                var scaleMtx = Matrix.CreateScale(1f / mipLevel2);
+                spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, scaleMtx);
+                // Draw sprites from Atlas
+                DrawSprites(gameTime, spriteBatch, currentAtlas);
+                spriteBatch.End();
+            }
+
+
+            GraphicsDevice.SetRenderTarget(null);
+            GraphicsDevice.Clear(Color.CornflowerBlue);
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null);
+            spriteBatch.Draw(rt, atlasSize, mipSize, Color.White);
+            spriteBatch.End();
+
+            spriteBatch.Begin();
+            spriteBatch.DrawString(font, String.Format("[F1] MipmapPerSprite - ({0})", useMipmapPerSprite ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F2] GenerateMipmap - ({0})", useGenerateBitmap ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F3] {0}", showAtlas ? "Show Sprites" : "Show Atlas"), new Vector2(20, 60), Color.White);
+            spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(20, 80), Color.White);
+            spriteBatch.End();
+        }
+
+    }
+}

+ 9 - 96
Samples/Atlas/SampleGame.cs

@@ -2,50 +2,29 @@ using System;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Input;
-using nkast.Aether.Graphics;
 
 namespace Samples.Atlas
 {
     public class SampleGame : Game
     {
         GraphicsDeviceManager graphics;
-        SpriteBatch spriteBatch;
-        SpriteFont font;
-
-        KeyboardState previousKeyboardState;
-
-        int mipLevel = 4;
-        bool showAtlas = false;
-        bool useGenerateBitmap = true;
-        bool useMipmapPerSprite = true;
-        Rectangle atlasSize = new Rectangle(0, 0, 1024, 512);
-        RenderTarget2D rt;
-
-
-        TextureAtlas atlasMipmapPerSprite;
-        TextureAtlas atlasMipmap;
-        TextureAtlas atlasNoMipmap;
         
+        AtlasSampleComponent _atlasSampleComponent;
+
         public SampleGame()
         {
             graphics = new GraphicsDeviceManager(this);
             Content.RootDirectory = "Content";
 
-            graphics.PreferredBackBufferWidth = atlasSize.Width;
-            graphics.PreferredBackBufferHeight = atlasSize.Height;
+            graphics.PreferredBackBufferWidth = 800;
+            graphics.PreferredBackBufferHeight = 480;
+
+            _atlasSampleComponent = new AtlasSampleComponent(this, graphics);
+            Components.Add(_atlasSampleComponent);
         }
 
         protected override void LoadContent()
-        {            
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-            font = Content.Load<SpriteFont>("font");
-
-            rt = new RenderTarget2D(GraphicsDevice, atlasSize.Width, atlasSize.Height);
-
-            // Load Atlas
-            atlasMipmapPerSprite = Content.Load<TextureAtlas>("atlasMipmapPerSprite");
-            atlasMipmap = Content.Load<TextureAtlas>("atlasMipmap");
-            atlasNoMipmap = Content.Load<TextureAtlas>("atlasNoMipmap");
+        {
         }
         
         /// <param name="gameTime">Provides a snapshot of timing values.</param>
@@ -57,82 +36,16 @@ namespace Samples.Atlas
             if (keyState.IsKeyDown(Keys.Escape) || gamePadState.Buttons.Back == ButtonState.Pressed)
                 Exit();
 
-            if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
-                useMipmapPerSprite = !useMipmapPerSprite;
-            if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
-                useGenerateBitmap = !useGenerateBitmap;
-            if (keyState.IsKeyDown(Keys.F3) && !previousKeyboardState.IsKeyDown(Keys.F3))
-                showAtlas = !showAtlas;
-            if (keyState.IsKeyDown(Keys.OemPlus) && !previousKeyboardState.IsKeyDown(Keys.OemPlus) && mipLevel < 10)
-                mipLevel++;
-            if (keyState.IsKeyDown(Keys.Add) && !previousKeyboardState.IsKeyDown(Keys.Add) && mipLevel < 10)
-                mipLevel++;
-            if (keyState.IsKeyDown(Keys.OemMinus) && !previousKeyboardState.IsKeyDown(Keys.OemMinus) && mipLevel > 0)
-                mipLevel--;
-            if (keyState.IsKeyDown(Keys.Subtract) && !previousKeyboardState.IsKeyDown(Keys.Subtract) && mipLevel > 0)
-                mipLevel--;
-            
-            previousKeyboardState = keyState;
             base.Update(gameTime);
         }
         
         protected override void Draw(GameTime gameTime)
         {
-            GraphicsDevice.BlendState = BlendState.Opaque;
-            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
-
-            int mipLevel2 = (int)Math.Pow(2, mipLevel);
-            var mipSize = atlasSize;
-            mipSize.Width /= mipLevel2;
-            mipSize.Height /= mipLevel2;
-            
-            GraphicsDevice.SetRenderTarget(rt);
-            GraphicsDevice.Clear(Color.Black);
-
-            var currentAtlas = (useGenerateBitmap) ? (useMipmapPerSprite ? atlasMipmapPerSprite : atlasMipmap) : atlasNoMipmap;
-            
-            if (showAtlas)
-            {
-                spriteBatch.Begin();
-                spriteBatch.Draw(currentAtlas.Texture, mipSize, Color.White);
-                spriteBatch.End();
-            }
-            else
-            {
-                var scaleMtx = Matrix.CreateScale(1f/mipLevel2);
-                spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, scaleMtx);
-                // Draw sprites from Atlas
-                DrawSprites(gameTime, spriteBatch, currentAtlas);
-                spriteBatch.End();
-            }
-
-
             GraphicsDevice.SetRenderTarget(null);
-            GraphicsDevice.Clear(Color.CornflowerBlue);
-            spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null);
-            spriteBatch.Draw(rt, atlasSize, mipSize, Color.White);
-            spriteBatch.End();
-
-            spriteBatch.Begin();
-            spriteBatch.DrawString(font, String.Format("[F1] MipmapPerSprite - ({0})", useMipmapPerSprite ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
-            spriteBatch.DrawString(font, String.Format("[F2] GenerateMipmap - ({0})", useGenerateBitmap ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
-            spriteBatch.DrawString(font, String.Format("[F3] {0}", showAtlas? "Show Sprites" : "Show Atlas"), new Vector2(20, 60), Color.White);
-            spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(20, 80), Color.White);
-            spriteBatch.End();
+            GraphicsDevice.Clear(Color.Black);
 
             base.Draw(gameTime);
         }
 
-        private void DrawSprites(GameTime gameTime, SpriteBatch spriteBatch, TextureAtlas atlas)
-        {
-            var sprite18 = atlas.Sprites["18"];
-            spriteBatch.Draw(sprite18, new Vector2(128,128), Color.White);
-
-            var spriteMushroom_2 = atlas.Sprites["Mushroom_2"];
-            spriteBatch.Draw(spriteMushroom_2, new Vector2(256 + 128, 128), Color.White);
-
-            var sprite10 = atlas.Sprites["10"];
-            spriteBatch.Draw(sprite10, new Vector2(512, 128), Color.White);
-        }
     }
 }

+ 1 - 0
Samples/Atlas/Samples.Atlas.DESKTOPGL.NET6.csproj

@@ -24,6 +24,7 @@
     <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="AtlasSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 1 - 0
Samples/Atlas/Samples.Atlas.WINDOWS.NET6.csproj

@@ -25,6 +25,7 @@
     <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="AtlasSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 1 - 0
Samples/Atlas/Samples.Atlas.WINDOWS.csproj

@@ -43,6 +43,7 @@
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="AtlasSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 2 - 1
Samples/Atlas/Samples.Atlas.XNA.csproj

@@ -67,8 +67,9 @@
     <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Program.cs" />
+    <Compile Include="AtlasSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
+    <Compile Include="Program.cs" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs" />

+ 168 - 0
Samples/Deferred/DeferredSampleComponent.cs

@@ -0,0 +1,168 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+
+namespace Samples.Deferred
+{
+    internal class DeferredSampleComponent : DrawableGameComponent
+    {
+        ContentManager Content;
+        SpriteBatch spriteBatch;
+        SpriteFont font;
+
+        KeyboardState previousKeyboardState;
+        
+        bool useLightA = true;
+        bool useLightB = true;
+        bool useLightC = true; 
+        bool rotate = true;
+
+        Vector3 cameraPosition;
+
+        Matrix world;
+        Matrix projection;
+        Matrix view;
+
+        Spaceship spaceship;
+        Vector3 spaceshipPos = Vector3.Zero;
+        float time = 0;
+
+        DeferredRendering _deferredRendering;
+
+        const float LightAIntensity = 10f;
+        const float LightBIntensity = 1f;
+        const float LightCIntensity = 3f;
+
+        float lightAcurrentIntensity = LightAIntensity;
+        float lightBcurrentIntensity = LightBIntensity;
+        float lightCcurrentIntensity = LightCIntensity;
+
+        public DeferredSampleComponent(Game game) : base(game)
+        {
+        }
+
+        /// <summary>Initializes the component. Used to load non-graphical resources.</summary>
+        public override void Initialize()
+        {
+            Content = new ContentManager(Game.Services, "Content");
+
+            base.Initialize();
+        }
+
+        /// <summary>Load graphical resources needed by this component.</summary>
+        protected override void LoadContent()
+        {
+            // Create and load our tank
+            spaceship = new Spaceship();
+            spaceship.Load(Content);
+            
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            font = Content.Load<SpriteFont>("font");
+            
+            projection = Matrix.CreatePerspectiveFieldOfView(
+                MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 2000f, 6000f);
+
+            _deferredRendering = new DeferredRendering(GraphicsDevice, Content);
+        }
+
+        /// <summary>Unload graphical resources needed by this component.</summary>
+        protected override void UnloadContent()
+        {
+            Content.Unload();
+        }
+
+        /// <summary>Update the component.</summary>
+        /// <param name="gameTime">GameTime of the Game.</param>
+        public override void Update(GameTime gameTime)
+        {
+            KeyboardState keyState = Keyboard.GetState();
+            GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
+
+            if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
+                useLightA = !useLightA;
+            if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
+                useLightB = !useLightB;
+            if (keyState.IsKeyDown(Keys.F3) && !previousKeyboardState.IsKeyDown(Keys.F3))
+                useLightC = !useLightC;
+            if (keyState.IsKeyDown(Keys.F4) && !previousKeyboardState.IsKeyDown(Keys.F4))
+                rotate = !rotate;
+
+            if (rotate)
+                time += (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+            float lightAtargetIntensity = (useLightA) ? LightAIntensity : 0f;
+            float lightBtargetIntensity = (useLightB) ? LightBIntensity : 0f;
+            float lightCtargetIntensity = (useLightC) ? LightCIntensity : 0f;
+            lightAcurrentIntensity += (lightAtargetIntensity - lightAcurrentIntensity) * (0.1f);
+            lightBcurrentIntensity += (lightBtargetIntensity - lightBcurrentIntensity) * (0.1f);
+            lightCcurrentIntensity += (lightCtargetIntensity - lightCcurrentIntensity) * (0.1f);
+
+            world = Matrix.CreateFromAxisAngle(Vector3.Up, time);
+            cameraPosition = new Vector3(0, 2800f, 2800f);
+            
+            view = Matrix.CreateLookAt(
+                   cameraPosition,
+                   Vector3.Zero,
+                   Vector3.Up);
+
+            previousKeyboardState = keyState;
+        }
+
+        /// <summary>Draw this component.</summary>
+        /// <param name="gameTime">The time elapsed since the last call to Draw.</param>
+        public override void Draw(GameTime gameTime)
+        {
+            _deferredRendering.SetGBuffer();
+            _deferredRendering.ClearGBuffer();
+            
+            //draw models
+            GraphicsDevice.BlendState = BlendState.Opaque;
+            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
+            spaceship.DrawDeferred(GraphicsDevice, _deferredRendering.basicEffect, world, view, projection);
+
+            _deferredRendering.ResolveGBuffer();
+            GraphicsDevice.SetRenderTarget(_deferredRendering.lightRT);
+            GraphicsDevice.Clear(Color.Transparent);
+
+            // Draw lights
+
+            //float ambient = 0.1f;
+            //GraphicsDevice.Clear(new Color(ambient, ambient, ambient, 0f));
+
+            var lightPos = spaceshipPos + new Vector3(2000,100,0);
+            _deferredRendering.DrawPointLight(
+                lightPos, Color.Goldenrod, 2000f, lightAcurrentIntensity,
+                view, projection, cameraPosition);
+
+            var light2Pos = spaceshipPos + new Vector3(0, 800, 1000);
+            _deferredRendering.DrawPointLight(
+                light2Pos, Color.CornflowerBlue, 900f, lightBcurrentIntensity,
+                view, projection, cameraPosition);
+
+            var spotLightPos = spaceshipPos + new Vector3(-1000,1000,0);
+            var lightDirection = spaceshipPos - spotLightPos;
+            _deferredRendering.DrawSpotLight(
+                spotLightPos, Color.White, 1000f, lightCcurrentIntensity, lightDirection,
+                MathHelper.ToRadians(3f), MathHelper.ToRadians(3f),
+                view, projection, cameraPosition);
+            
+            _deferredRendering.Combine();
+
+            
+            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullNone);
+            _deferredRendering.DrawRTs(spriteBatch);
+            spriteBatch.End();
+            spriteBatch.Begin();
+            spriteBatch.DrawString(font, String.Format("[F1] PointLight A - ({0})", useLightA ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F2] PointLight B - ({0})", useLightB ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F3] SpotLight C - ({0})", useLightC ? "ON" : "OFF"), new Vector2(20, 60), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F4] Rotate - ({0})", rotate ? "ON" : "OFF"), new Vector2(20, 80), Color.White);
+            spriteBatch.End();
+        }
+
+    }
+}

+ 5 - 124
Samples/Deferred/SampleGame.cs

@@ -1,53 +1,15 @@
-#region File Description
-//-----------------------------------------------------------------------------
-// SplitScreenGame.cs
-//
-// Microsoft XNA Community Game Platform
-// Copyright (C) Microsoft Corporation. All rights reserved.
-//-----------------------------------------------------------------------------
-#endregion
-
-#region Using Statements
 using System;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Input;
-#endregion
 
 namespace Samples.Deferred
 {
     public class SampleGame : Game
     {
         GraphicsDeviceManager graphics;
-        SpriteBatch spriteBatch;
-        SpriteFont font;
-
-        KeyboardState previousKeyboardState;
-        
-        bool useLightA = true;
-        bool useLightB = true;
-        bool useLightC = true; 
-        bool rotate = true;
-
-        Vector3 cameraPosition;
-
-        Matrix world;
-        Matrix projection;
-        Matrix view;
 
-        Spaceship spaceship;
-        Vector3 spaceshipPos = Vector3.Zero;
-        float time = 0;
-
-        DeferredRendering _deferredRendering;
-
-        const float LightAIntensity = 10f;
-        const float LightBIntensity = 1f;
-        const float LightCIntensity = 3f;
-
-        float lightAcurrentIntensity = LightAIntensity;
-        float lightBcurrentIntensity = LightBIntensity;
-        float lightCcurrentIntensity = LightCIntensity;
+        DeferredSampleComponent _deferredSampleComponent;
 
         public SampleGame()
         {
@@ -56,21 +18,12 @@ namespace Samples.Deferred
 
             graphics.GraphicsProfile = GraphicsProfile.HiDef;
 
+            _deferredSampleComponent = new DeferredSampleComponent(this);
+            Components.Add(_deferredSampleComponent);
         }
 
         protected override void LoadContent()
         {
-            // Create and load our tank
-            spaceship = new Spaceship();
-            spaceship.Load(Content);
-            
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-            font = Content.Load<SpriteFont>("font");
-            
-            projection = Matrix.CreatePerspectiveFieldOfView(
-                MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 2000f, 6000f);
-
-            _deferredRendering = new DeferredRendering(GraphicsDevice, Content);
         }
         
         /// <param name="gameTime">Provides a snapshot of timing values.</param>
@@ -82,85 +35,13 @@ namespace Samples.Deferred
             if (keyState.IsKeyDown(Keys.Escape) || gamePadState.Buttons.Back == ButtonState.Pressed)
                 Exit();
 
-            if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
-                useLightA = !useLightA;
-            if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
-                useLightB = !useLightB;
-            if (keyState.IsKeyDown(Keys.F3) && !previousKeyboardState.IsKeyDown(Keys.F3))
-                useLightC = !useLightC;
-            if (keyState.IsKeyDown(Keys.F4) && !previousKeyboardState.IsKeyDown(Keys.F4))
-                rotate = !rotate;
-
-            if (rotate)
-                time += (float)gameTime.ElapsedGameTime.TotalSeconds;
-
-            float lightAtargetIntensity = (useLightA) ? LightAIntensity : 0f;
-            float lightBtargetIntensity = (useLightB) ? LightBIntensity : 0f;
-            float lightCtargetIntensity = (useLightC) ? LightCIntensity : 0f;
-            lightAcurrentIntensity += (lightAtargetIntensity - lightAcurrentIntensity) * (0.1f);
-            lightBcurrentIntensity += (lightBtargetIntensity - lightBcurrentIntensity) * (0.1f);
-            lightCcurrentIntensity += (lightCtargetIntensity - lightCcurrentIntensity) * (0.1f);
-
-            world = Matrix.CreateFromAxisAngle(Vector3.Up, time);
-            cameraPosition = new Vector3(0, 2800f, 2800f);
-            
-            view = Matrix.CreateLookAt(
-                   cameraPosition,
-                   Vector3.Zero,
-                   Vector3.Up);
-
-            previousKeyboardState = keyState;
             base.Update(gameTime);
         }
         
         protected override void Draw(GameTime gameTime)
         {
-            _deferredRendering.SetGBuffer();
-            _deferredRendering.ClearGBuffer();
-            
-            //draw models
-            GraphicsDevice.BlendState = BlendState.Opaque;
-            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
-            spaceship.DrawDeferred(GraphicsDevice, _deferredRendering.basicEffect, world, view, projection);
-
-            _deferredRendering.ResolveGBuffer();
-            GraphicsDevice.SetRenderTarget(_deferredRendering.lightRT);
-            GraphicsDevice.Clear(Color.Transparent);
-
-            // Draw lights
-
-            //float ambient = 0.1f;
-            //GraphicsDevice.Clear(new Color(ambient, ambient, ambient, 0f));
-
-            var lightPos = spaceshipPos + new Vector3(2000,100,0);
-            _deferredRendering.DrawPointLight(
-                lightPos, Color.Goldenrod, 2000f, lightAcurrentIntensity,
-                view, projection, cameraPosition);
-
-            var light2Pos = spaceshipPos + new Vector3(0, 800, 1000);
-            _deferredRendering.DrawPointLight(
-                light2Pos, Color.CornflowerBlue, 900f, lightBcurrentIntensity,
-                view, projection, cameraPosition);
-
-            var spotLightPos = spaceshipPos + new Vector3(-1000,1000,0);
-            var lightDirection = spaceshipPos - spotLightPos;
-            _deferredRendering.DrawSpotLight(
-                spotLightPos, Color.White, 1000f, lightCcurrentIntensity, lightDirection,
-                MathHelper.ToRadians(3f), MathHelper.ToRadians(3f),
-                view, projection, cameraPosition);
-            
-            _deferredRendering.Combine();
-
-            
-            spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.Opaque, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullNone);
-            _deferredRendering.DrawRTs(spriteBatch);
-            spriteBatch.End();
-            spriteBatch.Begin();
-            spriteBatch.DrawString(font, String.Format("[F1] PointLight A - ({0})", useLightA ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
-            spriteBatch.DrawString(font, String.Format("[F2] PointLight B - ({0})", useLightB ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
-            spriteBatch.DrawString(font, String.Format("[F3] SpotLight C - ({0})", useLightC ? "ON" : "OFF"), new Vector2(20, 60), Color.White);
-            spriteBatch.DrawString(font, String.Format("[F4] Rotate - ({0})", rotate ? "ON" : "OFF"), new Vector2(20, 80), Color.White);
-            spriteBatch.End();
+            GraphicsDevice.SetRenderTarget(null);
+            GraphicsDevice.Clear(Color.Black);
 
             base.Draw(gameTime);
         }

+ 1 - 0
Samples/Deferred/Samples.Deferred.DESKTOPGL.NET6.csproj

@@ -25,6 +25,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="DeferredRendering.cs" />
+    <Compile Include="DeferredSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="QuadRenderer.cs" />

+ 1 - 0
Samples/Deferred/Samples.Deferred.WINDOWS.NET6.csproj

@@ -26,6 +26,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="DeferredRendering.cs" />
+    <Compile Include="DeferredSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="QuadRenderer.cs" />

+ 1 - 0
Samples/Deferred/Samples.Deferred.WINDOWS.csproj

@@ -44,6 +44,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="DeferredRendering.cs" />
+    <Compile Include="DeferredSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="QuadRenderer.cs" />

+ 2 - 1
Samples/Deferred/Samples.Deferred.XNA.csproj

@@ -68,8 +68,9 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="DeferredRendering.cs" />
-    <Compile Include="Program.cs" />
+    <Compile Include="DeferredSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
+    <Compile Include="Program.cs" />
     <Compile Include="QuadRenderer.cs" />
     <Compile Include="Spaceship.cs" />
   </ItemGroup>

+ 116 - 0
Samples/FXAA/FXAASampleComponent.cs

@@ -0,0 +1,116 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+
+namespace Samples.FXAA
+{
+    internal class FXAASampleComponent : DrawableGameComponent
+    {
+        ContentManager Content;
+        SpriteBatch spriteBatch;
+        SpriteFont font;
+
+        KeyboardState previousKeyboardState;
+
+        bool useFXAA = true;
+        bool rotate = true;
+        
+        Vector3 cameraPosition;
+
+        Matrix world;
+        Matrix projection;
+        Matrix view;
+
+        Spaceship spaceship;
+        Vector3 spaceshipPos = Vector3.Zero;
+        float time = 0;
+        
+        AntiAliasing _antiAliasing;
+
+
+        public FXAASampleComponent(Game game) : base(game)
+        {
+        }
+
+        /// <summary>Initializes the component. Used to load non-graphical resources.</summary>
+        public override void Initialize()
+        {
+            Content = new ContentManager(Game.Services, "Content");
+
+            base.Initialize();
+        }
+
+        /// <summary>Load graphical resources needed by this component.</summary>
+        protected override void LoadContent()
+        {
+            // Create and load our tank
+            spaceship = new Spaceship();
+            spaceship.Load(Content);
+            
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            font = Content.Load<SpriteFont>("font");
+            
+            projection = Matrix.CreatePerspectiveFieldOfView(
+                MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 10f, 10000f);
+            
+            _antiAliasing = new AntiAliasing(GraphicsDevice);
+        }
+
+        /// <summary>Unload graphical resources needed by this component.</summary>
+        protected override void UnloadContent()
+        {
+            Content.Unload();
+        }
+
+        /// <summary>Update the component.</summary>
+        /// <param name="gameTime">GameTime of the Game.</param>
+        public override void Update(GameTime gameTime)
+        {
+            KeyboardState keyState = Keyboard.GetState();
+            GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
+
+
+            if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
+                useFXAA = !useFXAA;
+            if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
+                rotate = !rotate;
+
+            if (rotate)
+                time += (float)gameTime.ElapsedGameTime.TotalSeconds;
+
+            world = Matrix.CreateFromAxisAngle(Vector3.Up, time);
+            cameraPosition = new Vector3(0, 2800f, 2800f);
+            
+            view = Matrix.CreateLookAt(
+                   cameraPosition,
+                   Vector3.Zero,
+                   Vector3.Up);
+
+            previousKeyboardState = keyState;
+        }
+
+        /// <summary>Draw this component.</summary>
+        /// <param name="gameTime">The time elapsed since the last call to Draw.</param>
+        public override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice.BlendState = BlendState.Opaque;
+            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
+
+            _antiAliasing.SetRenderTarget(GraphicsDevice.Viewport, Color.Black);
+            spaceship.Draw(world, view, projection);
+            GraphicsDevice.SetRenderTarget(null);
+
+            _antiAliasing.DrawRenderTarget( (useFXAA ? 3 : 0), GraphicsDevice.Viewport, false);
+
+            spriteBatch.Begin();
+            spriteBatch.DrawString(font, String.Format("[F1] FXAA - ({0})", useFXAA ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F2] Rotate - ({0})", rotate ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
+            spriteBatch.End();
+        }
+
+    }
+}

+ 4 - 70
Samples/FXAA/SampleGame.cs

@@ -1,43 +1,14 @@
-#region File Description
-//-----------------------------------------------------------------------------
-// SplitScreenGame.cs
-//
-// Microsoft XNA Community Game Platform
-// Copyright (C) Microsoft Corporation. All rights reserved.
-//-----------------------------------------------------------------------------
-#endregion
-
-#region Using Statements
 using System;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Input;
-#endregion
 
 namespace Samples.FXAA
 {
     public class SampleGame : Game
     {
         GraphicsDeviceManager graphics;
-        SpriteBatch spriteBatch;
-        SpriteFont font;
-
-        KeyboardState previousKeyboardState;
-
-        bool useFXAA = true;
-        bool rotate = true;
-        
-        Vector3 cameraPosition;
-
-        Matrix world;
-        Matrix projection;
-        Matrix view;
-
-        Spaceship spaceship;
-        Vector3 spaceshipPos = Vector3.Zero;
-        float time = 0;
-        
-        AntiAliasing _antiAliasing;
+        FXAASampleComponent _fxaaSampleComponent;
 
         public SampleGame()
         {
@@ -46,21 +17,12 @@ namespace Samples.FXAA
 
             graphics.GraphicsProfile = GraphicsProfile.HiDef;
 
+            _fxaaSampleComponent = new FXAASampleComponent(this);
+            Components.Add(_fxaaSampleComponent);
         }
 
         protected override void LoadContent()
         {
-            // Create and load our tank
-            spaceship = new Spaceship();
-            spaceship.Load(Content);
-            
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-            font = Content.Load<SpriteFont>("font");
-            
-            projection = Matrix.CreatePerspectiveFieldOfView(
-                MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 10f, 10000f);
-            
-            _antiAliasing = new AntiAliasing(GraphicsDevice);
         }
         
         /// <param name="gameTime">Provides a snapshot of timing values.</param>
@@ -72,41 +34,13 @@ namespace Samples.FXAA
             if (keyState.IsKeyDown(Keys.Escape) || gamePadState.Buttons.Back == ButtonState.Pressed)
                 Exit();
 
-            if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
-                useFXAA = !useFXAA;
-            if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
-                rotate = !rotate;
-
-            if (rotate)
-                time += (float)gameTime.ElapsedGameTime.TotalSeconds;
-
-            world = Matrix.CreateFromAxisAngle(Vector3.Up, time);
-            cameraPosition = new Vector3(0, 2800f, 2800f);
-            
-            view = Matrix.CreateLookAt(
-                   cameraPosition,
-                   Vector3.Zero,
-                   Vector3.Up);
-
-            previousKeyboardState = keyState;
             base.Update(gameTime);
         }
         
         protected override void Draw(GameTime gameTime)
         {
-            GraphicsDevice.BlendState = BlendState.Opaque;
-            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
-
-            _antiAliasing.SetRenderTarget(GraphicsDevice.Viewport, Color.Black);
-            spaceship.Draw(world, view, projection);
             GraphicsDevice.SetRenderTarget(null);
-
-            _antiAliasing.DrawRenderTarget( (useFXAA ? 3 : 0), GraphicsDevice.Viewport, false);
-
-            spriteBatch.Begin();
-            spriteBatch.DrawString(font, String.Format("[F1] FXAA - ({0})", useFXAA ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
-            spriteBatch.DrawString(font, String.Format("[F2] Rotate - ({0})", rotate ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
-            spriteBatch.End();
+            GraphicsDevice.Clear(Color.Black);
 
             base.Draw(gameTime);
         }

+ 1 - 0
Samples/FXAA/Samples.FXAA.DESKTOPGL.NET6.csproj

@@ -25,6 +25,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="AntiAliasing.cs" />
+    <Compile Include="FXAASampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Spaceship.cs" />

+ 1 - 0
Samples/FXAA/Samples.FXAA.WINDOWS.NET6.csproj

@@ -26,6 +26,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="AntiAliasing.cs" />
+    <Compile Include="FXAASampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Spaceship.cs" />

+ 1 - 0
Samples/FXAA/Samples.FXAA.WINDOWS.csproj

@@ -44,6 +44,7 @@
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="AntiAliasing.cs" />
+    <Compile Include="FXAASampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
     <Compile Include="Spaceship.cs" />

+ 2 - 1
Samples/FXAA/Samples.FXAA.XNA.csproj

@@ -68,8 +68,9 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="AntiAliasing.cs" />
-    <Compile Include="Program.cs" />
+    <Compile Include="FXAASampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
+    <Compile Include="Program.cs" />
     <Compile Include="Spaceship.cs" />
   </ItemGroup>
   <ItemGroup>

+ 135 - 0
Samples/SLMC/SLMCSampleComponent.cs

@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+
+namespace Samples.SLMC
+{
+    internal class SLMCSampleComponent : DrawableGameComponent
+    {
+        GraphicsDeviceManager graphics;
+        ContentManager Content;
+        SpriteBatch spriteBatch;
+        SpriteFont font;
+
+        KeyboardState previousKeyboardState;
+        
+        int mipLevel = 0;
+        Rectangle rtSize;
+        RenderTarget2D rt;
+
+        Texture2D tx;
+        
+        public SLMCSampleComponent(Game game, GraphicsDeviceManager graphics) : base(game)
+        {
+            this.graphics = graphics;
+        }
+
+        /// <summary>Initializes the component. Used to load non-graphical resources.</summary>
+        public override void Initialize()
+        {
+            Content = new ContentManager(Game.Services, "Content");
+
+            base.Initialize();
+        }
+
+        /// <summary>Load graphical resources needed by this component.</summary>
+        protected override void LoadContent()
+        {   
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            font = Content.Load<SpriteFont>("font");
+            
+            tx = Content.Load<Texture2D>("b_c0123");
+            rtSize = new Rectangle(0, 0, tx.Width * (1+4), tx.Height);
+
+            rt = new RenderTarget2D(GraphicsDevice, rtSize.Width, rtSize.Height);
+
+            graphics.PreferredBackBufferWidth = (int)rtSize.Width;
+            graphics.PreferredBackBufferHeight = (int)rtSize.Height;
+            graphics.ApplyChanges();
+        }
+
+        /// <summary>Unload graphical resources needed by this component.</summary>
+        protected override void UnloadContent()
+        {
+            Content.Unload();
+        }
+
+        /// <summary>Update the component.</summary>
+        /// <param name="gameTime">GameTime of the Game.</param>
+        public override void Update(GameTime gameTime)
+        {
+            KeyboardState keyState = Keyboard.GetState();
+            GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
+
+
+            if (keyState.IsKeyDown(Keys.OemPlus) && !previousKeyboardState.IsKeyDown(Keys.OemPlus) && mipLevel < tx.LevelCount-1)
+                mipLevel++;
+            if (keyState.IsKeyDown(Keys.Add) && !previousKeyboardState.IsKeyDown(Keys.Add) && mipLevel < tx.LevelCount-1)
+                mipLevel++;
+            if (keyState.IsKeyDown(Keys.OemMinus) && !previousKeyboardState.IsKeyDown(Keys.OemMinus) && mipLevel > 0)
+                mipLevel--;
+            if (keyState.IsKeyDown(Keys.Subtract) && !previousKeyboardState.IsKeyDown(Keys.Subtract) && mipLevel > 0)
+                mipLevel--;
+            
+            previousKeyboardState = keyState;
+        }
+
+        /// <summary>Draw this component.</summary>
+        /// <param name="gameTime">The time elapsed since the last call to Draw.</param>
+        public override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice.BlendState = BlendState.Opaque;
+            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
+
+            int mipLevel2 = (int)Math.Pow(2, mipLevel);
+            var mipSize = rtSize;
+            mipSize.Width /= mipLevel2;
+            mipSize.Height /= mipLevel2;
+
+            GraphicsDevice.SetRenderTarget(rt);
+            GraphicsDevice.Clear(Color.Black);
+
+            spriteBatch.Begin();
+            {
+                var destRect = new Rectangle(0, 0, tx.Width, tx.Height);
+                destRect.X /= mipLevel2;
+                destRect.Y /= mipLevel2;
+                destRect.Width /= mipLevel2;
+                destRect.Height /= mipLevel2;
+                
+                // draw all channels
+                destRect.X = (tx.Width * 0) / mipLevel2;
+                spriteBatch.Draw(tx, destRect, Color.White);
+
+                // draw each channels
+                destRect.X = (tx.Width * 1) / mipLevel2;
+                spriteBatch.Draw(tx, destRect, new Color(1f, 0f, 0f, 0f));
+                destRect.X = (tx.Width * 2) / mipLevel2;
+                spriteBatch.Draw(tx, destRect, new Color(0f, 1f, 0f, 0f));
+                destRect.X = (tx.Width * 3) / mipLevel2;
+                spriteBatch.Draw(tx, destRect, new Color(0f, 0f, 1f, 0f));
+                destRect.X = (tx.Width * 4) / mipLevel2;
+                spriteBatch.Draw(tx, destRect, new Color(0f, 0f, 0f, 1f)); // NOTE: alpha channel is not visible                
+            }
+            spriteBatch.End();
+
+            
+            GraphicsDevice.SetRenderTarget(null);
+            GraphicsDevice.Clear(Color.CornflowerBlue);
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null);
+            spriteBatch.Draw(rt, rtSize, mipSize, Color.White);
+            spriteBatch.End();
+
+
+            spriteBatch.Begin();
+            spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(11, 11), Color.Black);
+            spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(10, 10), Color.White);
+            spriteBatch.End();
+        }
+
+    }
+}

+ 6 - 77
Samples/SLMC/SampleGame.cs

@@ -8,17 +8,9 @@ namespace Samples.SLMC
     public class SampleGame : Game
     {
         GraphicsDeviceManager graphics;
-        SpriteBatch spriteBatch;
-        SpriteFont font;
 
-        KeyboardState previousKeyboardState;
-        
-        int mipLevel = 0;
-        Rectangle rtSize;
-        RenderTarget2D rt;
+        SLMCSampleComponent _slmcSampleComponent;
 
-        Texture2D tx;
-        
         public SampleGame()
         {
             graphics = new GraphicsDeviceManager(this);
@@ -26,21 +18,13 @@ namespace Samples.SLMC
 
             graphics.PreferredBackBufferWidth = 800;
             graphics.PreferredBackBufferHeight = 480;
+
+            _slmcSampleComponent = new SLMCSampleComponent(this, graphics);
+            Components.Add(_slmcSampleComponent);
         }
 
         protected override void LoadContent()
-        {            
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-            font = Content.Load<SpriteFont>("font");
-            
-            tx = Content.Load<Texture2D>("b_c0123");
-
-            rtSize = new Rectangle(0, 0, tx.Width * (1+4), tx.Height);
-            graphics.PreferredBackBufferWidth = (int)rtSize.Width;
-            graphics.PreferredBackBufferHeight = (int)rtSize.Height;
-            graphics.ApplyChanges();
-
-            rt = new RenderTarget2D(GraphicsDevice, rtSize.Width, rtSize.Height);
+        {
         }
         
         /// <param name="gameTime">Provides a snapshot of timing values.</param>
@@ -52,68 +36,13 @@ namespace Samples.SLMC
             if (keyState.IsKeyDown(Keys.Escape) || gamePadState.Buttons.Back == ButtonState.Pressed)
                 Exit();
 
-            if (keyState.IsKeyDown(Keys.OemPlus) && !previousKeyboardState.IsKeyDown(Keys.OemPlus) && mipLevel < tx.LevelCount-1)
-                mipLevel++;
-            if (keyState.IsKeyDown(Keys.Add) && !previousKeyboardState.IsKeyDown(Keys.Add) && mipLevel < tx.LevelCount-1)
-                mipLevel++;
-            if (keyState.IsKeyDown(Keys.OemMinus) && !previousKeyboardState.IsKeyDown(Keys.OemMinus) && mipLevel > 0)
-                mipLevel--;
-            if (keyState.IsKeyDown(Keys.Subtract) && !previousKeyboardState.IsKeyDown(Keys.Subtract) && mipLevel > 0)
-                mipLevel--;
-            
-            previousKeyboardState = keyState;
             base.Update(gameTime);
         }
         
         protected override void Draw(GameTime gameTime)
         {
-            GraphicsDevice.BlendState = BlendState.Opaque;
-            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
-
-            int mipLevel2 = (int)Math.Pow(2, mipLevel);
-            var mipSize = rtSize;
-            mipSize.Width /= mipLevel2;
-            mipSize.Height /= mipLevel2;
-
-            GraphicsDevice.SetRenderTarget(rt);
-            GraphicsDevice.Clear(Color.Black);
-
-            spriteBatch.Begin();
-            {
-                var destRect = new Rectangle(0, 0, tx.Width, tx.Height);
-                destRect.X /= mipLevel2;
-                destRect.Y /= mipLevel2;
-                destRect.Width /= mipLevel2;
-                destRect.Height /= mipLevel2;
-                
-                // draw all channels
-                destRect.X = (tx.Width * 0) / mipLevel2;
-                spriteBatch.Draw(tx, destRect, Color.White);
-
-                // draw each channels                 
-                destRect.X = (tx.Width * 1) / mipLevel2;
-                spriteBatch.Draw(tx, destRect, new Color(1f, 0f, 0f, 0f));
-                destRect.X = (tx.Width * 2) / mipLevel2;
-                spriteBatch.Draw(tx, destRect, new Color(0f, 1f, 0f, 0f));
-                destRect.X = (tx.Width * 3) / mipLevel2;
-                spriteBatch.Draw(tx, destRect, new Color(0f, 0f, 1f, 0f));
-                destRect.X = (tx.Width * 4) / mipLevel2;
-                spriteBatch.Draw(tx, destRect, new Color(0f, 0f, 0f, 1f)); // NOTE: alpha channel is not visible                
-            }
-            spriteBatch.End();
-
-            
             GraphicsDevice.SetRenderTarget(null);
-            GraphicsDevice.Clear(Color.CornflowerBlue);
-            spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null);
-            spriteBatch.Draw(rt, rtSize, mipSize, Color.White);
-            spriteBatch.End();
-
-
-            spriteBatch.Begin();
-            spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(11, 11), Color.Black);
-            spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(10, 10), Color.White);
-            spriteBatch.End();
+            GraphicsDevice.Clear(Color.Black);
 
             base.Draw(gameTime);
         }

+ 1 - 0
Samples/SLMC/Samples.SLMC.DESKTOPGL.NET6.csproj

@@ -24,6 +24,7 @@
     <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="SLMCSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 1 - 0
Samples/SLMC/Samples.SLMC.WINDOWS.NET6.csproj

@@ -25,6 +25,7 @@
     <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="SLMCSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 1 - 0
Samples/SLMC/Samples.SLMC.WINDOWS.csproj

@@ -43,6 +43,7 @@
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="SLMCSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 2 - 1
Samples/SLMC/Samples.SLMC.XNA.csproj

@@ -67,8 +67,9 @@
     <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Program.cs" />
+    <Compile Include="SLMCSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
+    <Compile Include="Program.cs" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs" />

+ 8 - 109
Samples/Tilemap/SampleGame.cs

@@ -1,60 +1,31 @@
 using System;
-using System.IO;
 using Microsoft.Xna.Framework;
 using Microsoft.Xna.Framework.Graphics;
 using Microsoft.Xna.Framework.Input;
-using nkast.Aether.Graphics;
-using nkast.Aether.Shaders;
 
 namespace Samples.Tilemaps
 {
     public class SampleGame : Game
     {
         GraphicsDeviceManager graphics;
-        SpriteBatch spriteBatch;
-        SpriteFont font;
 
-        KeyboardState previousKeyboardState;
-
-        int mipLevel = 4;
-        bool showAtlas = false;
-        bool useGenerateBitmap = true;
-        bool useMipmapPerSprite = true;
-        Rectangle atlasSize = new Rectangle(0, 0, 1024, 512);
-        RenderTarget2D rt;
-
-
-        Tilemap tilemapMipmapPerSprite;
-        Tilemap tilemapMipmap;
-        Tilemap tilemapNoMipmap;
         
+        TilemapSampleComponent _tilemapSampleComponent;
+
         public SampleGame()
         {
             graphics = new GraphicsDeviceManager(this);
             Content.RootDirectory = "Content";
 
-            graphics.PreferredBackBufferWidth = atlasSize.Width;
-            graphics.PreferredBackBufferHeight = atlasSize.Height;
+            graphics.PreferredBackBufferWidth = 800;
+            graphics.PreferredBackBufferHeight = 480;
+
+            _tilemapSampleComponent = new TilemapSampleComponent(this, graphics);
+            Components.Add(_tilemapSampleComponent);
         }
 
         protected override void LoadContent()
         {
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-            font = Content.Load<SpriteFont>("font");
-
-            rt = new RenderTarget2D(GraphicsDevice, atlasSize.Width, atlasSize.Height);
-
-            // Load tilemap
-            tilemapMipmapPerSprite = Content.Load<Tilemap>("tilemapMipmapPerSprite");
-            tilemapMipmap = Content.Load<Tilemap>("tilemapMipmap");
-            tilemapNoMipmap = Content.Load<Tilemap>("tilemapNoMipmap");
-
-#if DEBUG
-            using (var fs = File.Create("tilemapNoMipmapAtlas.png"))
-                tilemapNoMipmap.TextureAtlas.SaveAsPng(fs, tilemapNoMipmap.TextureAtlas.Width, tilemapNoMipmap.TextureAtlas.Height);
-            using (var fs = File.Create("tilemapMipmapAtlas.png"))
-                tilemapNoMipmap.TextureAtlas.SaveAsPng(fs, tilemapMipmap.TextureAtlas.Width, tilemapNoMipmap.TextureAtlas.Height);
-#endif
             
         }
         
@@ -67,87 +38,15 @@ namespace Samples.Tilemaps
             if (keyState.IsKeyDown(Keys.Escape) || gamePadState.Buttons.Back == ButtonState.Pressed)
                 Exit();
 
-            if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
-                useMipmapPerSprite = !useMipmapPerSprite;
-            if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
-                useGenerateBitmap = !useGenerateBitmap;
-            if (keyState.IsKeyDown(Keys.F3) && !previousKeyboardState.IsKeyDown(Keys.F3))
-                showAtlas = !showAtlas;
-            if (keyState.IsKeyDown(Keys.OemPlus) && !previousKeyboardState.IsKeyDown(Keys.OemPlus) && mipLevel < 10)
-                mipLevel++;
-            if (keyState.IsKeyDown(Keys.Add) && !previousKeyboardState.IsKeyDown(Keys.Add) && mipLevel < 10)
-                mipLevel++;
-            if (keyState.IsKeyDown(Keys.OemMinus) && !previousKeyboardState.IsKeyDown(Keys.OemMinus) && mipLevel > 0)
-                mipLevel--;
-            if (keyState.IsKeyDown(Keys.Subtract) && !previousKeyboardState.IsKeyDown(Keys.Subtract) && mipLevel > 0)
-                mipLevel--;
-            
-            previousKeyboardState = keyState;
             base.Update(gameTime);
         }
         
         protected override void Draw(GameTime gameTime)
         {
-            GraphicsDevice.BlendState = BlendState.Opaque;
-            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
-
-            GraphicsDevice.SetRenderTarget(rt);
-            GraphicsDevice.Clear(Color.Black);
-
-            var currentTilemap = (useGenerateBitmap) 
-                ? (useMipmapPerSprite ? tilemapMipmapPerSprite : tilemapMipmap)
-                : (tilemapNoMipmap);
-
-            int mipLevel2 = (int)Math.Pow(2, mipLevel);
-            var mipSize = atlasSize;
-            mipSize.Width /= mipLevel2;
-            mipSize.Height /= mipLevel2;
-            
-
-            if (showAtlas)
-            {
-                spriteBatch.Begin();
-                spriteBatch.Draw(currentTilemap.TextureAtlas, mipSize, Color.White);
-                spriteBatch.End();
-            }
-            else
-            {
-                DrawTilemap(gameTime, currentTilemap, mipSize);
-            }
-
-
             GraphicsDevice.SetRenderTarget(null);
-            GraphicsDevice.Clear(Color.CornflowerBlue);
-            spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null);
-            spriteBatch.Draw(rt, atlasSize, mipSize, Color.White);
-            spriteBatch.End();
-
-            spriteBatch.Begin();
-            spriteBatch.DrawString(font, String.Format("[F1] MipmapPerSprite - ({0})", useMipmapPerSprite ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
-            spriteBatch.DrawString(font, String.Format("[F2] GenerateMipmap - ({0})", useGenerateBitmap ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
-            spriteBatch.DrawString(font, String.Format("[F3] {0}", showAtlas? "Show Tilemap" : "Show Atlas"), new Vector2(20, 60), Color.White);
-            spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(20, 80), Color.White);
-            spriteBatch.End();
+            GraphicsDevice.Clear(Color.Black);
 
             base.Draw(gameTime);
         }
-
-        private void DrawTilemap(GameTime gameTime, Tilemap tilemap, Rectangle mipSize)
-        {
-            // setup tilemapEffect
-            var viewport = GraphicsDevice.Viewport;
-            Matrix projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1);
-            Matrix halfPixelOffset = Matrix.Identity;
-#if XNA
-            halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);
-#endif
-
-            tilemap.Effect.Projection = halfPixelOffset * projection;
-                        
-            // Draw tilemap
-            spriteBatch.Begin(0, BlendState.AlphaBlend, SamplerState.PointWrap, null, null, tilemap.Effect);
-            spriteBatch.Draw(tilemap.TextureMap, mipSize, Color.White);
-            spriteBatch.End();
-        }
     }
 }

+ 1 - 0
Samples/Tilemap/Samples.Tilemaps.DESKTOPGL.NET6.csproj

@@ -24,6 +24,7 @@
     <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="TilemapSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 1 - 0
Samples/Tilemap/Samples.Tilemaps.WINDOWS.NET6.csproj

@@ -25,6 +25,7 @@
     <DefineConstants>TRACE;WINDOWS MG</DefineConstants>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="TilemapSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 1 - 0
Samples/Tilemap/Samples.Tilemaps.WINDOWS.csproj

@@ -43,6 +43,7 @@
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <ItemGroup>
+    <Compile Include="TilemapSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
     <Compile Include="Program.cs" />
   </ItemGroup>

+ 2 - 1
Samples/Tilemap/Samples.Tilemaps.XNA.csproj

@@ -67,8 +67,9 @@
     <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="Program.cs" />
+    <Compile Include="TilemapSampleComponent.cs" />
     <Compile Include="SampleGame.cs" />
+    <Compile Include="Program.cs" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs" />

+ 169 - 0
Samples/Tilemap/TilemapSampleComponent.cs

@@ -0,0 +1,169 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using nkast.Aether.Graphics;
+using nkast.Aether.Shaders;
+
+namespace Samples.Tilemaps
+{
+    internal class TilemapSampleComponent : DrawableGameComponent
+    {
+        GraphicsDeviceManager graphics;
+        ContentManager Content;
+        SpriteBatch spriteBatch;
+        SpriteFont font;
+
+        KeyboardState previousKeyboardState;
+
+        int mipLevel = 4;
+        bool showAtlas = false;
+        bool useGenerateBitmap = true;
+        bool useMipmapPerSprite = true;
+        Rectangle atlasSize = new Rectangle(0, 0, 1024, 512);
+        RenderTarget2D rt;
+
+        Tilemap tilemapMipmapPerSprite;
+        Tilemap tilemapMipmap;
+        Tilemap tilemapNoMipmap;
+
+        public TilemapSampleComponent(Game game, GraphicsDeviceManager graphics) : base(game)
+        {
+            this.graphics = graphics;
+        }
+
+        /// <summary>Initializes the component. Used to load non-graphical resources.</summary>
+        public override void Initialize()
+        {
+            Content = new ContentManager(Game.Services, "Content");
+
+            base.Initialize();
+        }
+
+        /// <summary>Load graphical resources needed by this component.</summary>
+        protected override void LoadContent()
+        {
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            font = Content.Load<SpriteFont>("font");
+
+            rt = new RenderTarget2D(GraphicsDevice, atlasSize.Width, atlasSize.Height);
+
+            // Load tilemap
+            tilemapMipmapPerSprite = Content.Load<Tilemap>("tilemapMipmapPerSprite");
+            tilemapMipmap = Content.Load<Tilemap>("tilemapMipmap");
+            tilemapNoMipmap = Content.Load<Tilemap>("tilemapNoMipmap");
+
+#if DEBUG
+            using (var fs = File.Create("tilemapNoMipmapAtlas.png"))
+                tilemapNoMipmap.TextureAtlas.SaveAsPng(fs, tilemapNoMipmap.TextureAtlas.Width, tilemapNoMipmap.TextureAtlas.Height);
+            using (var fs = File.Create("tilemapMipmapAtlas.png"))
+                tilemapNoMipmap.TextureAtlas.SaveAsPng(fs, tilemapMipmap.TextureAtlas.Width, tilemapNoMipmap.TextureAtlas.Height);
+#endif
+
+            graphics.PreferredBackBufferWidth = atlasSize.Width;
+            graphics.PreferredBackBufferHeight = atlasSize.Height;
+            graphics.ApplyChanges();
+        }
+
+        /// <summary>Unload graphical resources needed by this component.</summary>
+        protected override void UnloadContent()
+        {
+            Content.Unload();
+        }
+
+        /// <summary>Update the component.</summary>
+        /// <param name="gameTime">GameTime of the Game.</param>
+        public override void Update(GameTime gameTime)
+        {
+            KeyboardState keyState = Keyboard.GetState();
+            GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
+
+            if (keyState.IsKeyDown(Keys.F1) && !previousKeyboardState.IsKeyDown(Keys.F1))
+                useMipmapPerSprite = !useMipmapPerSprite;
+            if (keyState.IsKeyDown(Keys.F2) && !previousKeyboardState.IsKeyDown(Keys.F2))
+                useGenerateBitmap = !useGenerateBitmap;
+            if (keyState.IsKeyDown(Keys.F3) && !previousKeyboardState.IsKeyDown(Keys.F3))
+                showAtlas = !showAtlas;
+            if (keyState.IsKeyDown(Keys.OemPlus) && !previousKeyboardState.IsKeyDown(Keys.OemPlus) && mipLevel < 10)
+                mipLevel++;
+            if (keyState.IsKeyDown(Keys.Add) && !previousKeyboardState.IsKeyDown(Keys.Add) && mipLevel < 10)
+                mipLevel++;
+            if (keyState.IsKeyDown(Keys.OemMinus) && !previousKeyboardState.IsKeyDown(Keys.OemMinus) && mipLevel > 0)
+                mipLevel--;
+            if (keyState.IsKeyDown(Keys.Subtract) && !previousKeyboardState.IsKeyDown(Keys.Subtract) && mipLevel > 0)
+                mipLevel--;
+            
+            previousKeyboardState = keyState;
+        }
+
+        private void DrawTilemap(GameTime gameTime, Tilemap tilemap, Rectangle mipSize)
+        {
+            // setup tilemapEffect
+            var viewport = GraphicsDevice.Viewport;
+            Matrix projection = Matrix.CreateOrthographicOffCenter(0, viewport.Width, viewport.Height, 0, 0, 1);
+            Matrix halfPixelOffset = Matrix.Identity;
+#if XNA
+            halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);
+#endif
+
+            tilemap.Effect.Projection = halfPixelOffset * projection;
+                        
+            // Draw tilemap
+            spriteBatch.Begin(0, BlendState.AlphaBlend, SamplerState.PointWrap, null, null, tilemap.Effect);
+            spriteBatch.Draw(tilemap.TextureMap, mipSize, Color.White);
+            spriteBatch.End();
+        }
+
+        /// <summary>Draw this component.</summary>
+        /// <param name="gameTime">The time elapsed since the last call to Draw.</param>
+        public override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice.BlendState = BlendState.Opaque;
+            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
+
+            GraphicsDevice.SetRenderTarget(rt);
+            GraphicsDevice.Clear(Color.Black);
+
+            var currentTilemap = (useGenerateBitmap) 
+                ? (useMipmapPerSprite ? tilemapMipmapPerSprite : tilemapMipmap)
+                : (tilemapNoMipmap);
+
+            int mipLevel2 = (int)Math.Pow(2, mipLevel);
+            var mipSize = atlasSize;
+            mipSize.Width /= mipLevel2;
+            mipSize.Height /= mipLevel2;
+            
+
+            if (showAtlas)
+            {
+                spriteBatch.Begin();
+                spriteBatch.Draw(currentTilemap.TextureAtlas, mipSize, Color.White);
+                spriteBatch.End();
+            }
+            else
+            {
+                DrawTilemap(gameTime, currentTilemap, mipSize);
+            }
+
+
+            GraphicsDevice.SetRenderTarget(null);
+            GraphicsDevice.Clear(Color.CornflowerBlue);
+            spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointWrap, null, null);
+            spriteBatch.Draw(rt, atlasSize, mipSize, Color.White);
+            spriteBatch.End();
+
+            spriteBatch.Begin();
+            spriteBatch.DrawString(font, String.Format("[F1] MipmapPerSprite - ({0})", useMipmapPerSprite ? "ON" : "OFF"), new Vector2(20, 20), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F2] GenerateMipmap - ({0})", useGenerateBitmap ? "ON" : "OFF"), new Vector2(20, 40), Color.White);
+            spriteBatch.DrawString(font, String.Format("[F3] {0}", showAtlas? "Show Tilemap" : "Show Atlas"), new Vector2(20, 60), Color.White);
+            spriteBatch.DrawString(font, String.Format("[+/-] MipLevel - ({0})", mipLevel), new Vector2(20, 80), Color.White);
+            spriteBatch.End();
+
+        }
+        
+    }
+}