瀏覽代碼

ShadowMapping updated to SDKand MG 3.8.*

CartBlanche 4 天之前
父節點
當前提交
c5ca9edb2a
共有 38 個文件被更改,包括 809 次插入597 次删除
  1. 49 0
      ShadowMapping/.vscode/launch.json
  2. 53 0
      ShadowMapping/.vscode/tasks.json
  3. 二進制
      ShadowMapping/Content/dude.xnb
  4. 二進制
      ShadowMapping/Content/grid.xnb
  5. 0 0
      ShadowMapping/Core/Content/DrawModel_0.xnb
  6. 0 0
      ShadowMapping/Core/Content/Grid_0.xnb
  7. 二進制
      ShadowMapping/Core/Content/checker_0.xnb
  8. 二進制
      ShadowMapping/Core/Content/dude.xnb
  9. 二進制
      ShadowMapping/Core/Content/grid.xnb
  10. 0 0
      ShadowMapping/Core/Content/headN_0.xnb
  11. 0 0
      ShadowMapping/Core/Content/headS_0.xnb
  12. 0 0
      ShadowMapping/Core/Content/head_0.xnb
  13. 0 0
      ShadowMapping/Core/Content/jacketN_0.xnb
  14. 0 0
      ShadowMapping/Core/Content/jacketS_0.xnb
  15. 0 0
      ShadowMapping/Core/Content/jacket_0.xnb
  16. 0 0
      ShadowMapping/Core/Content/pantsN_0.xnb
  17. 0 0
      ShadowMapping/Core/Content/pantsS_0.xnb
  18. 0 0
      ShadowMapping/Core/Content/pants_0.xnb
  19. 0 0
      ShadowMapping/Core/Content/upBodyC_0.xnb
  20. 0 0
      ShadowMapping/Core/Content/upBodyS_0.xnb
  21. 0 0
      ShadowMapping/Core/Content/upbodyN_0.xnb
  22. 16 0
      ShadowMapping/Core/ShadowMapping.Core.csproj
  23. 399 414
      ShadowMapping/Core/ShadowMapping.cs
  24. 0 45
      ShadowMapping/Main.cs
  25. 19 0
      ShadowMapping/Platforms/Android/AndroidManifest.xml
  26. 18 0
      ShadowMapping/Platforms/Android/MainActivity.cs
  27. 23 0
      ShadowMapping/Platforms/Android/ShadowMapping.Android.csproj
  28. 15 0
      ShadowMapping/Platforms/Desktop/Program.cs
  29. 23 0
      ShadowMapping/Platforms/Desktop/ShadowMapping.DesktopGL.csproj
  30. 16 0
      ShadowMapping/Platforms/Windows/Program.cs
  31. 25 0
      ShadowMapping/Platforms/Windows/ShadowMapping.Windows.csproj
  32. 11 3
      ShadowMapping/Platforms/iOS/Info.plist
  33. 27 0
      ShadowMapping/Platforms/iOS/Program.cs
  34. 23 0
      ShadowMapping/Platforms/iOS/ShadowMapping.iOS.csproj
  35. 0 25
      ShadowMapping/Properties/AssemblyInfo.cs
  36. 40 0
      ShadowMapping/README.md
  37. 0 110
      ShadowMapping/ShadowMapping.MacOS.csproj
  38. 52 0
      ShadowMapping/ShadowMapping.sln

+ 49 - 0
ShadowMapping/.vscode/launch.json

@@ -0,0 +1,49 @@
+{
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "name": "Launch Windows",
+      "type": "coreclr",
+      "request": "launch",
+      "preLaunchTask": "Build Windows",
+      "program": "${workspaceFolder}/Platforms/Windows/bin/Debug/net8.0-windows/ShadowMapping.Windows.exe",
+      "args": [],
+      "cwd": "${workspaceFolder}",
+      "stopAtEntry": false,
+      "console": "internalConsole"
+    },
+    {
+      "name": "Launch DesktopGL",
+      "type": "coreclr",
+      "request": "launch",
+      "preLaunchTask": "Build DesktopGL",
+      "program": "${workspaceFolder}/Platforms/Desktop/bin/Debug/net8.0/ShadowMapping.DesktopGL.exe",
+      "args": [],
+      "cwd": "${workspaceFolder}",
+      "stopAtEntry": false,
+      "console": "internalConsole"
+    },
+    {
+      "name": "Launch Android",
+      "type": "coreclr",
+      "request": "launch",
+      "preLaunchTask": "Build Android",
+      "program": "${workspaceFolder}/Platforms/Android/bin/Debug/net8.0-android/ShadowMapping.Android.dll",
+      "args": [],
+      "cwd": "${workspaceFolder}",
+      "stopAtEntry": false,
+      "console": "internalConsole"
+    },
+    {
+      "name": "Launch iOS",
+      "type": "coreclr",
+      "request": "launch",
+      "preLaunchTask": "Build iOS",
+      "program": "${workspaceFolder}/Platforms/iOS/bin/Debug/net8.0-ios/ShadowMapping.iOS.dll",
+      "args": [],
+      "cwd": "${workspaceFolder}",
+      "stopAtEntry": false,
+      "console": "internalConsole"
+    }
+  ]
+}

+ 53 - 0
ShadowMapping/.vscode/tasks.json

@@ -0,0 +1,53 @@
+{
+  "version": "2.0.0",
+  "tasks": [
+    {
+      "label": "Build Windows",
+      "type": "shell",
+      "command": "dotnet build Platforms/Windows/ShadowMapping.Windows.csproj",
+      "group": "build"
+    },
+    {
+      "label": "Build DesktopGL",
+      "type": "shell",
+      "command": "dotnet build Platforms/Desktop/ShadowMapping.DesktopGL.csproj",
+      "group": "build"
+    },
+    {
+      "label": "Build Android",
+      "type": "shell",
+      "command": "dotnet build Platforms/Android/ShadowMapping.Android.csproj",
+      "group": "build"
+    },
+    {
+      "label": "Build iOS",
+      "type": "shell",
+      "command": "dotnet build Platforms/iOS/ShadowMapping.iOS.csproj",
+      "group": "build"
+    },
+    {
+      "label": "Run Windows",
+      "type": "shell",
+      "command": "dotnet run --project Platforms/Windows/ShadowMapping.Windows.csproj",
+      "group": "test"
+    },
+    {
+      "label": "Run DesktopGL",
+      "type": "shell",
+      "command": "dotnet run --project Platforms/DesktopGL/ShadowMapping.DesktopGL.csproj",
+      "group": "test"
+    },
+    {
+      "label": "Run Android",
+      "type": "shell",
+      "command": "dotnet run --project Platforms/Android/ShadowMapping.Android.csproj",
+      "group": "test"
+    },
+    {
+      "label": "Run iOS",
+      "type": "shell",
+      "command": "dotnet run --project Platforms/iOS/ShadowMapping.iOS.csproj",
+      "group": "test"
+    }
+  ]
+}

二進制
ShadowMapping/Content/dude.xnb


二進制
ShadowMapping/Content/grid.xnb


+ 0 - 0
ShadowMapping/Content/DrawModel_0.xnb → ShadowMapping/Core/Content/DrawModel_0.xnb


+ 0 - 0
ShadowMapping/Content/Grid_0.xnb → ShadowMapping/Core/Content/Grid_0.xnb


二進制
ShadowMapping/Core/Content/checker_0.xnb


二進制
ShadowMapping/Core/Content/dude.xnb


二進制
ShadowMapping/Core/Content/grid.xnb


+ 0 - 0
ShadowMapping/Content/headN_0.xnb → ShadowMapping/Core/Content/headN_0.xnb


+ 0 - 0
ShadowMapping/Content/headS_0.xnb → ShadowMapping/Core/Content/headS_0.xnb


+ 0 - 0
ShadowMapping/Content/head_0.xnb → ShadowMapping/Core/Content/head_0.xnb


+ 0 - 0
ShadowMapping/Content/jacketN_0.xnb → ShadowMapping/Core/Content/jacketN_0.xnb


+ 0 - 0
ShadowMapping/Content/jacketS_0.xnb → ShadowMapping/Core/Content/jacketS_0.xnb


+ 0 - 0
ShadowMapping/Content/jacket_0.xnb → ShadowMapping/Core/Content/jacket_0.xnb


+ 0 - 0
ShadowMapping/Content/pantsN_0.xnb → ShadowMapping/Core/Content/pantsN_0.xnb


+ 0 - 0
ShadowMapping/Content/pantsS_0.xnb → ShadowMapping/Core/Content/pantsS_0.xnb


+ 0 - 0
ShadowMapping/Content/pants_0.xnb → ShadowMapping/Core/Content/pants_0.xnb


+ 0 - 0
ShadowMapping/Content/upBodyC_0.xnb → ShadowMapping/Core/Content/upBodyC_0.xnb


+ 0 - 0
ShadowMapping/Content/upBodyS_0.xnb → ShadowMapping/Core/Content/upBodyS_0.xnb


+ 0 - 0
ShadowMapping/Content/upbodyN_0.xnb → ShadowMapping/Core/Content/upbodyN_0.xnb


+ 16 - 0
ShadowMapping/Core/ShadowMapping.Core.csproj

@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>ShadowMapping.Core</RootNamespace>
+    <AssemblyName>ShadowMapping.Core</AssemblyName>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="..\..\ReachGraphicsDemo\Core\DataTypes\AnimationClip.cs" Link="DataTypes\AnimationClip.cs" />
+    <Compile Include="..\..\ReachGraphicsDemo\Core\DataTypes\AnimationPlayer.cs" Link="DataTypes\AnimationPlayer.cs" />
+    <Compile Include="..\..\ReachGraphicsDemo\Core\DataTypes\Keyframe.cs" Link="DataTypes\Keyframe.cs" />
+    <Compile Include="..\..\ReachGraphicsDemo\Core\DataTypes\SkinningData.cs" Link="DataTypes\SkinningData.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+</Project>

+ 399 - 414
ShadowMapping/ShadowMapping.cs → ShadowMapping/Core/ShadowMapping.cs

@@ -1,414 +1,399 @@
-#region File Description
-//-----------------------------------------------------------------------------
-// ShadowMapping.cs
-//
-// Microsoft XNA Community Game Platform
-// Copyright (C) Microsoft Corporation. All rights reserved.
-//-----------------------------------------------------------------------------
-#endregion
-
-#region Using Statements
-using System;
-using System.Collections.Generic;
-using Microsoft.Xna.Framework;
-using Microsoft.Xna.Framework.Audio;
-using Microsoft.Xna.Framework.Content;
-using Microsoft.Xna.Framework.GamerServices;
-using Microsoft.Xna.Framework.Graphics;
-using Microsoft.Xna.Framework.Input;
-using Microsoft.Xna.Framework.Net;
-using Microsoft.Xna.Framework.Storage;
-#endregion
-
-namespace ShadowMapping
-{
-    /// <summary>
-    /// Sample showing how to implement a simple shadow mapping technique where
-    /// the shadow map always contains the contents of the viewing frustum
-    /// </summary>
-    public class ShadowMappingGame : Microsoft.Xna.Framework.Game
-    {
-        #region Constants
-
-        // The size of the shadow map
-        // The larger the size the more detail we will have for our entire scene
-        const int shadowMapWidthHeight = 2048;
-
-        const int windowWidth = 800;
-        const int windowHeight = 480;
-
-        #endregion
-
-        #region Fields
-
-        GraphicsDeviceManager graphics;
-        SpriteBatch spriteBatch;
-
-        // Starting position and direction of our camera
-        Vector3 cameraPosition = new Vector3(0, 70, 100);
-        Vector3 cameraForward = new Vector3(0, -0.4472136f, -0.8944272f);
-        BoundingFrustum cameraFrustum = new BoundingFrustum(Matrix.Identity);
-
-        // Light direction
-        Vector3 lightDir = new Vector3(-0.3333333f, 0.6666667f, 0.6666667f);
-
-        KeyboardState currentKeyboardState;
-        GamePadState currentGamePadState;
-
-        // Our two models in the scene
-        Model gridModel;
-        Model dudeModel;
-
-        float rotateDude = 0.0f;
-
-        // The shadow map render target
-        RenderTarget2D shadowRenderTarget;
-
-        // Transform matrices
-        Matrix world;
-        Matrix view;
-        Matrix projection;
-
-        // ViewProjection matrix from the lights perspective
-        Matrix lightViewProjection;
-
-        #endregion
-
-        #region Initialization
-
-        public ShadowMappingGame()
-        {
-            graphics = new GraphicsDeviceManager(this);
-
-            Content.RootDirectory = "Content";
-
-            graphics.PreferredBackBufferWidth = windowWidth;
-            graphics.PreferredBackBufferHeight = windowHeight;
-
-            float aspectRatio = (float)windowWidth / (float)windowHeight;
-  
-            projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 
-                                                             aspectRatio, 
-                                                             1.0f, 1000.0f);
-        }
-
-
-        /// <summary>
-        /// LoadContent will be called once per game and is the place to load
-        /// all of your content.
-        /// </summary>
-        protected override void LoadContent()
-        {
-            spriteBatch = new SpriteBatch(GraphicsDevice);
-
-            // Load the two models we will be using in the sample
-            gridModel = Content.Load<Model>("grid");
-            dudeModel = Content.Load<Model>("dude");
-
-            // Create floating point render target
-            shadowRenderTarget = new RenderTarget2D(graphics.GraphicsDevice,
-                                                    shadowMapWidthHeight,
-                                                    shadowMapWidthHeight,
-                                                    false,
-                                                    SurfaceFormat.Single,
-                                                    DepthFormat.Depth24);
-        }
-
-        #endregion
-
-        #region Update and Draw
-
-        /// <summary>
-        /// Allows the game to run logic such as updating the world,
-        /// checking for collisions, gathering input, and playing audio.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        protected override void Update(GameTime gameTime)
-        {
-            HandleInput(gameTime);
-
-            UpdateCamera(gameTime);
-
-            base.Update(gameTime);
-        }
-
-        /// <summary>
-        /// This is called when the game should draw itself.
-        /// </summary>
-        /// <param name="gameTime">Provides a snapshot of timing values.</param>
-        protected override void Draw(GameTime gameTime)
-        {
-            // Update the lights ViewProjection matrix based on the 
-            // current camera frustum
-            lightViewProjection = CreateLightViewProjectionMatrix();
-
-            GraphicsDevice.BlendState = BlendState.Opaque;
-            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
-
-            // Render the scene to the shadow map
-            CreateShadowMap();
-
-            // Draw the scene using the shadow map
-            DrawWithShadowMap();
-
-            // Display the shadow map to the screen
-            DrawShadowMapToScreen();
-
-            base.Draw(gameTime);
-        }
-
-        #endregion
-
-        #region Methods
-
-        /// <summary>
-        /// Creates the WorldViewProjection matrix from the perspective of the 
-        /// light using the cameras bounding frustum to determine what is visible 
-        /// in the scene.
-        /// </summary>
-        /// <returns>The WorldViewProjection for the light</returns>
-        Matrix CreateLightViewProjectionMatrix()
-        {
-            // Matrix with that will rotate in points the direction of the light
-            Matrix lightRotation = Matrix.CreateLookAt(Vector3.Zero, 
-                                                       -lightDir, 
-                                                       Vector3.Up);
-
-            // Get the corners of the frustum
-            Vector3[] frustumCorners = cameraFrustum.GetCorners();
-
-            // Transform the positions of the corners into the direction of the light
-            for (int i = 0; i < frustumCorners.Length; i++)
-            {
-                frustumCorners[i] = Vector3.Transform(frustumCorners[i], lightRotation);
-            }
-
-            // Find the smallest box around the points
-            BoundingBox lightBox = BoundingBox.CreateFromPoints(frustumCorners);
-
-            Vector3 boxSize = lightBox.Max - lightBox.Min;
-            Vector3 halfBoxSize = boxSize * 0.5f;
-
-            // The position of the light should be in the center of the back
-            // pannel of the box. 
-            Vector3 lightPosition = lightBox.Min + halfBoxSize;
-            lightPosition.Z = lightBox.Min.Z;
-
-            // We need the position back in world coordinates so we transform 
-            // the light position by the inverse of the lights rotation
-            lightPosition = Vector3.Transform(lightPosition, 
-                                              Matrix.Invert(lightRotation));
-
-            // Create the view matrix for the light
-            Matrix lightView = Matrix.CreateLookAt(lightPosition, 
-                                                   lightPosition - lightDir, 
-                                                   Vector3.Up);
-
-            // Create the projection matrix for the light
-            // The projection is orthographic since we are using a directional light
-            Matrix lightProjection = Matrix.CreateOrthographic(boxSize.X, boxSize.Y, 
-                                                               -boxSize.Z, boxSize.Z);
-
-            return lightView * lightProjection;
-        }
-
-        /// <summary>
-        /// Renders the scene to the floating point render target then 
-        /// sets the texture for use when drawing the scene.
-        /// </summary>
-        void CreateShadowMap()
-        {
-            // Set our render target to our floating point render target
-            GraphicsDevice.SetRenderTarget(shadowRenderTarget);
-
-            // Clear the render target to white or all 1's
-            // We set the clear to white since that represents the 
-            // furthest the object could be away
-            GraphicsDevice.Clear(Color.White);
-
-            // Draw any occluders in our case that is just the dude model
-
-            // Set the models world matrix so it will rotate
-            world = Matrix.CreateRotationY(MathHelper.ToRadians(rotateDude));
-            // Draw the dude model
-            DrawModel(dudeModel, true);
-
-            // Set render target back to the back buffer
-            GraphicsDevice.SetRenderTarget(null);
-        }
-
-        /// <summary>
-        /// Renders the scene using the shadow map to darken the shadow areas
-        /// </summary>
-        void DrawWithShadowMap()
-        {
-            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
-
-            GraphicsDevice.SamplerStates[1] = SamplerState.PointClamp;
-
-            // Draw the grid
-            world = Matrix.Identity;
-            DrawModel(gridModel, false);
-
-            // Draw the dude model
-            world = Matrix.CreateRotationY(MathHelper.ToRadians(rotateDude));
-            DrawModel(dudeModel, false);
-        }
-
-        /// <summary>
-        /// Helper function to draw a model
-        /// </summary>
-        /// <param name="model">The model to draw</param>
-        /// <param name="technique">The technique to use</param>
-        void DrawModel(Model model, bool createShadowMap)
-        {
-            string techniqueName = createShadowMap ? "CreateShadowMap" : "DrawWithShadowMap";
-
-            Matrix[] transforms = new Matrix[model.Bones.Count];
-            model.CopyAbsoluteBoneTransformsTo(transforms);
-
-            // Loop over meshs in the model
-            foreach (ModelMesh mesh in model.Meshes)
-            {
-                // Loop over effects in the mesh
-                foreach (Effect effect in mesh.Effects)
-                {
-                    // Set the currest values for the effect
-                    effect.CurrentTechnique = effect.Techniques[techniqueName];
-                    effect.Parameters["World"].SetValue(world);
-                    effect.Parameters["View"].SetValue(view);
-                    effect.Parameters["Projection"].SetValue(projection);
-                    effect.Parameters["LightDirection"].SetValue(lightDir);
-                    effect.Parameters["LightViewProj"].SetValue(lightViewProjection);
-
-                    if (!createShadowMap)
-                        effect.Parameters["ShadowMap"].SetValue(shadowRenderTarget);
-                }
-                // Draw the mesh
-                mesh.Draw();
-            }
-        }
-
-        /// <summary>
-        /// Render the shadow map texture to the screen
-        /// </summary>
-        void DrawShadowMapToScreen()
-        {
-            spriteBatch.Begin(0, BlendState.Opaque, SamplerState.PointClamp, null, null);
-            spriteBatch.Draw(shadowRenderTarget, new Rectangle(0, 0, 128, 128), Color.White);
-            spriteBatch.End();
-
-            GraphicsDevice.Textures[0] = null;
-            GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
-        }
-
-        #endregion
-
-        #region Handle Input
-
-        /// <summary>
-        /// Handles input for quitting the game.
-        /// </summary>
-        void HandleInput(GameTime gameTime)
-        {
-            float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
-
-            currentKeyboardState = Keyboard.GetState();
-            currentGamePadState = GamePad.GetState(PlayerIndex.One);
-
-            // Rotate the dude model
-            rotateDude += currentGamePadState.Triggers.Right * time * 0.2f;
-            rotateDude -= currentGamePadState.Triggers.Left * time * 0.2f;
-            
-            if (currentKeyboardState.IsKeyDown(Keys.Q))
-                rotateDude -= time * 0.2f;
-            if (currentKeyboardState.IsKeyDown(Keys.E))
-                rotateDude += time * 0.2f;
-
-            // Check for exit.
-            if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
-                currentGamePadState.Buttons.Back == ButtonState.Pressed)
-            {
-                Exit();
-            }
-        }
-
-
-        /// <summary>
-        /// Handles input for moving the camera.
-        /// </summary>
-        void UpdateCamera(GameTime gameTime)
-        {
-            float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
-
-            // Check for input to rotate the camera.
-            float pitch = -currentGamePadState.ThumbSticks.Right.Y * time * 0.001f;
-            float turn = -currentGamePadState.ThumbSticks.Right.X * time * 0.001f;
-
-            if (currentKeyboardState.IsKeyDown(Keys.Up))
-                pitch += time * 0.001f;
-
-            if (currentKeyboardState.IsKeyDown(Keys.Down))
-                pitch -= time * 0.001f;
-
-            if (currentKeyboardState.IsKeyDown(Keys.Left))
-                turn += time * 0.001f;
-
-            if (currentKeyboardState.IsKeyDown(Keys.Right))
-                turn -= time * 0.001f;
-
-            Vector3 cameraRight = Vector3.Cross(Vector3.Up, cameraForward);
-            Vector3 flatFront = Vector3.Cross(cameraRight, Vector3.Up);
-
-            Matrix pitchMatrix = Matrix.CreateFromAxisAngle(cameraRight, pitch);
-            Matrix turnMatrix = Matrix.CreateFromAxisAngle(Vector3.Up, turn);
-
-            Vector3 tiltedFront = Vector3.TransformNormal(cameraForward, pitchMatrix *
-                                                          turnMatrix);
-
-            // Check angle so we cant flip over
-            if (Vector3.Dot(tiltedFront, flatFront) > 0.001f)
-            {
-                cameraForward = Vector3.Normalize(tiltedFront);
-            }
-
-            // Check for input to move the camera around.
-            if (currentKeyboardState.IsKeyDown(Keys.W))
-                cameraPosition += cameraForward * time * 0.1f;
-
-            if (currentKeyboardState.IsKeyDown(Keys.S))
-                cameraPosition -= cameraForward * time * 0.1f;
-
-            if (currentKeyboardState.IsKeyDown(Keys.A))
-                cameraPosition += cameraRight * time * 0.1f;
-
-            if (currentKeyboardState.IsKeyDown(Keys.D))
-                cameraPosition -= cameraRight * time * 0.1f;
-
-            cameraPosition += cameraForward *
-                              currentGamePadState.ThumbSticks.Left.Y * time * 0.1f;
-
-            cameraPosition -= cameraRight *
-                              currentGamePadState.ThumbSticks.Left.X * time * 0.1f;
-
-            if (currentGamePadState.Buttons.RightStick == ButtonState.Pressed ||
-                currentKeyboardState.IsKeyDown(Keys.R))
-            {
-                cameraPosition = new Vector3(0, 50, 50);
-                cameraForward = new Vector3(0, 0, -1);
-            }
-
-            cameraForward.Normalize();
-
-            // Create the new view matrix
-            view = Matrix.CreateLookAt(cameraPosition, 
-                                       cameraPosition + cameraForward, 
-                                       Vector3.Up);
-
-            // Set the new frustum value
-            cameraFrustum.Matrix = view * projection;
-        }
-
-        #endregion
-    }
-}
+//-----------------------------------------------------------------------------
+// ShadowMapping.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using System;
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+using Microsoft.Xna.Framework.Content;
+// using Microsoft.Xna.Framework.GamerServices;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+// using Microsoft.Xna.Framework.Net;
+// using Microsoft.Xna.Framework.Storage;
+using SkinnedModel;
+
+namespace ShadowMapping
+{
+    /// <summary>
+    /// Sample showing how to implement a simple shadow mapping technique where
+    /// the shadow map always contains the contents of the viewing frustum
+    /// </summary>
+    public class ShadowMappingGame : Game
+    {
+
+        // The size of the shadow map
+        // The larger the size the more detail we will have for our entire scene
+        const int shadowMapWidthHeight = 2048;
+
+        const int windowWidth = 800;
+        const int windowHeight = 480;
+
+
+
+        GraphicsDeviceManager graphics;
+        SpriteBatch? spriteBatch;
+
+        // Starting position and direction of our camera
+        Vector3 cameraPosition = new Vector3(0, 70, 100);
+        Vector3 cameraForward = new Vector3(0, -0.4472136f, -0.8944272f);
+        BoundingFrustum cameraFrustum = new BoundingFrustum(Matrix.Identity);
+
+        // Light direction
+        Vector3 lightDir = new Vector3(-0.3333333f, 0.6666667f, 0.6666667f);
+
+        KeyboardState currentKeyboardState;
+        GamePadState currentGamePadState;
+
+        // Our two models in the scene
+        Model? gridModel;
+        Model? dudeModel;
+
+        float rotateDude = 0.0f;
+
+        // The shadow map render target
+        RenderTarget2D? shadowRenderTarget;
+
+        // Transform matrices
+        Matrix world;
+        Matrix view;
+        Matrix projection;
+
+        // ViewProjection matrix from the lights perspective
+        Matrix lightViewProjection;
+
+
+
+        public ShadowMappingGame()
+        {
+            graphics = new GraphicsDeviceManager(this);
+
+            Content.RootDirectory = "Content";
+
+            graphics.PreferredBackBufferWidth = windowWidth;
+            graphics.PreferredBackBufferHeight = windowHeight;
+
+            float aspectRatio = (float)windowWidth / (float)windowHeight;
+
+            projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
+                                                             aspectRatio,
+                                                             1.0f, 1000.0f);
+        }
+
+
+        /// <summary>
+        /// LoadContent will be called once per game and is the place to load
+        /// all of your content.
+        /// </summary>
+        protected override void LoadContent()
+        {
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+
+            // Load the two models we will be using in the sample
+            gridModel = Content.Load<Model>("grid");
+            dudeModel = Content.Load<Model>("dude");
+
+            // Create floating point render target
+            shadowRenderTarget = new RenderTarget2D(graphics.GraphicsDevice,
+                                                    shadowMapWidthHeight,
+                                                    shadowMapWidthHeight,
+                                                    false,
+                                                    SurfaceFormat.Single,
+                                                    DepthFormat.Depth24);
+        }
+
+
+
+        /// <summary>
+        /// Allows the game to run logic such as updating the world,
+        /// checking for collisions, gathering input, and playing audio.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Update(GameTime gameTime)
+        {
+            HandleInput(gameTime);
+
+            UpdateCamera(gameTime);
+
+            base.Update(gameTime);
+        }
+
+        /// <summary>
+        /// This is called when the game should draw itself.
+        /// </summary>
+        /// <param name="gameTime">Provides a snapshot of timing values.</param>
+        protected override void Draw(GameTime gameTime)
+        {
+            // Update the lights ViewProjection matrix based on the 
+            // current camera frustum
+            lightViewProjection = CreateLightViewProjectionMatrix();
+
+            GraphicsDevice.BlendState = BlendState.Opaque;
+            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
+
+            // Render the scene to the shadow map
+            CreateShadowMap();
+
+            // Draw the scene using the shadow map
+            DrawWithShadowMap();
+
+            // Display the shadow map to the screen
+            DrawShadowMapToScreen();
+
+            base.Draw(gameTime);
+        }
+
+
+
+        /// <summary>
+        /// Creates the WorldViewProjection matrix from the perspective of the 
+        /// light using the cameras bounding frustum to determine what is visible 
+        /// in the scene.
+        /// </summary>
+        /// <returns>The WorldViewProjection for the light</returns>
+        Matrix CreateLightViewProjectionMatrix()
+        {
+            // Matrix with that will rotate in points the direction of the light
+            Matrix lightRotation = Matrix.CreateLookAt(Vector3.Zero,
+                                                       -lightDir,
+                                                       Vector3.Up);
+
+            // Get the corners of the frustum
+            Vector3[] frustumCorners = cameraFrustum.GetCorners();
+
+            // Transform the positions of the corners into the direction of the light
+            for (int i = 0; i < frustumCorners.Length; i++)
+            {
+                frustumCorners[i] = Vector3.Transform(frustumCorners[i], lightRotation);
+            }
+
+            // Find the smallest box around the points
+            BoundingBox lightBox = BoundingBox.CreateFromPoints(frustumCorners);
+
+            Vector3 boxSize = lightBox.Max - lightBox.Min;
+            Vector3 halfBoxSize = boxSize * 0.5f;
+
+            // The position of the light should be in the center of the back
+            // pannel of the box. 
+            Vector3 lightPosition = lightBox.Min + halfBoxSize;
+            lightPosition.Z = lightBox.Min.Z;
+
+            // We need the position back in world coordinates so we transform 
+            // the light position by the inverse of the lights rotation
+            lightPosition = Vector3.Transform(lightPosition,
+                                              Matrix.Invert(lightRotation));
+
+            // Create the view matrix for the light
+            Matrix lightView = Matrix.CreateLookAt(lightPosition,
+                                                   lightPosition - lightDir,
+                                                   Vector3.Up);
+
+            // Create the projection matrix for the light
+            // The projection is orthographic since we are using a directional light
+            Matrix lightProjection = Matrix.CreateOrthographic(boxSize.X, boxSize.Y,
+                                                               -boxSize.Z, boxSize.Z);
+
+            return lightView * lightProjection;
+        }
+
+        /// <summary>
+        /// Renders the scene to the floating point render target then 
+        /// sets the texture for use when drawing the scene.
+        /// </summary>
+        void CreateShadowMap()
+        {
+            // Set our render target to our floating point render target
+            GraphicsDevice.SetRenderTarget(shadowRenderTarget);
+
+            // Clear the render target to white or all 1's
+            // We set the clear to white since that represents the 
+            // furthest the object could be away
+            GraphicsDevice.Clear(Color.White);
+
+            // Draw any occluders in our case that is just the dude model
+
+            // Set the models world matrix so it will rotate
+            world = Matrix.CreateRotationY(MathHelper.ToRadians(rotateDude));
+            // Draw the dude model
+            DrawModel(dudeModel!, true);
+
+            // Set render target back to the back buffer
+            GraphicsDevice.SetRenderTarget(null);
+        }
+
+        /// <summary>
+        /// Renders the scene using the shadow map to darken the shadow areas
+        /// </summary>
+        void DrawWithShadowMap()
+        {
+            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
+
+            GraphicsDevice.SamplerStates[1] = SamplerState.PointClamp;
+
+            // Draw the grid
+            world = Matrix.Identity;
+            DrawModel(gridModel!, false);
+
+            // Draw the dude model
+            world = Matrix.CreateRotationY(MathHelper.ToRadians(rotateDude));
+            DrawModel(dudeModel!, false);
+        }
+
+        /// <summary>
+        /// Helper function to draw a model
+        /// </summary>
+        /// <param name="model">The model to draw</param>
+        /// <param name="technique">The technique to use</param>
+        void DrawModel(Model model, bool createShadowMap)
+        {
+            string techniqueName = createShadowMap ? "CreateShadowMap" : "DrawWithShadowMap";
+
+            Matrix[] transforms = new Matrix[model.Bones.Count];
+            model.CopyAbsoluteBoneTransformsTo(transforms);
+
+            // Loop over meshs in the model
+            foreach (ModelMesh mesh in model.Meshes)
+            {
+                // Loop over effects in the mesh
+                foreach (Effect effect in mesh.Effects)
+                {
+                    // Set the currest values for the effect
+                    effect.CurrentTechnique = effect.Techniques[techniqueName];
+                    effect.Parameters["World"].SetValue(world);
+                    effect.Parameters["View"].SetValue(view);
+                    effect.Parameters["Projection"].SetValue(projection);
+                    effect.Parameters["LightDirection"].SetValue(lightDir);
+                    effect.Parameters["LightViewProj"].SetValue(lightViewProjection);
+
+                    if (!createShadowMap)
+                        effect.Parameters["ShadowMap"].SetValue(shadowRenderTarget);
+                }
+                // Draw the mesh
+                mesh.Draw();
+            }
+        }
+
+        /// <summary>
+        /// Render the shadow map texture to the screen
+        /// </summary>
+        void DrawShadowMapToScreen()
+        {
+            spriteBatch!.Begin(0, BlendState.Opaque, SamplerState.PointClamp, null, null);
+            spriteBatch!.Draw(shadowRenderTarget!, new Rectangle(0, 0, 128, 128), Color.White);
+            spriteBatch.End();
+
+            GraphicsDevice.Textures[0] = null;
+            GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
+        }
+
+
+
+        /// <summary>
+        /// Handles input for quitting the game.
+        /// </summary>
+        void HandleInput(GameTime gameTime)
+        {
+            float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
+
+            currentKeyboardState = Keyboard.GetState();
+            currentGamePadState = GamePad.GetState(PlayerIndex.One);
+
+            // Rotate the dude model
+            rotateDude += currentGamePadState.Triggers.Right * time * 0.2f;
+            rotateDude -= currentGamePadState.Triggers.Left * time * 0.2f;
+
+            if (currentKeyboardState.IsKeyDown(Keys.Q))
+                rotateDude -= time * 0.2f;
+            if (currentKeyboardState.IsKeyDown(Keys.E))
+                rotateDude += time * 0.2f;
+
+            // Check for exit.
+            if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
+                currentGamePadState.Buttons.Back == ButtonState.Pressed)
+            {
+                Exit();
+            }
+        }
+
+
+        /// <summary>
+        /// Handles input for moving the camera.
+        /// </summary>
+        void UpdateCamera(GameTime gameTime)
+        {
+            float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
+
+            // Check for input to rotate the camera.
+            float pitch = -currentGamePadState.ThumbSticks.Right.Y * time * 0.001f;
+            float turn = -currentGamePadState.ThumbSticks.Right.X * time * 0.001f;
+
+            if (currentKeyboardState.IsKeyDown(Keys.Up))
+                pitch += time * 0.001f;
+
+            if (currentKeyboardState.IsKeyDown(Keys.Down))
+                pitch -= time * 0.001f;
+
+            if (currentKeyboardState.IsKeyDown(Keys.Left))
+                turn += time * 0.001f;
+
+            if (currentKeyboardState.IsKeyDown(Keys.Right))
+                turn -= time * 0.001f;
+
+            Vector3 cameraRight = Vector3.Cross(Vector3.Up, cameraForward);
+            Vector3 flatFront = Vector3.Cross(cameraRight, Vector3.Up);
+
+            Matrix pitchMatrix = Matrix.CreateFromAxisAngle(cameraRight, pitch);
+            Matrix turnMatrix = Matrix.CreateFromAxisAngle(Vector3.Up, turn);
+
+            Vector3 tiltedFront = Vector3.TransformNormal(cameraForward, pitchMatrix *
+                                                          turnMatrix);
+
+            // Check angle so we cant flip over
+            if (Vector3.Dot(tiltedFront, flatFront) > 0.001f)
+            {
+                cameraForward = Vector3.Normalize(tiltedFront);
+            }
+
+            // Check for input to move the camera around.
+            if (currentKeyboardState.IsKeyDown(Keys.W))
+                cameraPosition += cameraForward * time * 0.1f;
+
+            if (currentKeyboardState.IsKeyDown(Keys.S))
+                cameraPosition -= cameraForward * time * 0.1f;
+
+            if (currentKeyboardState.IsKeyDown(Keys.A))
+                cameraPosition += cameraRight * time * 0.1f;
+
+            if (currentKeyboardState.IsKeyDown(Keys.D))
+                cameraPosition -= cameraRight * time * 0.1f;
+
+            cameraPosition += cameraForward *
+                              currentGamePadState.ThumbSticks.Left.Y * time * 0.1f;
+
+            cameraPosition -= cameraRight *
+                              currentGamePadState.ThumbSticks.Left.X * time * 0.1f;
+
+            if (currentGamePadState.Buttons.RightStick == ButtonState.Pressed ||
+                currentKeyboardState.IsKeyDown(Keys.R))
+            {
+                cameraPosition = new Vector3(0, 50, 50);
+                cameraForward = new Vector3(0, 0, -1);
+            }
+
+            cameraForward.Normalize();
+
+            // Create the new view matrix
+            view = Matrix.CreateLookAt(cameraPosition,
+                                       cameraPosition + cameraForward,
+                                       Vector3.Up);
+
+            // Set the new frustum value
+            cameraFrustum.Matrix = view * projection;
+        }
+
+    }
+}

+ 0 - 45
ShadowMapping/Main.cs

@@ -1,45 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-
-using MonoMac.AppKit;
-using MonoMac.Foundation;
-
-namespace ShadowMapping
-{
-	static class Program
-	{
-		/// <summary>
-		/// The main entry point for the application.
-		/// </summary>
-		static void Main (string[] args)
-		{
-			NSApplication.Init ();
-			
-			using (var p = new NSAutoreleasePool ()) {
-				NSApplication.SharedApplication.Delegate = new AppDelegate ();
-				NSApplication.Main (args);
-			}
-
-
-		}
-	}
-
-	class AppDelegate : NSApplicationDelegate
-	{
-		ShadowMappingGame game;
-
-		public override void FinishedLaunching (MonoMac.Foundation.NSObject notification)
-		{
-			game = new ShadowMappingGame ();
-			game.Run ();
-		}
-		
-		public override bool ApplicationShouldTerminateAfterLastWindowClosed (NSApplication sender)
-		{
-			return true;
-		}
-	}  
-}
-
-

+ 19 - 0
ShadowMapping/Platforms/Android/AndroidManifest.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.yourcompany.ShadowMapping"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <application android:label="ShadowMapping" android:icon="@mipmap/icon">
+        <activity android:name="android.app.NativeActivity"
+                  android:label="ShadowMapping"
+                  android:configChanges="orientation|keyboardHidden|screenSize"
+                  android:screenOrientation="landscape">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
+    <uses-feature android:glEsVersion="0x00020000" android:required="true" />
+</manifest>

+ 18 - 0
ShadowMapping/Platforms/Android/MainActivity.cs

@@ -0,0 +1,18 @@
+using Android.App;
+using Android.OS;
+using Microsoft.Xna.Framework;
+
+namespace ShadowMapping.Android
+{
+    [Activity(Label = "ShadowMapping", MainLauncher = true, Icon = "@mipmap/icon", Theme = "@style/MainTheme", ConfigurationChanges = Android.Content.PM.ConfigChanges.ScreenSize | Android.Content.PM.ConfigChanges.Orientation)]
+    public class MainActivity : AndroidGameActivity
+    {
+        protected override void OnCreate(Bundle bundle)
+        {
+            base.OnCreate(bundle);
+            var game = new ShadowMappingGame();
+            SetContentView((View)game.Services.GetService(typeof(View)));
+            game.Run();
+        }
+    }
+}

+ 23 - 0
ShadowMapping/Platforms/Android/ShadowMapping.Android.csproj

@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0-android</TargetFramework>
+    <RootNamespace>ShadowMapping</RootNamespace>
+    <AssemblyTitle>Shadow Mapping</AssemblyTitle>
+    <Product>Shadow Mapping</Product>
+    <Description>This sample shows you how to implement basic shadow mapping from a directional light</Description>
+    <Company>Microsoft</Company>
+    <Copyright>Copyright © Microsoft 2008</Copyright>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.*" />
+    <ProjectReference Include="..\..\Core\ShadowMapping.Core.csproj" />
+  </ItemGroup>
+  
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 15 - 0
ShadowMapping/Platforms/Desktop/Program.cs

@@ -0,0 +1,15 @@
+using System;
+using Microsoft.Xna.Framework;
+
+namespace ShadowMapping.Desktop
+{
+    public static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            using (var game = new ShadowMappingGame())
+                game.Run();
+        }
+    }
+}

+ 23 - 0
ShadowMapping/Platforms/Desktop/ShadowMapping.DesktopGL.csproj

@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>ShadowMapping</RootNamespace>
+    <AssemblyTitle>Shadow Mapping</AssemblyTitle>
+    <Product>Shadow Mapping</Product>
+    <Description>This sample shows you how to implement basic shadow mapping from a directional light</Description>
+    <Company>Microsoft</Company>
+    <Copyright>Copyright © Microsoft 2008</Copyright>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+    <ProjectReference Include="..\..\Core\ShadowMapping.Core.csproj" />
+  </ItemGroup>
+  
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 16 - 0
ShadowMapping/Platforms/Windows/Program.cs

@@ -0,0 +1,16 @@
+using System;
+using Microsoft.Xna.Framework;
+using System.Windows.Forms;
+
+namespace ShadowMapping.Windows
+{
+    public static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            using (var game = new ShadowMappingGame())
+                game.Run();
+        }
+    }
+}

+ 25 - 0
ShadowMapping/Platforms/Windows/ShadowMapping.Windows.csproj

@@ -0,0 +1,25 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>net8.0-windows</TargetFramework>
+    <RootNamespace>ShadowMapping</RootNamespace>
+    <AssemblyTitle>Shadow Mapping</AssemblyTitle>
+    <Product>Shadow Mapping</Product>
+    <Description>This sample shows you how to implement basic shadow mapping from a directional light</Description>
+    <Company>Microsoft</Company>
+    <Copyright>Copyright © Microsoft 2008</Copyright>
+    <UseWindowsForms>false</UseWindowsForms>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+  
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.WindowsDX" Version="3.8.*" />
+    <ProjectReference Include="..\..\Core\ShadowMapping.Core.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 11 - 3
ShadowMapping/Info.plist → ShadowMapping/Platforms/iOS/Info.plist

@@ -9,8 +9,16 @@
 	<key>CFBundleVersion</key>
 	<string>1</string>
 	<key>LSMinimumSystemVersion</key>
-	<string>10.6</string>
-	<key>NSPrincipalClass</key>
-	<string>NSApplication</string>
+	<string>12.0</string>
+	<key>UIDeviceFamily</key>
+	<array>
+		<string>1</string>
+		<string>2</string>
+	</array>
+	<key>UISupportedInterfaceOrientations</key>
+	<array>
+		<string>UIInterfaceOrientationLandscapeLeft</string>
+		<string>UIInterfaceOrientationLandscapeRight</string>
+	</array>
 </dict>
 </plist>

+ 27 - 0
ShadowMapping/Platforms/iOS/Program.cs

@@ -0,0 +1,27 @@
+using System;
+using Microsoft.Xna.Framework;
+using UIKit;
+
+namespace ShadowMapping.iOS
+{
+    public class Application
+    {
+        // This is the main entry point of the application.
+        static void Main(string[] args)
+        {
+            UIApplication.Main(args, null, typeof(AppDelegate));
+        }
+    }
+
+    public class AppDelegate : UIApplicationDelegate
+    {
+        private ShadowMappingGame _game;
+
+        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
+        {
+            _game = new ShadowMappingGame();
+            _game.Run();
+            return true;
+        }
+    }
+}

+ 23 - 0
ShadowMapping/Platforms/iOS/ShadowMapping.iOS.csproj

@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0-ios</TargetFramework>
+    <RootNamespace>ShadowMapping</RootNamespace>
+    <AssemblyTitle>Shadow Mapping</AssemblyTitle>
+    <Product>Shadow Mapping</Product>
+    <Description>This sample shows you how to implement basic shadow mapping from a directional light</Description>
+    <Company>Microsoft</Company>
+    <Copyright>Copyright © Microsoft 2008</Copyright>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.iOS" Version="3.8.*" />
+    <ProjectReference Include="..\..\Core\ShadowMapping.Core.csproj" />
+  </ItemGroup>
+  
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 0 - 25
ShadowMapping/Properties/AssemblyInfo.cs

@@ -1,25 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Shadow Mapping")]
-[assembly: AssemblyProduct("Shadow Mapping")]
-[assembly: AssemblyDescription("This sample shows you how to implement basic shadow mapping from a directional light")]
-[assembly: AssemblyCompany("Microsoft")]
-
-[assembly: AssemblyCopyright("Copyright © Microsoft 2008")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyVersion("1.0.0.0")]

+ 40 - 0
ShadowMapping/README.md

@@ -0,0 +1,40 @@
+# ShadowMapping MonoGame Sample
+
+This project demonstrates basic shadow mapping from a directional light using MonoGame 3.8.* and .NET 8.0. The solution is organized for modern cross-platform development, with each platform using its own SDK-style .csproj file.
+
+## Project Structure
+- **Platforms/Windows/ShadowMapping.Windows.csproj**: Windows-specific project (DirectX, `net8.0-windows`)
+- **Platforms/DesktopGL/ShadowMapping.DesktopGL.csproj**: Cross-platform OpenGL project (`net8.0`)
+- **Platforms/Android/ShadowMapping.Android.csproj**: Android project (`net8.0-android`)
+- **Platforms/iOS/ShadowMapping.iOS.csproj**: iOS project (`net8.0-ios`)
+- **Core/**: Shared game logic (`ShadowMapping.cs`)
+- **Content/**: Pre-built .xnb assets used directly by the game
+
+## How to Build & Run
+
+### Prerequisites
+- [.NET 8.0 SDK](https://dotnet.microsoft.com/download)
+- [MonoGame 3.8.*](https://www.monogame.net/)
+- For Android/iOS: Android/iOS SDK & emulator/device
+
+### Windows & DesktopGL (VSCode)
+1. Open the folder in VSCode.
+2. Use the provided tasks to build for Windows or DesktopGL:
+   - `Build Windows` or `Build DesktopGL`
+3. Use the provided tasks to run Windows or DesktopGL:
+   - `Run Windows` or `Run DesktopGL`
+
+### Visual Studio
+1. Open `ShadowMapping.sln`.
+2. Set the desired platform project as startup (Windows, DesktopGL, Android, or iOS).
+3. Build and run.
+
+### Android/iOS
+1. Open the respective project in Visual Studio or use `dotnet build`.
+2. Deploy to an emulator or device.
+
+## Notes
+- All platform projects use SDK-style .csproj files; legacy `AssemblyInfo.cs` is no longer used.
+- No Content.mgcb file is used; .xnb files are loaded directly.
+- Platform-specific code is minimized and organized into subdirectories.
+- Only Windows, DesktopGL, Android, and iOS are supported. Linux, MacOS, and PSMobile are not supported in MonoGame 3.8.*.

+ 0 - 110
ShadowMapping/ShadowMapping.MacOS.csproj

@@ -1,110 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>10.0.0</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{36473816-E068-4D38-84F3-F5564BA77FF8}</ProjectGuid>
-    <ProjectTypeGuids>{948B3504-5B70-4649-8FE4-BDE1FB46EC69};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <OutputType>Exe</OutputType>
-    <RootNamespace>ShadowMapping</RootNamespace>
-    <AssemblyName>ShadowMapping</AssemblyName>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>True</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>False</Optimize>
-    <OutputPath>bin\Debug</OutputPath>
-    <DefineConstants>DEBUG;</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <EnablePackageSigning>False</EnablePackageSigning>
-    <IncludeMonoRuntime>False</IncludeMonoRuntime>
-    <ConsolePause>False</ConsolePause>
-    <EnableCodeSigning>False</EnableCodeSigning>
-    <CreatePackage>False</CreatePackage>
-    <CodeSigningKey>Mac Developer</CodeSigningKey>
-    <UseSGen>False</UseSGen>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>True</Optimize>
-    <OutputPath>bin\Release</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <EnablePackageSigning>False</EnablePackageSigning>
-    <IncludeMonoRuntime>False</IncludeMonoRuntime>
-    <LinkMode>Full</LinkMode>
-    <ConsolePause>False</ConsolePause>
-    <EnableCodeSigning>False</EnableCodeSigning>
-    <CreatePackage>False</CreatePackage>
-    <CodeSigningKey>Mac Developer</CodeSigningKey>
-    <UseSGen>False</UseSGen>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|AnyCPU' ">
-    <DebugType>none</DebugType>
-    <Optimize>True</Optimize>
-    <OutputPath>bin\AppStore</OutputPath>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PackageSigningKey>3rd Party Mac Developer Installer</PackageSigningKey>
-    <IncludeMonoRuntime>True</IncludeMonoRuntime>
-    <LinkMode>Full</LinkMode>
-    <EnablePackageSigning>True</EnablePackageSigning>
-    <ConsolePause>False</ConsolePause>
-    <EnableCodeSigning>True</EnableCodeSigning>
-    <CreatePackage>True</CreatePackage>
-    <CodeSigningKey>3rd Party Mac Developer Application</CodeSigningKey>
-    <UseSGen>False</UseSGen>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Drawing" />
-    <Reference Include="MonoMac" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="Main.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="ShadowMapping.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="Info.plist" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(MSBuildExtensionsPath)\Mono\MonoMac\v0.0\Mono.MonoMac.targets" />
-  <ItemGroup>
-    <Folder Include="Content\" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="Content\DrawModel_0.xnb" />
-    <Content Include="Content\Grid_0.xnb" />
-    <Content Include="Content\dude.xnb" />
-    <Content Include="Content\grid.xnb" />
-    <Content Include="Content\headN_0.xnb" />
-    <Content Include="Content\headS_0.xnb" />
-    <Content Include="Content\head_0.xnb" />
-    <Content Include="Content\jacketN_0.xnb" />
-    <Content Include="Content\jacketS_0.xnb" />
-    <Content Include="Content\jacket_0.xnb" />
-    <Content Include="Content\pantsN_0.xnb" />
-    <Content Include="Content\pantsS_0.xnb" />
-    <Content Include="Content\pants_0.xnb" />
-    <Content Include="Content\upBodyC_0.xnb" />
-    <Content Include="Content\upBodyS_0.xnb" />
-    <Content Include="Content\upbodyN_0.xnb" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\MonoGame.Framework\MonoGame.Framework.MacOS.csproj">
-      <Project>{36C538E6-C32A-4A8D-A39C-566173D7118E}</Project>
-      <Name>MonoGame.Framework.MacOS</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\ThirdParty\Lidgren.Network\Lidgren.Network.MacOS.csproj">
-      <Project>{AE483C29-042E-4226-BA52-D247CE7676DA}</Project>
-      <Name>Lidgren.Network.MacOS</Name>
-    </ProjectReference>
-  </ItemGroup>
-</Project>

+ 52 - 0
ShadowMapping/ShadowMapping.sln

@@ -0,0 +1,52 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.2.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShadowMapping.Windows", "Platforms\Windows\ShadowMapping.Windows.csproj", "{A1A1A1A1-0000-0000-0000-000000000001}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShadowMapping.Android", "Platforms\Android\ShadowMapping.Android.csproj", "{A1A1A1A1-0000-0000-0000-000000000003}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShadowMapping.iOS", "Platforms\iOS\ShadowMapping.iOS.csproj", "{A1A1A1A1-0000-0000-0000-000000000004}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShadowMapping.Core", "Core\ShadowMapping.Core.csproj", "{ACD6FB30-5B06-0789-1F4A-C9503BFCBD37}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ShadowMapping.DesktopGL", "Platforms\Desktop\ShadowMapping.DesktopGL.csproj", "{BBF9F338-E5B1-98C3-5DBA-2583E76FD4C4}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A1A1A1A1-0000-0000-0000-000000000001}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000001}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000001}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000001}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000003}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000003}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000003}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000003}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000003}.Release|Any CPU.Deploy.0 = Release|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000004}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000004}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000004}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000004}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000004}.Release|Any CPU.Build.0 = Release|Any CPU
+		{A1A1A1A1-0000-0000-0000-000000000004}.Release|Any CPU.Deploy.0 = Release|Any CPU
+		{ACD6FB30-5B06-0789-1F4A-C9503BFCBD37}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{ACD6FB30-5B06-0789-1F4A-C9503BFCBD37}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{ACD6FB30-5B06-0789-1F4A-C9503BFCBD37}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{ACD6FB30-5B06-0789-1F4A-C9503BFCBD37}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BBF9F338-E5B1-98C3-5DBA-2583E76FD4C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BBF9F338-E5B1-98C3-5DBA-2583E76FD4C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BBF9F338-E5B1-98C3-5DBA-2583E76FD4C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BBF9F338-E5B1-98C3-5DBA-2583E76FD4C4}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		      SolutionGuid = {5F7C634A-9BDE-4843-8FA5-31A76E08192E}
+	EndGlobalSection
+EndGlobal