Parcourir la source

History Reset and Projects updated to SDK and MG 3.8.*

CartBlanche il y a 1 mois
commit
787aa50223
100 fichiers modifiés avec 3110 ajouts et 0 suppressions
  1. 57 0
      .gitignore
  2. 36 0
      2DShaderSample/.config/dotnet-tools.json
  3. 49 0
      2DShaderSample/.vscode/launch.json
  4. 45 0
      2DShaderSample/.vscode/tasks.json
  5. 113 0
      2DShaderSample/2DShaderSample.sln
  6. 11 0
      2DShaderSample/Core/2DShaderSample.Core.csproj
  7. 84 0
      2DShaderSample/Core/Content/Content.mgcb
  8. 18 0
      2DShaderSample/Core/Content/effects/Bevels.fx
  9. 17 0
      2DShaderSample/Core/Content/effects/BlackOut.fx
  10. 17 0
      2DShaderSample/Core/Content/effects/ColorFlip.fx
  11. 17 0
      2DShaderSample/Core/Content/effects/Grayscale.fx
  12. 19 0
      2DShaderSample/Core/Content/effects/HighContrast.fx
  13. 20 0
      2DShaderSample/Core/Content/effects/Invert.fx
  14. 15 0
      2DShaderSample/Core/Content/effects/NoEffect.fx
  15. 36 0
      2DShaderSample/Core/Content/effects/RainbowH.fx
  16. 64 0
      2DShaderSample/Core/Content/font.spritefont
  17. BIN
      2DShaderSample/Core/Content/images/bg5.jpg
  18. BIN
      2DShaderSample/Core/Content/images/surge.png
  19. 99 0
      2DShaderSample/Core/ShaderTest.cs
  20. 24 0
      2DShaderSample/Platforms/Android/2DShaderSample.Android.csproj
  21. 11 0
      2DShaderSample/Platforms/Android/AndroidManifest.xml
  22. 23 0
      2DShaderSample/Platforms/Android/MainActivity.cs
  23. BIN
      2DShaderSample/Platforms/Android/Resources/mipmap/icon.png
  24. 24 0
      2DShaderSample/Platforms/DesktopGL/2DShaderSample.DesktopGL.csproj
  25. 20 0
      2DShaderSample/Platforms/DesktopGL/Program.cs
  26. 25 0
      2DShaderSample/Platforms/Windows/2DShaderSample.Windows.csproj
  27. 20 0
      2DShaderSample/Platforms/Windows/Program.cs
  28. 24 0
      2DShaderSample/Platforms/iOS/2DShaderSample.iOS.csproj
  29. 28 0
      2DShaderSample/Platforms/iOS/Info.plist
  30. 30 0
      2DShaderSample/Platforms/iOS/Program.cs
  31. 39 0
      2DShaderSample/README.md
  32. 18 0
      AdMob/.vscode/launch.json
  33. 3 0
      AdMob/.vscode/settings.json
  34. 11 0
      AdMob/.vscode/tasks.json
  35. 70 0
      AdMob/Activity1.cs
  36. 38 0
      AdMob/AdMob.Android.csproj
  37. 24 0
      AdMob/AdMob.sln
  38. 19 0
      AdMob/Assets/AboutAssets.txt
  39. 92 0
      AdMob/Game1.cs
  40. 8 0
      AdMob/Properties/AndroidManifest.xml
  41. 44 0
      AdMob/Resources/AboutResources.txt
  42. 65 0
      AdMob/Resources/Resource.designer.cs
  43. BIN
      AdMob/Resources/drawable/Icon.png
  44. BIN
      AdMob/Resources/drawable/Splash.png
  45. 14 0
      AdMob/Resources/layout/Main.axml
  46. 7 0
      AdMob/Resources/values/Styles.xml
  47. 5 0
      AdMob/Resources/values/strings.xml
  48. 27 0
      Aiming/.vscode/launch.json
  49. 47 0
      Aiming/.vscode/tasks.json
  50. 46 0
      Aiming/Aiming.sln
  51. 15 0
      Aiming/Core/Aiming.Core.csproj
  52. 116 0
      Aiming/Core/AimingGame.cs
  53. 37 0
      Aiming/Core/Content/Content.mgcb
  54. BIN
      Aiming/Core/Content/Default.png
  55. BIN
      Aiming/Core/Content/GameThumbnail.png
  56. BIN
      Aiming/Core/Content/cat.png
  57. BIN
      Aiming/Core/Content/spotlight.png
  58. 29 0
      Aiming/Platforms/Android/Aiming.Android.csproj
  59. 20 0
      Aiming/Platforms/Android/AndroidManifest.xml
  60. 20 0
      Aiming/Platforms/Android/MainActivity.cs
  61. 25 0
      Aiming/Platforms/DesktopGL/Aiming.DesktopGL.csproj
  62. 14 0
      Aiming/Platforms/DesktopGL/Program.cs
  63. 26 0
      Aiming/Platforms/Windows/Aiming.Windows.csproj
  64. 14 0
      Aiming/Platforms/Windows/Program.cs
  65. 26 0
      Aiming/Platforms/iOS/Aiming.iOS.csproj
  66. 24 0
      Aiming/Platforms/iOS/Info.plist
  67. 24 0
      Aiming/Platforms/iOS/Main.cs
  68. 63 0
      Aiming/README.md
  69. 27 0
      Audio3D/.vscode/launch.json
  70. 3 0
      Audio3D/.vscode/settings.json
  71. 33 0
      Audio3D/.vscode/tasks.json
  72. 44 0
      Audio3D/Audio3D.sln
  73. 14 0
      Audio3D/Core/Audio3D.Core.csproj
  74. 189 0
      Audio3D/Core/AudioManager.cs
  75. 68 0
      Audio3D/Core/Cat.cs
  76. BIN
      Audio3D/Core/Content/CatSound0.xnb
  77. BIN
      Audio3D/Core/Content/CatSound1.xnb
  78. BIN
      Audio3D/Core/Content/CatSound2.xnb
  79. BIN
      Audio3D/Core/Content/CatTexture.xnb
  80. BIN
      Audio3D/Core/Content/DogSound.xnb
  81. BIN
      Audio3D/Core/Content/DogTexture.xnb
  82. BIN
      Audio3D/Core/Content/checker.xnb
  83. 65 0
      Audio3D/Core/Dog.cs
  84. 192 0
      Audio3D/Core/Game.cs
  85. 23 0
      Audio3D/Core/IAudioEmitter.cs
  86. 73 0
      Audio3D/Core/QuadDrawer.cs
  87. 103 0
      Audio3D/Core/SpriteEntity.cs
  88. 18 0
      Audio3D/Platforms/Android/AndroidManifest.xml
  89. 21 0
      Audio3D/Platforms/Android/Audio3D.Android.csproj
  90. 19 0
      Audio3D/Platforms/Android/MainActivity.cs
  91. 21 0
      Audio3D/Platforms/DesktopGL/Audio3D.DesktopGL.csproj
  92. 14 0
      Audio3D/Platforms/DesktopGL/Program.cs
  93. 22 0
      Audio3D/Platforms/Windows/Audio3D.Windows.csproj
  94. 14 0
      Audio3D/Platforms/Windows/Program.cs
  95. 21 0
      Audio3D/Platforms/iOS/Audio3D.iOS.csproj
  96. 27 0
      Audio3D/Platforms/iOS/Info.plist
  97. 12 0
      Audio3D/Platforms/iOS/Program.cs
  98. 37 0
      Audio3D/README.md
  99. 7 0
      BackgroundThreadTester/.vscode/extensions.json
  100. 67 0
      BackgroundThreadTester/.vscode/launch.json

+ 57 - 0
.gitignore

@@ -0,0 +1,57 @@
+#OS junk files
+[Tt]humbs.db
+*.DS_Store
+
+#Visual Studio files
+*.pidb
+*.userprefs
+*.[Oo]bj
+*.exe
+*.pdb
+*.user
+*.aps
+*.pch
+*.vspscc
+*.vssscc
+*_i.c
+*_p.c
+*.ncb
+*.suo
+*.tlb
+*.tlh
+*.bak
+*.[Cc]ache
+*.ilk
+*.log
+*.lib
+*.sbr
+*.sdf
+ipch/
+obj/
+[Bb]in
+[Dd]ebug*/
+[Rr]elease*/
+Ankh.NoLoad
+
+#Tooling
+_ReSharper*/
+*.resharper
+[Tt]est[Rr]esult*
+
+#Project files
+[Bb]uild/
+
+#Subversion files
+.svn
+
+# Office Temp Files
+~$*
+
+#monodroid private beta
+monodroid*.msi
+/CompiledContent/Android/IgnoreMe.dll
+/CompiledContent/OSX/IgnoreMe.dll
+/CompiledContent/Windows8/IgnoreMe.dll
+/CompiledContent/Windows/IgnoreMe.dll
+*.cachefile
+*.dll

+ 36 - 0
2DShaderSample/.config/dotnet-tools.json

@@ -0,0 +1,36 @@
+{
+  "version": 1,
+  "isRoot": true,
+  "tools": {
+    "dotnet-mgcb": {
+      "version": "3.8.4",
+      "commands": [
+        "mgcb"
+      ]
+    },
+    "dotnet-mgcb-editor": {
+      "version": "3.8.4",
+      "commands": [
+        "mgcb-editor"
+      ]
+    },
+    "dotnet-mgcb-editor-linux": {
+      "version": "3.8.4",
+      "commands": [
+        "mgcb-editor-linux"
+      ]
+    },
+    "dotnet-mgcb-editor-windows": {
+      "version": "3.8.4",
+      "commands": [
+        "mgcb-editor-windows"
+      ]
+    },
+    "dotnet-mgcb-editor-mac": {
+      "version": "3.8.4",
+      "commands": [
+        "mgcb-editor-mac"
+      ]
+    }
+  }
+}

+ 49 - 0
2DShaderSample/.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/2DShaderSample.Windows.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/Windows",
+            "stopAtEntry": false,
+            "console": "internalConsole"
+        },
+        {
+            "name": "Launch DesktopGL",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-desktopgl",
+            "program": "${workspaceFolder}/Platforms/DesktopGL/bin/Debug/net8.0/2DShaderSample.DesktopGL.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/DesktopGL",
+            "stopAtEntry": false,
+            "console": "internalConsole"
+        },
+        {
+            "name": "Launch iOS",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-ios",
+            "program": "${workspaceFolder}/Platforms/iOS/bin/Debug/net8.0-ios/2DShaderSample.iOS.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/iOS",
+            "stopAtEntry": false,
+            "console": "internalConsole"
+        },
+        {
+            "name": "Launch Android",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-android",
+            "program": "${workspaceFolder}/Platforms/Android/bin/Debug/net8.0-android/2DShaderSample.Android.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/Android",
+            "stopAtEntry": false,
+            "console": "internalConsole"
+        }
+    ]
+}

+ 45 - 0
2DShaderSample/.vscode/tasks.json

@@ -0,0 +1,45 @@
+{
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "build-windows",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "build",
+                "Platforms/Windows/2DShaderSample.Windows.csproj"
+            ],
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-desktopgl",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "build",
+                "Platforms/DesktopGL/2DShaderSample.DesktopGL.csproj"
+            ],
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-ios",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "build",
+                "Platforms/iOS/2DShaderSample.iOS.csproj"
+            ],
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-android",
+            "command": "dotnet",
+            "type": "process",
+            "args": [
+                "build",
+                "Platforms/Android/2DShaderSample.Android.csproj"
+            ],
+            "problemMatcher": "$msCompile"
+        }
+    ]
+}

+ 113 - 0
2DShaderSample/2DShaderSample.sln

@@ -0,0 +1,113 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{FBF56CC3-7AE6-AD2D-3F14-7F97FD322CD6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XNA2DShaderExamples.Core", "Core\XNA2DShaderExamples.Core.csproj", "{119B5664-187F-4427-9317-B7930BE070AB}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{324791A1-5798-203D-0CA6-A8E0DAEC81C8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Windows", "Windows", "{E4D925BB-EB21-135E-07FA-7558DA769730}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XNA2DShaderExamples.Windows", "Platforms\Windows\XNA2DShaderExamples.Windows.csproj", "{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DesktopGL", "DesktopGL", "{91D1BC8C-EC53-FBF8-D730-71448E1710A6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XNA2DShaderExamples.DesktopGL", "Platforms\DesktopGL\XNA2DShaderExamples.DesktopGL.csproj", "{21283E2A-531A-4C7E-9C18-9349D967164D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Android", "Android", "{C12F4581-1215-E9D3-7920-679DE6ABBC05}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XNA2DShaderExamples.Android", "Platforms\Android\XNA2DShaderExamples.Android.csproj", "{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "iOS", "iOS", "{3260BC3A-D039-20BF-4861-22673C64F5D4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XNA2DShaderExamples.iOS", "Platforms\iOS\XNA2DShaderExamples.iOS.csproj", "{2D12772C-92AE-4F50-9DE5-802EB7011B82}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{119B5664-187F-4427-9317-B7930BE070AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Debug|x64.Build.0 = Debug|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Debug|x86.Build.0 = Debug|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Release|x64.ActiveCfg = Release|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Release|x64.Build.0 = Release|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Release|x86.ActiveCfg = Release|Any CPU
+		{119B5664-187F-4427-9317-B7930BE070AB}.Release|x86.Build.0 = Release|Any CPU
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Debug|Any CPU.ActiveCfg = Debug|x64
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Debug|Any CPU.Build.0 = Debug|x64
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Debug|x64.ActiveCfg = Debug|x64
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Debug|x64.Build.0 = Debug|x64
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Debug|x86.ActiveCfg = Debug|x86
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Debug|x86.Build.0 = Debug|x86
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Release|Any CPU.ActiveCfg = Release|x64
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Release|Any CPU.Build.0 = Release|x64
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Release|x64.ActiveCfg = Release|x64
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Release|x64.Build.0 = Release|x64
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Release|x86.ActiveCfg = Release|x86
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C}.Release|x86.Build.0 = Release|x86
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Debug|x64.Build.0 = Debug|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Debug|x86.Build.0 = Debug|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Release|x64.ActiveCfg = Release|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Release|x64.Build.0 = Release|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Release|x86.ActiveCfg = Release|Any CPU
+		{21283E2A-531A-4C7E-9C18-9349D967164D}.Release|x86.Build.0 = Release|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Debug|x64.Build.0 = Debug|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Debug|x86.Build.0 = Debug|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Release|x64.ActiveCfg = Release|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Release|x64.Build.0 = Release|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Release|x86.ActiveCfg = Release|Any CPU
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2}.Release|x86.Build.0 = Release|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Debug|x64.Build.0 = Debug|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Debug|x86.Build.0 = Debug|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Release|x64.ActiveCfg = Release|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Release|x64.Build.0 = Release|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Release|x86.ActiveCfg = Release|Any CPU
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82}.Release|x86.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{119B5664-187F-4427-9317-B7930BE070AB} = {FBF56CC3-7AE6-AD2D-3F14-7F97FD322CD6}
+		{E4D925BB-EB21-135E-07FA-7558DA769730} = {324791A1-5798-203D-0CA6-A8E0DAEC81C8}
+		{A62D25F1-4E72-43A8-9D9C-038ECB1A2B4C} = {E4D925BB-EB21-135E-07FA-7558DA769730}
+		{91D1BC8C-EC53-FBF8-D730-71448E1710A6} = {324791A1-5798-203D-0CA6-A8E0DAEC81C8}
+		{21283E2A-531A-4C7E-9C18-9349D967164D} = {91D1BC8C-EC53-FBF8-D730-71448E1710A6}
+		{C12F4581-1215-E9D3-7920-679DE6ABBC05} = {324791A1-5798-203D-0CA6-A8E0DAEC81C8}
+		{5632A9F7-2EF7-4B32-975F-56ACC91F57D2} = {C12F4581-1215-E9D3-7920-679DE6ABBC05}
+		{3260BC3A-D039-20BF-4861-22673C64F5D4} = {324791A1-5798-203D-0CA6-A8E0DAEC81C8}
+		{2D12772C-92AE-4F50-9DE5-802EB7011B82} = {3260BC3A-D039-20BF-4861-22673C64F5D4}
+	EndGlobalSection
+EndGlobal

+ 11 - 0
2DShaderSample/Core/2DShaderSample.Core.csproj

@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <AssemblyName>XNA2DShaderExamples.Core</AssemblyName>
+    <RootNamespace>ShaderTests</RootNamespace>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+</Project>

+ 84 - 0
2DShaderSample/Core/Content/Content.mgcb

@@ -0,0 +1,84 @@
+
+#----------------------------- Global Properties ----------------------------#
+
+/outputDir:bin/$(Platform)
+/intermediateDir:obj/$(Platform)
+/platform:DesktopGL
+/config:$(Configuration)
+/profile:HiDef
+/compress:False
+
+#-------------------------------- References --------------------------------#
+
+
+#---------------------------------- Content ---------------------------------#
+
+#begin Fonts
+/importer:FontDescriptionImporter
+/processor:FontDescriptionProcessor
+/build:font.spritefont
+
+#begin Effects
+/importer:EffectImporter
+/processor:EffectProcessor
+/processorParam:DebugMode=Auto
+/build:effects/Bevels.fx
+
+/importer:EffectImporter
+/processor:EffectProcessor
+/processorParam:DebugMode=Auto
+/build:effects/BlackOut.fx
+
+/importer:EffectImporter
+/processor:EffectProcessor
+/processorParam:DebugMode=Auto
+/build:effects/ColorFlip.fx
+
+/importer:EffectImporter
+/processor:EffectProcessor
+/processorParam:DebugMode=Auto
+/build:effects/GrayScale.fx
+
+/importer:EffectImporter
+/processor:EffectProcessor
+/processorParam:DebugMode=Auto
+/build:effects/HighContrast.fx
+
+/importer:EffectImporter
+/processor:EffectProcessor
+/processorParam:DebugMode=Auto
+/build:effects/Invert.fx
+
+/importer:EffectImporter
+/processor:EffectProcessor
+/processorParam:DebugMode=Auto
+/build:effects/NoEffect.fx
+
+/importer:EffectImporter
+/processor:EffectProcessor
+/processorParam:DebugMode=Auto
+/build:effects/RainbowH.fx
+
+#begin Textures
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:images/bg5.jpg
+
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:images/surge.png
+

+ 18 - 0
2DShaderSample/Core/Content/effects/Bevels.fx

@@ -0,0 +1,18 @@
+sampler s0;
+
+float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
+{
+    float4 color = tex2D(s0, coords);
+	color -= tex2D(s0, coords - 0.002) * 2.5f;
+	color += tex2D(s0, coords + 0.002) * 2.5f;
+
+    return color;
+}
+
+technique Technique1
+{
+    pass Pass1
+    {
+        PixelShader = compile ps_3_0 PixelShaderFunction();
+    }
+}

+ 17 - 0
2DShaderSample/Core/Content/effects/BlackOut.fx

@@ -0,0 +1,17 @@
+sampler s0;
+
+float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
+{
+    float4 color = tex2D(s0, coords);
+	color.rgb = 0;
+
+    return color;
+}
+
+technique Technique1
+{
+    pass Pass1
+    {
+        PixelShader = compile ps_3_0 PixelShaderFunction();
+    }
+}

+ 17 - 0
2DShaderSample/Core/Content/effects/ColorFlip.fx

@@ -0,0 +1,17 @@
+sampler s0;
+
+float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
+{
+    float4 color = tex2D(s0, coords);
+	color.rgb = color.bgr;
+
+    return color;
+}
+
+technique Technique1
+{
+    pass Pass1
+    {
+        PixelShader = compile ps_3_0 PixelShaderFunction();
+    }
+}

+ 17 - 0
2DShaderSample/Core/Content/effects/Grayscale.fx

@@ -0,0 +1,17 @@
+sampler s0;
+
+float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
+{
+    float4 color = tex2D(s0, coords);
+	color.rgb = color.r;
+
+    return color;
+}
+
+technique Technique1
+{
+    pass Pass1
+    {
+        PixelShader = compile ps_3_0 PixelShaderFunction();
+    }
+}

+ 19 - 0
2DShaderSample/Core/Content/effects/HighContrast.fx

@@ -0,0 +1,19 @@
+sampler s0;
+
+float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
+{
+    float4 color = tex2D(s0, coords);
+
+	if      (color.r > .65) color.r = 1;
+	else if (color.r < .35) color.r = 0;
+
+    return color;
+}
+
+technique Technique1
+{
+    pass Pass1
+    {
+        PixelShader = compile ps_3_0 PixelShaderFunction();
+    }
+}

+ 20 - 0
2DShaderSample/Core/Content/effects/Invert.fx

@@ -0,0 +1,20 @@
+sampler s0;
+
+float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
+{
+    float4 color = tex2D(s0, coords);
+	
+	if (!any(color)) return color;
+	
+	color.rgb = 1 - color.rgb;
+
+    return color;
+}
+
+technique Technique1
+{
+    pass Pass1
+    {
+        PixelShader = compile ps_3_0 PixelShaderFunction();
+    }
+}

+ 15 - 0
2DShaderSample/Core/Content/effects/NoEffect.fx

@@ -0,0 +1,15 @@
+sampler s0;
+
+float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
+{
+    float4 color = tex2D(s0, coords);
+    return color;
+}
+
+technique Technique1
+{
+    pass Pass1
+    {
+        PixelShader = compile ps_3_0 PixelShaderFunction();
+    }
+}

+ 36 - 0
2DShaderSample/Core/Content/effects/RainbowH.fx

@@ -0,0 +1,36 @@
+sampler s0;
+
+float4 red    = float4(1,0,0,1);
+float4 orange = float4(1,.5,0,1);
+float4 yellow = float4(1,1,0,1);
+float4 green  = float4(0,1,0,1);
+float4 blue   = float4(0,0,1,1);
+float4 indigo = float4(.3,0,.8,1);
+float4 violet = float4(1,.8,1,1);
+
+float step = 1.0/7;
+
+float4 PixelShaderFunction(float2 coords: TEXCOORD0) : COLOR0
+{
+    float4 color = tex2D(s0, coords);
+
+	if (!any(color)) return color;
+
+	if      (coords.x < (step * 1)) color = red;
+	else if (coords.x < (step * 2)) color = orange;
+	else if (coords.x < (step * 3)) color = yellow;
+	else if (coords.x < (step * 4)) color = green;
+	else if (coords.x < (step * 5)) color = blue;
+	else if (coords.x < (step * 6)) color = indigo;
+	else                            color = violet;
+
+    return color;
+}
+
+technique Technique1
+{
+    pass Pass1
+    {
+        PixelShader = compile ps_3_0 PixelShaderFunction();
+    }
+}

+ 64 - 0
2DShaderSample/Core/Content/font.spritefont

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+This file contains an xml description of a font, and will be read by the XNA
+Framework Content Pipeline. Follow the comments to customize the appearance
+of the font in your game, and to change the characters which are available to draw
+with.
+-->
+<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
+  <Asset Type="Graphics:FontDescription">
+
+    <!--
+    Modify this string to change the font that will be imported.
+    -->
+    <FontName>Segoe Print</FontName>
+
+    <!--
+    Size is a float value, measured in points. Modify this value to change
+    the size of the font.
+    -->
+    <Size>12</Size>
+
+    <!--
+    Spacing is a float value, measured in pixels. Modify this value to change
+    the amount of spacing in between characters.
+    -->
+    <Spacing>0</Spacing>
+
+    <!--
+    UseKerning controls the layout of the font. If this value is true, kerning information
+    will be used when placing characters.
+    -->
+    <UseKerning>true</UseKerning>
+
+    <!--
+    Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
+    and "Bold, Italic", and are case sensitive.
+    -->
+    <Style>Bold</Style>
+
+    <!--
+    If you uncomment this line, the default character will be substituted if you draw
+    or measure text that contains characters which were not included in the font.
+    -->
+    <DefaultCharacter>*</DefaultCharacter> 
+
+    <!--
+    CharacterRegions control what letters are available in the font. Every
+    character from Start to End will be built and made available for drawing. The
+    default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
+    character set. The characters are ordered according to the Unicode standard.
+    See the documentation for more information.
+    -->
+    <CharacterRegions>
+      <CharacterRegion>
+        <Start>&#32;</Start>
+        <End>&#126;</End>
+      </CharacterRegion>
+      <CharacterRegion>
+        <Start>&#1024;</Start>
+        <End>&#1327;</End>
+      </CharacterRegion>
+    </CharacterRegions>
+  </Asset>
+</XnaContent>

BIN
2DShaderSample/Core/Content/images/bg5.jpg


BIN
2DShaderSample/Core/Content/images/surge.png


+ 99 - 0
2DShaderSample/Core/ShaderTest.cs

@@ -0,0 +1,99 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+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 Microsoft.Xna.Framework.Media;
+
+namespace ShaderTest
+{
+    public class ShaderTestGame : Game
+    {
+        GraphicsDeviceManager graphics;
+        SpriteBatch spriteBatch;
+
+        KeyboardState PreviousKeyState;
+        KeyboardState CurrentKeyState;
+
+        Texture2D background;
+        Texture2D surge;
+        SpriteFont font;
+
+        List<Effect> shaderEffects;
+        int shaderEffectIdx;
+
+        public ShaderTestGame()
+        {
+            graphics = new GraphicsDeviceManager(this);
+            Content.RootDirectory = "Content";
+            shaderEffectIdx = 0;
+        }
+
+        protected override void Initialize()
+        {
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            base.Initialize();
+        }
+
+        protected override void LoadContent()
+        {
+            font = Content.Load<SpriteFont>("font");
+            background = Content.Load<Texture2D>(@"images\bg5");
+            surge = Content.Load<Texture2D>(@"images\surge");
+
+            shaderEffects = new List<Effect>();
+            shaderEffects.Add(Content.Load<Effect>(@"effects\NoEffect"));
+            shaderEffects.Add(Content.Load<Effect>(@"effects\HighContrast"));
+            shaderEffects.Add(Content.Load<Effect>(@"effects\Bevels"));
+            shaderEffects.Add(Content.Load<Effect>(@"effects\Grayscale"));
+            shaderEffects.Add(Content.Load<Effect>(@"effects\ColorFlip"));
+            shaderEffects.Add(Content.Load<Effect>(@"effects\Invert"));
+            shaderEffects.Add(Content.Load<Effect>(@"effects\BlackOut"));
+            shaderEffects.Add(Content.Load<Effect>(@"effects\RainbowH"));
+        }
+
+        protected override void Update(GameTime gameTime)
+        {
+            PreviousKeyState = CurrentKeyState;
+            CurrentKeyState = Keyboard.GetState();
+            
+            if (CurrentKeyState.IsKeyDown(Keys.Escape)) this.Exit();
+
+            if (CurrentKeyState.IsKeyDown(Keys.Up) && PreviousKeyState.IsKeyUp(Keys.Up))
+            {
+                shaderEffectIdx++;
+                if (shaderEffectIdx >= shaderEffects.Count()) shaderEffectIdx = 0;
+            }
+
+            if (CurrentKeyState.IsKeyDown(Keys.Down) && PreviousKeyState.IsKeyUp(Keys.Down))
+            {
+                shaderEffectIdx--;
+                if (shaderEffectIdx < 0 ) shaderEffectIdx = shaderEffects.Count() - 1;
+            }
+
+            base.Update(gameTime);
+        }
+
+        protected override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice.Clear(Color.Black);
+
+            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
+            spriteBatch.Draw(background, new Vector2(-200, -200), Color.White);
+            shaderEffects[shaderEffectIdx].CurrentTechnique.Passes[0].Apply();
+            spriteBatch.Draw(surge, new Vector2(300,200), null, Color.White, 0f, Vector2.Zero, 2.0f, SpriteEffects.None, 0f);
+            spriteBatch.End();
+
+            spriteBatch.Begin();
+            spriteBatch.DrawString(font, "Press Up/Down to change shader effect", new Vector2(10, 10), Color.White);
+            spriteBatch.DrawString(font, "Current Effect: " + shaderEffects[shaderEffectIdx].Name, new Vector2(10, 30), Color.White);
+            spriteBatch.End();
+
+            base.Draw(gameTime);
+        }
+    }
+}

+ 24 - 0
2DShaderSample/Platforms/Android/2DShaderSample.Android.csproj

@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0-android</TargetFramework>
+    <Nullable>enable</Nullable>
+    <RootNamespace>ShaderTest.Android</RootNamespace>
+    <AssemblyName>2DShaderSample.Android</AssemblyName>
+    <MonoGamePlatform>Android</MonoGamePlatform>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\XNA2DShaderExamples.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <MonoGameContentReference Include="..\..\Core\Content\Content.mgcb">
+      <Link>Content\Content.mgcb</Link>
+    </MonoGameContentReference>
+  </ItemGroup>
+  <Target Name="RestoreDotnetTools" BeforeTargets="CollectPackageReferences">
+    <Message Text="Restoring dotnet tools (this might take a while depending on your internet speed and should only happen upon building your project for the first time, or after upgrading MonoGame, or clearing your nuget cache)" Importance="High" />
+    <Exec Command="dotnet tool restore" />
+  </Target>
+</Project>

+ 11 - 0
2DShaderSample/Platforms/Android/AndroidManifest.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.xna2dshaderexamples">
+  <application android:label="XNA2DShaderExamples" android:icon="@mipmap/icon">
+    <activity android:name="android.app.Activity" android:label="XNA2DShaderExamples" android:exported="true">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+  </application>
+</manifest>

+ 23 - 0
2DShaderSample/Platforms/Android/MainActivity.cs

@@ -0,0 +1,23 @@
+using Android.App;
+using Android.OS;
+
+
+namespace ShaderTest.Android
+{
+    /// <summary>
+    /// The main entry point for the Android application.
+    /// </summary>
+    [Activity(Label = "2DShaderSample", MainLauncher = true, Icon = "@mipmap/icon")]
+    public class MainActivity : Activity
+    {
+        /// <summary>
+        /// Called when the activity is first created.
+        /// </summary>
+        protected override void OnCreate(Bundle savedInstanceState)
+        {
+            base.OnCreate(savedInstanceState);
+            var game = new ShaderTestGame();
+            game.Run();
+        }
+    }
+}

BIN
2DShaderSample/Platforms/Android/Resources/mipmap/icon.png


+ 24 - 0
2DShaderSample/Platforms/DesktopGL/2DShaderSample.DesktopGL.csproj

@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0</TargetFramework>
+    <Nullable>enable</Nullable>
+    <RootNamespace>ShaderTest.DesktopGL</RootNamespace>
+    <AssemblyName>2DShaderSample.DesktopGL</AssemblyName>
+    <MonoGamePlatform>DesktopGL</MonoGamePlatform>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\2DShaderSample.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <MonoGameContentReference Include="..\..\Core\Content\Content.mgcb">
+      <Link>Content\Content.mgcb</Link>
+    </MonoGameContentReference>
+  </ItemGroup>
+  <Target Name="RestoreDotnetTools" BeforeTargets="CollectPackageReferences">
+    <Message Text="Restoring dotnet tools (this might take a while depending on your internet speed and should only happen upon building your project for the first time, or after upgrading MonoGame, or clearing your nuget cache)" Importance="High" />
+    <Exec Command="dotnet tool restore" />
+  </Target>
+</Project>

+ 20 - 0
2DShaderSample/Platforms/DesktopGL/Program.cs

@@ -0,0 +1,20 @@
+using System;
+
+namespace ShaderTest.DesktopGL
+{
+    /// <summary>
+    /// The main entry point for the DesktopGL application.
+    /// </summary>
+    public static class Program
+    {
+        /// <summary>
+        /// Application entry point.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            using (var game = new ShaderTestGame())
+                game.Run();
+        }
+    }
+}

+ 25 - 0
2DShaderSample/Platforms/Windows/2DShaderSample.Windows.csproj

@@ -0,0 +1,25 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>WinExe</OutputType>
+    <TargetFramework>net8.0-windows</TargetFramework>
+    <UseWindowsForms>false</UseWindowsForms>
+    <Nullable>enable</Nullable>
+    <RootNamespace>ShaderTest.Windows</RootNamespace>
+    <AssemblyName>2DShaderSample.Windows</AssemblyName>
+    <MonoGamePlatform>Windows</MonoGamePlatform>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\2DShaderSample.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.WindowsDX" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <MonoGameContentReference Include="..\..\Core\Content\Content.mgcb">
+      <Link>Content\Content.mgcb</Link>
+    </MonoGameContentReference>
+  </ItemGroup>
+  <Target Name="RestoreDotnetTools" BeforeTargets="CollectPackageReferences">
+    <Message Text="Restoring dotnet tools (this might take a while depending on your internet speed and should only happen upon building your project for the first time, or after upgrading MonoGame, or clearing your nuget cache)" Importance="High" />
+    <Exec Command="dotnet tool restore" />
+  </Target>
+</Project>

+ 20 - 0
2DShaderSample/Platforms/Windows/Program.cs

@@ -0,0 +1,20 @@
+using System;
+
+namespace ShaderTest.Windows
+{
+    /// <summary>
+    /// The main entry point for the Windows application.
+    /// </summary>
+    public static class Program
+    {
+        /// <summary>
+        /// Application entry point.
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            using (var game = new ShaderTestGame())
+                game.Run();
+        }
+    }
+}

+ 24 - 0
2DShaderSample/Platforms/iOS/2DShaderSample.iOS.csproj

@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net8.0-ios</TargetFramework>
+    <Nullable>enable</Nullable>
+    <RootNamespace>ShaderTests</RootNamespace>
+    <AssemblyName>2DShaderSample.iOS</AssemblyName>
+    <MonoGamePlatform>iOS</MonoGamePlatform>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\2DShaderSample.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.iOS" Version="3.8.*" />
+    <PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <MonoGameContentReference Include="..\..\Core\Content\Content.mgcb">
+      <Link>Content\Content.mgcb</Link>
+    </MonoGameContentReference>
+  </ItemGroup>
+  <Target Name="RestoreDotnetTools" BeforeTargets="CollectPackageReferences">
+    <Message Text="Restoring dotnet tools (this might take a while depending on your internet speed and should only happen upon building your project for the first time, or after upgrading MonoGame, or clearing your nuget cache)" Importance="High" />
+    <Exec Command="dotnet tool restore" />
+  </Target>
+</Project>

+ 28 - 0
2DShaderSample/Platforms/iOS/Info.plist

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>CFBundleDisplayName</key>
+    <string>XNA2DShaderExamples</string>
+    <key>CFBundleIdentifier</key>
+    <string>com.example.xna2dshaderexamples</string>
+    <key>CFBundleVersion</key>
+    <string>1.0</string>
+    <key>CFBundleShortVersionString</key>
+    <string>1.0</string>
+    <key>UILaunchStoryboardName</key>
+    <string>LaunchScreen</string>
+    <key>LSRequiresIPhoneOS</key>
+    <true/>
+    <key>UIRequiredDeviceCapabilities</key>
+    <array>
+        <string>armv7</string>
+    </array>
+    <key>UISupportedInterfaceOrientations</key>
+    <array>
+        <string>UIInterfaceOrientationPortrait</string>
+        <string>UIInterfaceOrientationLandscapeLeft</string>
+        <string>UIInterfaceOrientationLandscapeRight</string>
+    </array>
+</dict>
+</plist>

+ 30 - 0
2DShaderSample/Platforms/iOS/Program.cs

@@ -0,0 +1,30 @@
+using Foundation;
+using UIKit;
+
+namespace ShaderTest.iOS
+{
+    /// <summary>
+    /// The main entry point for the iOS application.
+    /// </summary>
+    public class Application
+    {
+        /// <summary>
+        /// Application entry point.
+        /// </summary>
+        static void Main(string[] args)
+        {
+            UIApplication.Main(args, null, typeof(AppDelegate));
+        }
+    }
+
+    public class AppDelegate : UIApplicationDelegate
+    {
+        ShaderTestGame game;
+        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
+        {
+            game = new ShaderTestGame();
+            game.Run();
+            return true;
+        }
+    }
+}

+ 39 - 0
2DShaderSample/README.md

@@ -0,0 +1,39 @@
+# XNA2DShaderExamples
+
+This project demonstrates the use of 2D shaders in MonoGame 3.8.* across multiple platforms: Windows, DesktopGL, Android, and iOS. It uses pre-built .xnb content files and is structured for modern .NET 8 SDK-style projects.
+
+## Project Structure
+
+- `/Core` — Shared game logic and assets
+- `/Platforms/Windows` — Windows-specific entry point and project
+- `/Platforms/DesktopGL` — DesktopGL-specific entry point and project
+- `/Platforms/Android` — Android-specific entry point and project
+- `/Platforms/iOS` — iOS-specific entry point and project
+
+## Building and Running
+
+### Prerequisites
+- .NET 8 SDK
+- Visual Studio 2022+ or VSCode
+- MonoGame 3.8.* NuGet packages (restored automatically)
+
+### Windows & DesktopGL
+- Open the solution in Visual Studio or VSCode
+- Build and run the desired platform project
+- Or use VSCode tasks/launch configurations for build/run
+
+### Android & iOS
+- Open the solution in Visual Studio (Windows for Android, Mac for iOS)
+- Build and deploy to device or emulator
+
+## Notes
+- No `Content.mgcb` file is used; .xnb files are loaded directly.
+- Platform-specific code is separated to avoid `#if` blocks.
+
+## Controls
+- Use Up/Down arrows to cycle through shader effects
+- Press Escape to exit (Windows/DesktopGL)
+
+---
+
+For more details, see the source code in each platform and the `Core` directory.

+ 18 - 0
AdMob/.vscode/launch.json

@@ -0,0 +1,18 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "MonoGame Android Build, Deploy & Run",
+            "type": "coreclr",
+            "request": "launch",
+            "program": "dotnet",
+            "args": [
+                "publish", "AdMob.Android.csproj", "-c", "Debug", "-f", "net8.0-android"
+            ],
+            "cwd": "${workspaceFolder}",
+            "console": "integratedTerminal",
+            "stopAtEntry": false,
+            "postDebugTask": "Install and Run APK"
+        }
+    ]
+}

+ 3 - 0
AdMob/.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+    "dotnet.preferCSharpExtension": true
+}

+ 11 - 0
AdMob/.vscode/tasks.json

@@ -0,0 +1,11 @@
+{
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "Install and Run APK",
+            "type": "shell",
+            "command": "adb install -r bin/Debug/net8.0-android/com.companyname.admob.apk && adb shell monkey -p com.companyname.admob -c android.intent.category.LAUNCHER 1",
+            "problemMatcher": []
+        }
+    ]
+}

+ 70 - 0
AdMob/Activity1.cs

@@ -0,0 +1,70 @@
+using System;
+
+using Android.App;
+using Android.Content;
+using Android.Runtime;
+using Android.Views;
+using Android.Widget;
+using Android.OS;
+using Microsoft.Xna.Framework;
+using Android.Gms.Ads;
+using Android.Content.PM;
+
+namespace MonoGame.Samples.AdMob
+{
+    [Activity (
+        Label = "AdMob",
+        MainLauncher = true,
+        Icon = "@drawable/icon",
+        Theme = "@style/Theme.Splash",
+        ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.Keyboard|ConfigChanges.KeyboardHidden)]	
+    public class Activity1 : AndroidGameActivity
+    {
+        private Game1 _game;
+        private View _view;
+
+        protected override void OnCreate(Bundle bundle)
+        {
+            base.OnCreate(bundle);
+
+            // Initialize Google Mobile Ads SDK
+            MobileAds.Initialize(this);
+
+            // Create the MonoGame view
+            _game = new Game1();
+            _view = _game.Services.GetService(typeof(View)) as View;
+
+            // Create a layout to hold both the game and the ad
+            var layout = new LinearLayout(this)
+            {
+                Orientation = Orientation.Vertical
+            };
+
+            // Add the MonoGame view
+            layout.AddView(_view, new LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.MatchParent,
+                0, 1f)); // Weight 1 to fill remaining space
+
+            // Create and add the AdMob banner
+            var adView = new AdView(this)
+            {
+                AdSize = AdSize.Banner,
+                AdUnitId = "ca-app-pub-3940256099942544/6300978111" // Test Ad Unit ID
+            };
+            var adParams = new LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.MatchParent,
+                ViewGroup.LayoutParams.WrapContent);
+            layout.AddView(adView, adParams);
+
+            // Load an ad
+            var adRequest = new AdRequest.Builder().Build();
+            adView.LoadAd(adRequest);
+
+            // Set the layout as the content view
+            SetContentView(layout);
+            _game.Run();
+        }
+    }
+}
+
+

+ 38 - 0
AdMob/AdMob.Android.csproj

@@ -0,0 +1,38 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net8.0-android</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>MonoGame.Samples.AdMob</RootNamespace>
+    <AssemblyName>MonoGame.Samples.AdMob</AssemblyName>
+    <AndroidApplication>true</AndroidApplication>
+    <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
+    <UseMaui>false</UseMaui>
+    <ImplicitUsings>disable</ImplicitUsings>
+    <Nullable>disable</Nullable>
+    <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
+    <AssemblyTitle>MonoGame AdMob Sample</AssemblyTitle>
+    <AssemblyCompany>MonoGame</AssemblyCompany>
+    <AssemblyProduct>MonoGame AdMob Sample</AssemblyProduct>
+  </PropertyGroup>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DefineConstants>DEBUG;ANDROID</DefineConstants>
+    <AndroidLinkMode>None</AndroidLinkMode>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+  </PropertyGroup>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
+    <DefineConstants>ANDROID</DefineConstants>
+    <AndroidLinkMode>SdkOnly</AndroidLinkMode>
+    <AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
+    <DebugType>none</DebugType>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.*" />
+    <PackageReference Include="Xamarin.GooglePlayServices.Ads" Version="120.0.0" />
+  </ItemGroup>
+
+</Project>

+ 24 - 0
AdMob/AdMob.sln

@@ -0,0 +1,24 @@
+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}") = "AdMob.Android", "AdMob.Android.csproj", "{E1DB4DAE-277C-6E59-3E9B-7F8020524FA8}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{E1DB4DAE-277C-6E59-3E9B-7F8020524FA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E1DB4DAE-277C-6E59-3E9B-7F8020524FA8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E1DB4DAE-277C-6E59-3E9B-7F8020524FA8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E1DB4DAE-277C-6E59-3E9B-7F8020524FA8}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {076C6A8B-47FA-4029-9704-7E6661A1FB00}
+	EndGlobalSection
+EndGlobal

+ 19 - 0
AdMob/Assets/AboutAssets.txt

@@ -0,0 +1,19 @@
+Any raw assets you want to be deployed with your application can be placed in
+this directory (and child directories) and given a Build Action of "AndroidAsset".
+
+These files will be deployed with you package and will be accessible using Android's
+AssetManager, like this:
+
+public class ReadAsset : Activity
+{
+	protected override void OnCreate (Bundle bundle)
+	{
+		base.OnCreate (bundle);
+
+		InputStream input = Assets.Open ("my_asset.txt");
+	}
+}
+
+Additionally, some Android functions will automatically load asset files:
+
+Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");

+ 92 - 0
AdMob/Game1.cs

@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+
+#if ANDROID
+using Android.App;
+#endif
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Media;
+
+namespace MonoGame.Samples.AdMob
+{
+	/// <summary>
+	/// This is the main type for your game
+	/// </summary>
+	public class Game1 : Game
+	{
+		public static Game1 Instance { get; private set; }
+		
+		GraphicsDeviceManager graphics;
+		SpriteBatch spriteBatch;		
+		
+		public Game1 ()  
+		{
+			Instance = this;
+			graphics = new GraphicsDeviceManager (this);
+			
+			Content.RootDirectory = "Content";
+			
+			graphics.PreferMultiSampling = true;
+			graphics.IsFullScreen = true;	
+
+			graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight | DisplayOrientation.Portrait;
+		}
+		
+		/// <summary>
+		/// Allows the game to perform any initialization it needs to before starting to run.
+		/// This is where it can query for any required services and load any non-graphic
+		/// related content.  Calling base.Initialize will enumerate through any components
+		/// and initialize them as well.
+		/// </summary>
+		protected override void Initialize ()
+		{
+			// TODO: Add your initialization logic here
+
+			base.Initialize ();
+		}
+
+		/// <summary>
+		/// LoadContent will be called once per game and is the place to load
+		/// all of your content.
+		/// </summary>
+		protected override void LoadContent ()
+		{
+			// Create a new SpriteBatch, which can be used to draw textures.
+			spriteBatch = new SpriteBatch (GraphicsDevice);
+			
+		}
+
+		/// <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)
+		{
+			if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
+			{
+				Exit();
+			}
+			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)
+		{
+			graphics.GraphicsDevice.Clear (Color.CornflowerBlue);
+			
+			// Won't be visible until we hide the movie
+			spriteBatch.Begin();
+			spriteBatch.End();
+		}
+	}
+}
+
+

+ 8 - 0
AdMob/Properties/AndroidManifest.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="MonoGame.Samples.AdMob">
+	<application android:label="AdMob" android:icon="@drawable/icon">
+		<activity android:name="com.google.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
+	</application>
+	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+	<uses-permission android:name="android.permission.INTERNET" />
+</manifest>

+ 44 - 0
AdMob/Resources/AboutResources.txt

@@ -0,0 +1,44 @@
+Images, layout descriptions, binary blobs and string dictionaries can be included 
+in your application as resource files.  Various Android APIs are designed to 
+operate on the resource IDs instead of dealing with images, strings or binary blobs 
+directly.
+
+For example, a sample Android app that contains a user interface layout (main.axml),
+an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) 
+would keep its resources in the "Resources" directory of the application:
+
+Resources/
+    drawable/
+        icon.png
+
+    layout/
+        main.axml
+
+    values/
+        strings.xml
+
+In order to get the build system to recognize Android resources, set the build action to
+"AndroidResource".  The native Android APIs do not operate directly with filenames, but 
+instead operate on resource IDs.  When you compile an Android application that uses resources, 
+the build system will package the resources for distribution and generate a class called "R" 
+(this is an Android convention) that contains the tokens for each one of the resources 
+included. For example, for the above Resources layout, this is what the R class would expose:
+
+public class R {
+    public class drawable {
+        public const int icon = 0x123;
+    }
+
+    public class layout {
+        public const int main = 0x456;
+    }
+
+    public class strings {
+        public const int first_string = 0xabc;
+        public const int second_string = 0xbcd;
+    }
+}
+
+You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main 
+to reference the layout/main.axml file, or R.strings.first_string to reference the first 
+string in the dictionary file values/strings.xml.

+ 65 - 0
AdMob/Resources/Resource.designer.cs

@@ -0,0 +1,65 @@
+#pragma warning disable 1591
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.586
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+[assembly: Android.Runtime.ResourceDesignerAttribute("MonoGame.Samples.AdMob.Resource", IsApplication=true)]
+
+namespace MonoGame.Samples.AdMob
+{
+	
+	
+	[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
+	public partial class Resource
+	{
+		
+		Resource()
+		{
+			global::Android.Runtime.ResourceIdManager.UpdateIdValues ();
+		}
+		
+		public static void UpdateIdValues()
+		{
+		}
+		
+		public partial class Attribute
+		{
+			
+			private Attribute()
+			{
+			}
+		}
+		
+		public partial class Drawable
+		{
+			
+			// aapt resource value: 0x7f020000
+			public const int Icon = 2130837504;
+			
+			// aapt resource value: 0x7f020001
+			public const int Splash = 2130837505;
+			
+			private Drawable()
+			{
+			}
+		}
+		
+		public partial class Style
+		{
+			
+			// aapt resource value: 0x7f030000
+			public const int Theme_Splash = 2130903040;
+			
+			private Style()
+			{
+			}
+		}
+	}
+}
+#pragma warning restore 1591

BIN
AdMob/Resources/drawable/Icon.png


BIN
AdMob/Resources/drawable/Splash.png


+ 14 - 0
AdMob/Resources/layout/Main.axml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+<Button  
+    android:id="@+id/myButton"
+    android:layout_width="fill_parent" 
+    android:layout_height="wrap_content" 
+    android:text="@string/hello"
+    />
+</LinearLayout>
+

+ 7 - 0
AdMob/Resources/values/Styles.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <style name="Theme.Splash" parent="android:Theme">
+    <item name="android:windowBackground">@drawable/splash</item>
+    <item name="android:windowNoTitle">true</item>
+  </style>
+</resources>

+ 5 - 0
AdMob/Resources/values/strings.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="hello">Hello MonoGame AdMob!</string>
+    <string name="app_name">MonoGame AdMob Sample</string>
+</resources>

+ 27 - 0
Aiming/.vscode/launch.json

@@ -0,0 +1,27 @@
+{
+  "version": "0.2.0",
+  "configurations": [
+    {
+      "name": "Run Windows",
+      "type": "coreclr",
+      "request": "launch",
+      "preLaunchTask": "build-windows",
+      "program": "${workspaceFolder}/Platforms/Windows/bin/Debug/net8.0-windows/Aiming.Windows.exe",
+      "args": [],
+      "cwd": "${workspaceFolder}/Platforms/Windows",
+      "stopAtEntry": false,
+      "console": "internalConsole"
+    },
+    {
+      "name": "Run DesktopGL",
+      "type": "coreclr",
+      "request": "launch",
+      "preLaunchTask": "build-desktopgl",
+      "program": "${workspaceFolder}/Platforms/DesktopGL/bin/Debug/net8.0/Aiming.DesktopGL.exe",
+      "args": [],
+      "cwd": "${workspaceFolder}/Platforms/DesktopGL",
+      "stopAtEntry": false,
+      "console": "internalConsole"
+    }
+  ]
+}

+ 47 - 0
Aiming/.vscode/tasks.json

@@ -0,0 +1,47 @@
+{
+  "version": "2.0.0",
+  "tasks": [
+    {
+      "label": "build-windows",
+      "type": "shell",
+      "command": "dotnet build Platforms/Windows/Aiming.Windows.csproj",
+      "group": "build",
+      "problemMatcher": "$msCompile"
+    },
+    {
+      "label": "build-desktopgl",
+      "type": "shell",
+      "command": "dotnet build Platforms/DesktopGL/Aiming.DesktopGL.csproj",
+      "group": "build",
+      "problemMatcher": "$msCompile"
+    },
+    {
+      "label": "build-android",
+      "type": "shell",
+      "command": "dotnet build Platforms/Android/Aiming.Android.csproj",
+      "group": "build",
+      "problemMatcher": "$msCompile"
+    },
+    {
+      "label": "build-ios",
+      "type": "shell",
+      "command": "dotnet build Platforms/iOS/Aiming.iOS.csproj",
+      "group": "build",
+      "problemMatcher": "$msCompile"
+    },
+    {
+      "label": "run-windows",
+      "type": "shell",
+      "command": "dotnet run --project Platforms/Windows/Aiming.Windows.csproj",
+      "group": "test",
+      "problemMatcher": []
+    },
+    {
+      "label": "run-desktopgl",
+      "type": "shell",
+      "command": "dotnet run --project Platforms/DesktopGL/Aiming.DesktopGL.csproj",
+      "group": "test",
+      "problemMatcher": []
+    }
+  ]
+}

+ 46 - 0
Aiming/Aiming.sln

@@ -0,0 +1,46 @@
+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}") = "Aiming.Android", "Platforms\Android\Aiming.Android.csproj", "{F1DCECB8-D539-6B7B-EAC5-A0D48B217A30}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aiming.iOS", "Platforms\iOS\Aiming.iOS.csproj", "{5E492C63-6CC8-4091-B25B-03A88120A8F0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aiming.Windows", "Platforms\Windows\Aiming.Windows.csproj", "{6FBA11F0-0AFB-66BD-1A3D-FB11E6CA972B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aiming.DesktopGL", "Platforms\DesktopGL\Aiming.DesktopGL.csproj", "{023C00AD-B2D9-50D2-3D3A-BD4AFBBD25CC}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F1DCECB8-D539-6B7B-EAC5-A0D48B217A30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F1DCECB8-D539-6B7B-EAC5-A0D48B217A30}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F1DCECB8-D539-6B7B-EAC5-A0D48B217A30}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{F1DCECB8-D539-6B7B-EAC5-A0D48B217A30}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F1DCECB8-D539-6B7B-EAC5-A0D48B217A30}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F1DCECB8-D539-6B7B-EAC5-A0D48B217A30}.Release|Any CPU.Deploy.0 = Release|Any CPU
+		{5E492C63-6CC8-4091-B25B-03A88120A8F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5E492C63-6CC8-4091-B25B-03A88120A8F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5E492C63-6CC8-4091-B25B-03A88120A8F0}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+		{5E492C63-6CC8-4091-B25B-03A88120A8F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5E492C63-6CC8-4091-B25B-03A88120A8F0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5E492C63-6CC8-4091-B25B-03A88120A8F0}.Release|Any CPU.Deploy.0 = Release|Any CPU
+		{6FBA11F0-0AFB-66BD-1A3D-FB11E6CA972B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6FBA11F0-0AFB-66BD-1A3D-FB11E6CA972B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6FBA11F0-0AFB-66BD-1A3D-FB11E6CA972B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6FBA11F0-0AFB-66BD-1A3D-FB11E6CA972B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{023C00AD-B2D9-50D2-3D3A-BD4AFBBD25CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{023C00AD-B2D9-50D2-3D3A-BD4AFBBD25CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{023C00AD-B2D9-50D2-3D3A-BD4AFBBD25CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{023C00AD-B2D9-50D2-3D3A-BD4AFBBD25CC}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {041B000C-440E-4E15-AE36-5F085266BF6E}
+	EndGlobalSection
+EndGlobal

+ 15 - 0
Aiming/Core/Aiming.Core.csproj

@@ -0,0 +1,15 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>Aiming.Core</RootNamespace>
+    <AssemblyName>Aiming.Core</AssemblyName>
+    <Description>Shared game logic for Aiming MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>CartBlanche</Company>
+    <Version>1.0.0</Version>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+</Project>

+ 116 - 0
Aiming/Core/AimingGame.cs

@@ -0,0 +1,116 @@
+//----------------------------------------------------------------------------- 
+// AimingGame.cs (moved to Core)
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+using Microsoft.Xna.Framework.Input.Touch;
+using Microsoft.Xna.Framework.Content;
+
+namespace Aiming
+{
+    /// <summary>
+    /// This sample shows how to aim one object towards another. In this sample, a
+    /// spotlight turns to aim towards a cat that the player controls.
+    /// </summary>
+    public class AimingGame : Game
+    {
+        // how fast can the cat move?  this is in terms of pixels per frame.
+        const float CatSpeed = 10.0f;
+        // how fast can the spot light turn? this is in terms of radians per frame.
+        const float SpotlightTurnSpeed = 0.025f;
+        GraphicsDeviceManager graphics;
+        SpriteBatch spriteBatch;
+        Texture2D spotlightTexture;
+        Vector2 spotlightPosition = new Vector2();
+        Vector2 spotlightOrigin = new Vector2();
+        float spotlightAngle = 0.0f;
+        Texture2D catTexture;
+        Vector2 catPosition = new Vector2();
+        Vector2 catOrigin = new Vector2();
+        public AimingGame()
+        {
+            graphics = new GraphicsDeviceManager(this);
+            Content.RootDirectory = "Content";
+            graphics.PreferredBackBufferWidth = 480;
+            graphics.PreferredBackBufferHeight = 640;
+#if MOBILE
+            graphics.IsFullScreen = true;
+#endif
+        }
+        protected override void Initialize()
+        {
+            base.Initialize();
+            Viewport vp = graphics.GraphicsDevice.Viewport;
+            spotlightPosition.X = vp.X + vp.Width / 2;
+            spotlightPosition.Y = vp.Y + vp.Height / 2;
+            catPosition.X = vp.X + vp.Width / 4;
+            catPosition.Y = vp.Y + vp.Height / 2;
+        }
+        protected override void LoadContent()
+        {
+            spriteBatch = new SpriteBatch(GraphicsDevice);
+            spotlightTexture = Content.Load<Texture2D>("spotlight");
+            spotlightOrigin.X = spotlightTexture.Width / 2;
+            spotlightOrigin.Y = spotlightTexture.Height / 2;
+            catTexture = Content.Load<Texture2D>("cat");
+            catOrigin.X = catTexture.Width / 2;
+            catOrigin.Y = catTexture.Height / 2;
+        }
+        protected override void Update(GameTime gameTime)
+        {
+            // Allows the game to exit
+            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
+                Keyboard.GetState().IsKeyDown(Keys.Escape))
+                Exit();
+            // Move the cat with arrow keys or touch
+            Vector2 move = Vector2.Zero;
+            KeyboardState keyState = Keyboard.GetState();
+            if (keyState.IsKeyDown(Keys.Left)) move.X -= 1;
+            if (keyState.IsKeyDown(Keys.Right)) move.X += 1;
+            if (keyState.IsKeyDown(Keys.Up)) move.Y -= 1;
+            if (keyState.IsKeyDown(Keys.Down)) move.Y += 1;
+            if (move.Length() > 1)
+                move.Normalize();
+            catPosition += move * CatSpeed;
+            // Touch input (for mobile)
+            TouchCollection touches = TouchPanel.GetState();
+            if (touches.Count > 0)
+            {
+                Vector2 touch = touches[0].Position;
+                Vector2 diff = touch - catPosition;
+                if (diff.Length() > CatSpeed)
+                {
+                    diff.Normalize();
+                    catPosition += diff * CatSpeed;
+                }
+                else
+                {
+                    catPosition = touch;
+                }
+            }
+            // Aim the spotlight at the cat
+            Vector2 toCat = catPosition - spotlightPosition;
+            float desiredAngle = (float)Math.Atan2(toCat.Y, toCat.X);
+            float delta = MathHelper.WrapAngle(desiredAngle - spotlightAngle);
+            if (Math.Abs(delta) < SpotlightTurnSpeed)
+                spotlightAngle = desiredAngle;
+            else
+                spotlightAngle += Math.Sign(delta) * SpotlightTurnSpeed;
+            base.Update(gameTime);
+        }
+        protected override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice.Clear(Color.MonoGameOrange);
+            spriteBatch.Begin();
+            spriteBatch.Draw(spotlightTexture, spotlightPosition, null, Color.White, spotlightAngle, spotlightOrigin, 1.0f, SpriteEffects.None, 0f);
+            spriteBatch.Draw(catTexture, catPosition, null, Color.White, 0f, catOrigin, 1.0f, SpriteEffects.None, 0f);
+            spriteBatch.End();
+            base.Draw(gameTime);
+        }
+    }
+}

+ 37 - 0
Aiming/Core/Content/Content.mgcb

@@ -0,0 +1,37 @@
+#----------------------------- Global Properties ----------------------------#
+
+/outputDir:bin/$(Platform)
+/intermediateDir:obj/$(Platform)
+/platform:DesktopGL
+/config:
+/profile:Reach
+/compress:False
+
+#-------------------------------- References --------------------------------#
+
+
+#---------------------------------- Content ----------------------------------#
+
+#begin cat.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:cat.png
+
+#begin spotlight.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:spotlight.png

BIN
Aiming/Core/Content/Default.png


BIN
Aiming/Core/Content/GameThumbnail.png


BIN
Aiming/Core/Content/cat.png


BIN
Aiming/Core/Content/spotlight.png


+ 29 - 0
Aiming/Platforms/Android/Aiming.Android.csproj

@@ -0,0 +1,29 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-android</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Aiming.Android</RootNamespace>
+    <AssemblyName>Aiming.Android</AssemblyName>
+    <Description>Android platform for Aiming MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>MonoGame Foundation</Company>
+    <Version>1.0.0</Version>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+    <AndroidManifest>AndroidManifest.xml</AndroidManifest>
+    <SupportedOSPlatformVersion>28.0</SupportedOSPlatformVersion>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Aiming.Core.csproj" />
+  </ItemGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.4" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\..\CompiledContent\Android\Content\Textures\cat.xnb" Link="Content\cat.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Android\Content\Textures\spotlight.xnb" Link="Content\spotlight.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 20 - 0
Aiming/Platforms/Android/AndroidManifest.xml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.cartblanche.aiming"
+    android:versionCode="1"
+    android:versionName="1.0">
+    <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="34" />
+    <application android:label="Aiming Sample" android:icon="@mipmap/ic_launcher">
+        <activity android:name="android.app.Activity"
+            android:label="Aiming Sample"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:screenOrientation="landscape"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>

+ 20 - 0
Aiming/Platforms/Android/MainActivity.cs

@@ -0,0 +1,20 @@
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using Microsoft.Xna.Framework;
+
+namespace Aiming.Android
+{
+    [Activity (Label = "Aiming Sample", MainLauncher = true
+	          , Icon = "@drawable/icon", Theme = "@style/Theme.Splash",ConfigurationChanges=ConfigChanges.Orientation|ConfigChanges.Keyboard|ConfigChanges.KeyboardHidden)]	
+    public class MainActivity : AndroidGameActivity
+    {
+        protected override void OnCreate(Bundle savedInstanceState)
+        {
+            base.OnCreate(savedInstanceState);
+            var game = new AimingGame();
+            SetContentView((game.Services.GetService(typeof(Android.Views.View))) as Android.Views.View);
+            game.Run();
+        }
+    }
+}

+ 25 - 0
Aiming/Platforms/DesktopGL/Aiming.DesktopGL.csproj

@@ -0,0 +1,25 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>Aiming.DesktopGL</RootNamespace>
+    <AssemblyName>Aiming.DesktopGL</AssemblyName>
+    <Description>DesktopGL platform for Aiming MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>MonoGame Foundation</Company>
+    <Version>1.0.0</Version>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Aiming.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\cat.xnb" Link="Content\cat.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\spotlight.xnb" Link="Content\spotlight.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 14 - 0
Aiming/Platforms/DesktopGL/Program.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Aiming.DesktopGL
+{
+    public static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            using var game = new Aiming.AimingGame();
+            game.Run();
+        }
+    }
+}

+ 26 - 0
Aiming/Platforms/Windows/Aiming.Windows.csproj

@@ -0,0 +1,26 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-windows</TargetFramework>
+    <OutputType>WinExe</OutputType>
+    <UseWindowsForms>true</UseWindowsForms>
+    <RootNamespace>Aiming.Windows</RootNamespace>
+    <AssemblyName>Aiming.Windows</AssemblyName>
+    <Description>Windows platform for Aiming MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>MonoGame Foundation</Company>
+    <Version>1.0.0</Version>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Aiming.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\cat.xnb" Link="Content\cat.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\Windows\Content\Textures\spotlight.xnb" Link="Content\spotlight.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 14 - 0
Aiming/Platforms/Windows/Program.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Aiming.Windows
+{
+    public static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            using var game = new Aiming.AimingGame();
+            game.Run();
+        }
+    }
+}

+ 26 - 0
Aiming/Platforms/iOS/Aiming.iOS.csproj

@@ -0,0 +1,26 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-ios</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <SupportedOSPlatformVersion>11.0</SupportedOSPlatformVersion>
+    <RootNamespace>Aiming.iOS</RootNamespace>
+    <AssemblyName>Aiming.iOS</AssemblyName>
+    <Description>iOS platform for Aiming MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>MonoGame Foundation</Company>
+    <Version>1.0.0</Version>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Aiming.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.iOS" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\..\CompiledContent\iOS\Content\Textures\cat.xnb" Link="Content\cat.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+    <Content Include="..\..\..\CompiledContent\iOS\Content\Textures\spotlight.xnb" Link="Content\spotlight.xnb">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 24 - 0
Aiming/Platforms/iOS/Info.plist

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>CFBundleDisplayName</key>
+    <string>Aiming Sample</string>
+    <key>CFBundleIdentifier</key>
+    <string>com.cartblanche.aiming</string>
+    <key>CFBundleVersion</key>
+    <string>1.0</string>
+    <key>CFBundleShortVersionString</key>
+    <string>1.0.0</string>
+    <key>UILaunchStoryboardName</key>
+    <string>LaunchScreen</string>
+    <key>LSRequiresIPhoneOS</key>
+    <true/>
+    <key>UISupportedInterfaceOrientations</key>
+    <array>
+        <string>UIInterfaceOrientationPortrait</string>
+        <string>UIInterfaceOrientationLandscapeLeft</string>
+        <string>UIInterfaceOrientationLandscapeRight</string>
+    </array>
+</dict>
+</plist>

+ 24 - 0
Aiming/Platforms/iOS/Main.cs

@@ -0,0 +1,24 @@
+using Foundation;
+using UIKit;
+
+namespace Aiming.iOS
+{
+    [Register("AppDelegate")]
+    public class AppDelegate : UIApplicationDelegate
+    {
+        AimingGame game;
+        public override void FinishedLaunching(UIApplication app)
+        {
+            game = new AimingGame();
+            game.Run();
+        }
+    }
+
+    public class Application
+    {
+        static void Main(string[] args)
+        {
+            UIApplication.Main(args, null, "AppDelegate");
+        }
+    }
+}

+ 63 - 0
Aiming/README.md

@@ -0,0 +1,63 @@
+# Aiming MonoGame Sample
+
+This is a cross-platform MonoGame 3.8.4 sample project demonstrating how to aim one object towards another (e.g., a spotlight tracking a cat). The project is organized for modern .NET 8 SDK-style builds and supports Windows, DesktopGL, Android, and iOS.
+
+## Project Structure
+
+```
+Aiming/
+├── Core/                # Shared game logic (AimingGame.cs, Aiming.Core.csproj)
+├── Platforms/
+│   ├── Windows/         # Windows-specific entry point and csproj
+│   ├── DesktopGL/       # DesktopGL (cross-platform OpenGL) entry point and csproj
+│   ├── Android/         # Android entry point, csproj, and manifest
+│   └── iOS/             # iOS entry point, csproj, and Info.plist
+├── Content/             # Shared content (PNG, XNB, etc.)
+├── .vscode/             # VS Code tasks and launch configs
+├── README.md            # This file
+└── Aiming.sln           # Visual Studio solution
+```
+
+## Prerequisites
+- .NET 8 SDK
+- MonoGame 3.8.4 (NuGet packages are referenced automatically)
+- For Android/iOS: Xamarin/MAUI workloads and platform SDKs
+- Visual Studio 2022+ or VS Code
+
+## Building and Running
+
+### With Visual Studio
+- Open `Aiming.sln`
+- Set the desired platform project as startup (Windows, DesktopGL, Android, or iOS)
+- Build and run
+
+### With VS Code
+- Use the provided tasks and launch configurations:
+  - **Build:**
+    - `build-windows` — Windows
+    - `build-desktopgl` — DesktopGL
+    - `build-android` — Android
+    - `build-ios` — iOS
+  - **Run/Debug:**
+    - `Run Windows` — Launches Windows build
+    - `Run DesktopGL` — Launches DesktopGL build
+- Press `Ctrl+Shift+B` to build, or use the Run/Debug panel
+
+### Command Line
+```
+dotnet build Platforms/Windows/Aiming.Windows.csproj
+# or
+dotnet build Platforms/DesktopGL/Aiming.DesktopGL.csproj
+# or
+ dotnet build Platforms/Android/Aiming.Android.csproj
+# or
+ dotnet build Platforms/iOS/Aiming.iOS.csproj
+```
+
+## Notes
+- Content is loaded as `.xnb` or `.png` files directly, depending on platform.
+- Android/iOS builds require the appropriate SDKs and emulators/devices.
+- If you encounter issues with Android entry points, check the MonoGame 3.8.4 documentation for the latest supported base class for `MainActivity`.
+
+## License
+MIT (see LICENSE if present)

+ 27 - 0
Audio3D/.vscode/launch.json

@@ -0,0 +1,27 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Run Windows",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-windows",
+            "program": "${workspaceFolder}/Platforms/Windows/bin/Debug/net8.0-windows/Audio3D.Windows.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/Windows",
+            "stopAtEntry": false,
+            "console": "internalConsole"
+        },
+        {
+            "name": "Run DesktopGL",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-desktopgl",
+            "program": "${workspaceFolder}/Platforms/DesktopGL/bin/Debug/net8.0/Audio3D.DesktopGL.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}/Platforms/DesktopGL",
+            "stopAtEntry": false,
+            "console": "internalConsole"
+        }
+    ]
+}

+ 3 - 0
Audio3D/.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+    "dotnet.preferCSharpExtension": true
+}

+ 33 - 0
Audio3D/.vscode/tasks.json

@@ -0,0 +1,33 @@
+{
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "build-windows",
+            "type": "shell",
+            "command": "dotnet build Platforms/Windows/Audio3D.Windows.csproj",
+            "group": "build",
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "build-desktopgl",
+            "type": "shell",
+            "command": "dotnet build Platforms/DesktopGL/Audio3D.DesktopGL.csproj",
+            "group": "build",
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "run-windows",
+            "type": "shell",
+            "command": "dotnet run --project Platforms/Windows/Audio3D.Windows.csproj",
+            "group": "test",
+            "problemMatcher": "$msCompile"
+        },
+        {
+            "label": "run-desktopgl",
+            "type": "shell",
+            "command": "dotnet run --project Platforms/DesktopGL/Audio3D.DesktopGL.csproj",
+            "group": "test",
+            "problemMatcher": "$msCompile"
+        }
+    ]
+}

+ 44 - 0
Audio3D/Audio3D.sln

@@ -0,0 +1,44 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31912.275
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3D.Core", "Core\Audio3D.Core.csproj", "{A1A1A1A1-0000-0000-0000-000000000001}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3D.Windows", "Platforms\Windows\Audio3D.Windows.csproj", "{A1A1A1A1-0000-0000-0000-000000000002}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3D.DesktopGL", "Platforms\DesktopGL\Audio3D.DesktopGL.csproj", "{A1A1A1A1-0000-0000-0000-000000000003}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3D.Android", "Platforms\Android\Audio3D.Android.csproj", "{A1A1A1A1-0000-0000-0000-000000000004}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio3D.iOS", "Platforms\iOS\Audio3D.iOS.csproj", "{A1A1A1A1-0000-0000-0000-000000000005}"
+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-000000000002}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+        {A1A1A1A1-0000-0000-0000-000000000002}.Debug|Any CPU.Build.0 = Debug|Any CPU
+        {A1A1A1A1-0000-0000-0000-000000000002}.Release|Any CPU.ActiveCfg = Release|Any CPU
+        {A1A1A1A1-0000-0000-0000-000000000002}.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}.Release|Any CPU.ActiveCfg = Release|Any CPU
+        {A1A1A1A1-0000-0000-0000-000000000003}.Release|Any CPU.Build.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}.Release|Any CPU.ActiveCfg = Release|Any CPU
+        {A1A1A1A1-0000-0000-0000-000000000004}.Release|Any CPU.Build.0 = Release|Any CPU
+        {A1A1A1A1-0000-0000-0000-000000000005}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+        {A1A1A1A1-0000-0000-0000-000000000005}.Debug|Any CPU.Build.0 = Debug|Any CPU
+        {A1A1A1A1-0000-0000-0000-000000000005}.Release|Any CPU.ActiveCfg = Release|Any CPU
+        {A1A1A1A1-0000-0000-0000-000000000005}.Release|Any CPU.Build.0 = Release|Any CPU
+    EndGlobalSection
+EndGlobal
+

+ 14 - 0
Audio3D/Core/Audio3D.Core.csproj

@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <RootNamespace>Audio3D.Core</RootNamespace>
+    <AssemblyTitle>Audio3D Core</AssemblyTitle>
+    <Description>Shared game logic for Audio3D MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>CartBlanche</Company>
+    <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+</Project>

+ 189 - 0
Audio3D/Core/AudioManager.cs

@@ -0,0 +1,189 @@
+//-----------------------------------------------------------------------------
+// AudioManager.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using System.Collections.Generic;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+
+namespace Audio3D
+{
+    /// <summary>
+    /// Audio manager keeps track of what 3D sounds are playing, updating
+    /// their settings as the camera and entities move around the world, and
+    /// automatically disposing sound effect instances after they finish playing.
+    /// </summary>
+    public class AudioManager : Microsoft.Xna.Framework.GameComponent
+    {
+
+
+        // List of all the sound effects that will be loaded into this manager.
+        static string[] soundNames =
+        {
+            "CatSound0",
+            "CatSound1",
+            "CatSound2",
+            "DogSound",
+        };
+
+
+        // The listener describes the ear which is hearing 3D sounds.
+        // This is usually set to match the camera.
+        public AudioListener Listener
+        {
+            get { return listener; }
+        }
+
+        AudioListener listener = new AudioListener();
+
+
+        // The emitter describes an entity which is making a 3D sound.
+        AudioEmitter emitter = new AudioEmitter();
+
+
+        // Store all the sound effects that are available to be played.
+        Dictionary<string, SoundEffect> soundEffects = new Dictionary<string, SoundEffect>();
+
+        
+        // Keep track of all the 3D sounds that are currently playing.
+        List<ActiveSound> activeSounds = new List<ActiveSound>();
+
+
+
+
+        public AudioManager(Game game)
+            : base(game)
+        { }
+
+
+        /// <summary>
+        /// Initializes the audio manager.
+        /// </summary>
+        public override void Initialize()
+        {
+            // Set the scale for 3D audio so it matches the scale of our game world.
+            // DistanceScale controls how much sounds change volume as you move further away.
+            // DopplerScale controls how much sounds change pitch as you move past them.
+            SoundEffect.DistanceScale = 2000;
+            SoundEffect.DopplerScale = 0.1f;
+
+            // Load all the sound effects.
+            foreach (string soundName in soundNames)
+            {
+                soundEffects.Add(soundName, Game.Content.Load<SoundEffect>(soundName));
+            }
+
+            base.Initialize();
+        }
+
+
+        /// <summary>
+        /// Unloads the sound effect data.
+        /// </summary>
+        protected override void Dispose(bool disposing)
+        {
+            try
+            {
+                if (disposing)
+                {
+                    foreach (SoundEffect soundEffect in soundEffects.Values)
+                    {
+                        soundEffect.Dispose();
+                    }
+
+                    soundEffects.Clear();
+                }
+            }
+            finally
+            {
+                base.Dispose(disposing);
+            }
+        }
+
+        
+        /// <summary>
+        /// Updates the state of the 3D audio system.
+        /// </summary>
+        public override void Update(GameTime gameTime)
+        {
+            // Loop over all the currently playing 3D sounds.
+            int index = 0;
+
+            while (index < activeSounds.Count)
+            {
+                ActiveSound activeSound = activeSounds[index];
+
+                if (activeSound.Instance.State == SoundState.Stopped)
+                {
+                    // If the sound has stopped playing, dispose it.
+                    activeSound.Instance.Dispose();
+
+                    // Remove it from the active list.
+                    activeSounds.RemoveAt(index);
+                }
+                else
+                {
+                    // If the sound is still playing, update its 3D settings.
+                    Apply3D(activeSound);
+
+                    index++;
+                }
+            }
+
+            base.Update(gameTime);
+        }
+
+
+        /// <summary>
+        /// Triggers a new 3D sound.
+        /// </summary>
+        public SoundEffectInstance Play3DSound(string soundName, bool isLooped, IAudioEmitter emitter)
+        {
+            ActiveSound activeSound = new ActiveSound();
+
+            // Fill in the instance and emitter fields.
+            activeSound.Instance = soundEffects[soundName].CreateInstance();
+            activeSound.Instance.IsLooped = isLooped;
+
+            activeSound.Emitter = emitter;
+
+            // Set the 3D position of this sound, and then play it.
+            Apply3D(activeSound);
+
+            activeSound.Instance.Play();
+
+            // Remember that this sound is now active.
+            activeSounds.Add(activeSound);
+
+            return activeSound.Instance;
+        }
+
+
+        /// <summary>
+        /// Updates the position and velocity settings of a 3D sound.
+        /// </summary>
+        private void Apply3D(ActiveSound activeSound)
+        {
+            emitter.Position = activeSound.Emitter.Position;
+            emitter.Forward = activeSound.Emitter.Forward;
+            emitter.Up = activeSound.Emitter.Up;
+            emitter.Velocity = activeSound.Emitter.Velocity;
+
+            activeSound.Instance.Apply3D(listener, emitter);
+        }
+
+
+        /// <summary>
+        /// Internal helper class for keeping track of an active 3D sound,
+        /// and remembering which emitter object it is attached to.
+        /// </summary>
+        private class ActiveSound
+        {
+            public SoundEffectInstance Instance;
+            public IAudioEmitter Emitter;
+        }
+    }
+}

+ 68 - 0
Audio3D/Core/Cat.cs

@@ -0,0 +1,68 @@
+//-----------------------------------------------------------------------------
+// Cat.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using System;
+using Microsoft.Xna.Framework;
+
+namespace Audio3D
+{
+    /// <summary>
+    /// Entity class which moves in a circle and plays cat sounds.
+    /// This uses a single-shot sound, which will stop automatically
+    /// when it finishes playing. See the Dog class for an example of
+    /// using a looping sound.
+    /// </summary>
+    class Cat : SpriteEntity
+    {
+
+        // How long until we should play the next sound.
+        TimeSpan timeDelay = TimeSpan.Zero;
+
+        // Random number generator for choosing between sound variations.
+        static Random random = new Random();
+
+
+
+        /// <summary>
+        /// Updates the position of the cat, and plays sounds.
+        /// </summary>
+        public override void Update(GameTime gameTime, AudioManager audioManager)
+        {
+            // Move the cat in a big circle.
+            double time = gameTime.TotalGameTime.TotalSeconds;
+
+            float dx = (float)-Math.Cos(time);
+            float dz = (float)-Math.Sin(time);
+
+            Vector3 newPosition = new Vector3(dx, 0, dz) * 6000;
+
+            // Update entity position and velocity.
+            Velocity = newPosition - Position;
+            Position = newPosition;
+            if (Velocity == Vector3.Zero)
+                Forward = Vector3.Forward;
+            else
+                Forward = Vector3.Normalize(Velocity);
+
+            Up = Vector3.Up;
+
+            // If the time delay has run out, trigger another single-shot sound.
+            timeDelay -= gameTime.ElapsedGameTime;
+
+            if (timeDelay < TimeSpan.Zero)
+            {
+                // For variety, randomly choose between three slightly different
+                // variants of the sound (CatSound0, CatSound1, and CatSound2).
+                string soundName = "CatSound" + random.Next(3);
+
+                audioManager.Play3DSound(soundName, false, this);
+
+                timeDelay += TimeSpan.FromSeconds(1.25f);
+            }
+        }
+    }
+}

BIN
Audio3D/Core/Content/CatSound0.xnb


BIN
Audio3D/Core/Content/CatSound1.xnb


BIN
Audio3D/Core/Content/CatSound2.xnb


BIN
Audio3D/Core/Content/CatTexture.xnb


BIN
Audio3D/Core/Content/DogSound.xnb


BIN
Audio3D/Core/Content/DogTexture.xnb


BIN
Audio3D/Core/Content/checker.xnb


+ 65 - 0
Audio3D/Core/Dog.cs

@@ -0,0 +1,65 @@
+//-----------------------------------------------------------------------------
+// Dog.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Audio;
+
+namespace Audio3D
+{
+    /// Entity class which sits in one place and plays dog sounds.
+    /// This uses a looping sound, which must be explicitly stopped
+    /// to prevent it going on forever. See the Cat class for an
+    /// example of using a single-shot sound.
+    class Dog : SpriteEntity
+    {
+
+        // How long until we should start or stop the sound.
+        TimeSpan timeDelay = TimeSpan.Zero;
+
+        // The sound which is currently playing, if any.
+        SoundEffectInstance activeSound = null;
+
+
+
+        /// <summary>
+        /// Updates the position of the dog, and plays sounds.
+        /// </summary>
+        public override void Update(GameTime gameTime, AudioManager audioManager)
+        {
+            // Set the entity to a fixed position.
+            Position = new Vector3(0, 0, -4000);
+            Forward = Vector3.Forward;
+            Up = Vector3.Up;
+            Velocity = Vector3.Zero;
+
+            // If the time delay has run out, start or stop the looping sound.
+            // This would normally go on forever, but we stop it after a six
+            // second delay, then start it up again after four more seconds.
+            timeDelay -= gameTime.ElapsedGameTime;
+
+            if (timeDelay < TimeSpan.Zero)
+            {
+                if (activeSound == null)
+                {
+                    // If no sound is currently playing, trigger one.
+                    activeSound = audioManager.Play3DSound("DogSound", true, this);
+
+                    timeDelay += TimeSpan.FromSeconds(6);
+                }
+                else
+                {
+                    // Otherwise stop the current sound.
+                    activeSound.Stop(false);
+                    activeSound = null;
+
+                    timeDelay += TimeSpan.FromSeconds(4);
+                }
+            }
+        }
+    }
+}

+ 192 - 0
Audio3D/Core/Game.cs

@@ -0,0 +1,192 @@
+//-----------------------------------------------------------------------------
+// Game.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
+using Microsoft.Xna.Framework.Graphics;
+using Microsoft.Xna.Framework.Input;
+
+namespace Audio3D
+{
+    /// <summary>
+    /// Sample showing how to implement 3D audio.
+    /// </summary>
+    public class Audio3DGame : Game
+    {
+
+        GraphicsDeviceManager graphics;
+
+        AudioManager audioManager;
+
+        SpriteEntity cat;
+        SpriteEntity dog;
+
+        Texture2D checkerTexture;
+
+        QuadDrawer quadDrawer;
+
+        Vector3 cameraPosition = new Vector3(0, 512, 0);
+        Vector3 cameraForward = Vector3.Forward;
+        Vector3 cameraUp = Vector3.Up;
+        Vector3 cameraVelocity = Vector3.Zero;
+
+        KeyboardState currentKeyboardState;
+        GamePadState currentGamePadState;
+
+
+
+
+        public Audio3DGame()
+        {
+            Content.RootDirectory = "Content";
+
+            graphics = new GraphicsDeviceManager(this);
+
+            audioManager = new AudioManager(this);
+
+            Components.Add(audioManager);
+
+            cat = new Cat();
+            dog = new Dog();
+        }
+
+
+        /// <summary>
+        /// Load your graphics content.
+        /// </summary>
+        protected override void LoadContent()
+        {
+            cat.Texture = Content.Load<Texture2D>("CatTexture");
+            dog.Texture = Content.Load<Texture2D>("DogTexture");
+
+            checkerTexture = Content.Load<Texture2D>("checker");
+
+            quadDrawer = new QuadDrawer(graphics.GraphicsDevice);
+        }
+
+
+
+
+
+        /// <summary>
+        /// Allows the game to run logic.
+        /// </summary>
+        protected override void Update(GameTime gameTime)
+        {
+            HandleInput();
+
+            UpdateCamera();
+
+            // Tell the AudioManager about the new camera position.
+            audioManager.Listener.Position = cameraPosition;
+            audioManager.Listener.Forward = cameraForward;
+            audioManager.Listener.Up = cameraUp;
+            audioManager.Listener.Velocity = cameraVelocity;
+
+            // Tell our game entities to move around and play sounds.
+            cat.Update(gameTime, audioManager);
+            dog.Update(gameTime, audioManager);
+
+            base.Update(gameTime);
+        }
+
+
+        /// <summary>
+        /// This is called when the game should draw itself.
+        /// </summary>
+        protected override void Draw(GameTime gameTime)
+        {
+            GraphicsDevice device = graphics.GraphicsDevice;
+
+            device.Clear(Color.CornflowerBlue);
+
+            device.BlendState = BlendState.AlphaBlend;
+
+            // Compute camera matrices.
+            Matrix view = Matrix.CreateLookAt(cameraPosition,
+                                              cameraPosition + cameraForward,
+                                              cameraUp);
+
+            Matrix projection = Matrix.CreatePerspectiveFieldOfView(1, device.Viewport.AspectRatio,
+                                                                    1, 100000);
+
+            // Draw the checkered ground polygon.
+            Matrix groundTransform = Matrix.CreateScale(20000) *
+                                     Matrix.CreateRotationX(MathHelper.PiOver2);
+
+            quadDrawer.DrawQuad(checkerTexture, 32, groundTransform, view, projection);
+
+            // Draw the game entities.
+            cat.Draw(quadDrawer, cameraPosition, view, projection);
+            dog.Draw(quadDrawer, cameraPosition, view, projection);
+
+            base.Draw(gameTime);
+        }
+
+
+
+
+
+        /// <summary>
+        /// Handles input for quitting the game.
+        /// </summary>
+        void HandleInput()
+        {
+            currentKeyboardState = Keyboard.GetState();
+            currentGamePadState = GamePad.GetState(PlayerIndex.One);
+
+            // Check for exit.
+            if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
+                currentGamePadState.Buttons.Back == ButtonState.Pressed)
+            {
+                Exit();
+            }
+        }
+
+
+        /// <summary>
+        /// Handles input for moving the camera.
+        /// </summary>
+        void UpdateCamera()
+        {
+            const float turnSpeed = 0.05f;
+            const float accelerationSpeed = 4;
+            const float frictionAmount = 0.98f;
+
+            // Turn left or right.
+            float turn = -currentGamePadState.ThumbSticks.Left.X * turnSpeed;
+
+            if (currentKeyboardState.IsKeyDown(Keys.Left))
+                turn += turnSpeed;
+
+            if (currentKeyboardState.IsKeyDown(Keys.Right))
+                turn -= turnSpeed;
+
+            cameraForward = Vector3.TransformNormal(cameraForward,
+                                                    Matrix.CreateRotationY(turn));
+
+            // Accelerate forward or backward.
+            float accel = currentGamePadState.ThumbSticks.Left.Y * accelerationSpeed;
+
+            if (currentKeyboardState.IsKeyDown(Keys.Up))
+                accel += accelerationSpeed;
+
+            if (currentKeyboardState.IsKeyDown(Keys.Down))
+                accel -= accelerationSpeed;
+
+            cameraVelocity += cameraForward * accel;
+
+            // Add velocity to the current position.
+            cameraPosition += cameraVelocity;
+
+            // Apply the friction force.
+            cameraVelocity *= frictionAmount;
+        }
+
+
+    }
+}

+ 23 - 0
Audio3D/Core/IAudioEmitter.cs

@@ -0,0 +1,23 @@
+//-----------------------------------------------------------------------------
+// IAudioEmitter.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using Microsoft.Xna.Framework;
+
+namespace Audio3D
+{
+    /// <summary>
+    /// Interface used by the AudioManager to look up the position
+    /// and velocity of entities that can emit 3D sounds.
+    /// </summary>
+    public interface IAudioEmitter
+    {
+        Vector3 Position { get; }
+        Vector3 Forward { get; }
+        Vector3 Up { get; }
+        Vector3 Velocity { get; }
+    }
+}

+ 73 - 0
Audio3D/Core/QuadDrawer.cs

@@ -0,0 +1,73 @@
+//-----------------------------------------------------------------------------
+// QuadDrawer.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Audio3D
+{
+    /// <summary>
+    /// Helper for drawing 3D quadrilaterals. This is used to draw the cat
+    /// and dog billboard sprites, and also the checkered ground polygon.
+    /// </summary>
+    class QuadDrawer
+    {
+
+        GraphicsDevice graphicsDevice;
+        AlphaTestEffect effect;
+        VertexPositionTexture[] vertices;
+
+
+
+        /// <summary>
+        /// Constructs a new quadrilateral drawing worker.
+        /// </summary>
+        public QuadDrawer(GraphicsDevice device)
+        {
+            graphicsDevice = device;
+
+            effect = new AlphaTestEffect(device);
+
+            effect.AlphaFunction = CompareFunction.Greater;
+            effect.ReferenceAlpha = 128;
+
+            // Preallocate an array of four vertices.
+            vertices = new VertexPositionTexture[4];
+
+            vertices[0].Position = new Vector3(1, 1, 0);
+            vertices[1].Position = new Vector3(-1, 1, 0);
+            vertices[2].Position = new Vector3(1, -1, 0);
+            vertices[3].Position = new Vector3(-1, -1, 0);
+        }
+
+
+        /// <summary>
+        /// Draws a quadrilateral as part of the 3D world.
+        /// </summary>
+        public void DrawQuad(Texture2D texture, float textureRepeats,
+                             Matrix world, Matrix view, Matrix projection)
+        {
+            // Set our effect to use the specified texture and camera matrices.
+            effect.Texture = texture;
+
+            effect.World = world;
+            effect.View = view;
+            effect.Projection = projection;
+
+            // Update our vertex array to use the specified number of texture repeats.
+            vertices[0].TextureCoordinate = new Vector2(0, 0);
+            vertices[1].TextureCoordinate = new Vector2(textureRepeats, 0);
+            vertices[2].TextureCoordinate = new Vector2(0, textureRepeats);
+            vertices[3].TextureCoordinate = new Vector2(textureRepeats, textureRepeats);
+
+            // Draw the quad.
+            effect.CurrentTechnique.Passes[0].Apply();
+
+            graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, vertices, 0, 2);
+        }
+    }
+}

+ 103 - 0
Audio3D/Core/SpriteEntity.cs

@@ -0,0 +1,103 @@
+//-----------------------------------------------------------------------------
+// SpriteEntity.cs
+//
+// Microsoft XNA Community Game Platform
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------------
+
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace Audio3D
+{
+    /// <summary>
+    /// Base class for game entities that are displayed as billboard sprites,
+    /// and which can emit 3D sounds. The Cat and Dog classes both derive from this.
+    /// </summary>
+    abstract class SpriteEntity : IAudioEmitter
+    {
+
+
+        /// <summary>
+        /// Gets or sets the 3D position of the entity.
+        /// </summary>
+        public Vector3 Position
+        {
+            get { return position; }
+            set { position = value; }
+        }
+
+        Vector3 position;
+
+
+        /// <summary>
+        /// Gets or sets which way the entity is facing.
+        /// </summary>
+        public Vector3 Forward
+        {
+            get { return forward; }
+            set { forward = value; }
+        }
+
+        Vector3 forward;
+
+
+        /// <summary>
+        /// Gets or sets the orientation of this entity.
+        /// </summary>
+        public Vector3 Up
+        {
+            get { return up; }
+            set { up = value; }
+        }
+
+        Vector3 up;
+
+        
+        /// <summary>
+        /// Gets or sets how fast this entity is moving.
+        /// </summary>
+        public Vector3 Velocity
+        {
+            get { return velocity; }
+            protected set { velocity = value; }
+        }
+
+        Vector3 velocity;
+
+
+        /// <summary>
+        /// Gets or sets the texture used to display this entity.
+        /// </summary>
+        public Texture2D Texture
+        {
+            get { return texture; }
+            set { texture = value; }
+        }
+
+        Texture2D texture;
+
+
+
+
+        /// <summary>
+        /// Updates the position of the entity, and allows it to play sounds.
+        /// </summary>
+        public abstract void Update(GameTime gameTime, AudioManager audioManager);
+
+
+        /// <summary>
+        /// Draws the entity as a billboard sprite.
+        /// </summary>
+        public void Draw(QuadDrawer quadDrawer, Vector3 cameraPosition,
+                         Matrix view, Matrix projection)
+        {
+            Matrix world = Matrix.CreateTranslation(0, 1, 0) *
+                           Matrix.CreateScale(800) *
+                           Matrix.CreateConstrainedBillboard(Position, cameraPosition,
+                                                             Up, null, null);
+
+            quadDrawer.DrawQuad(Texture, 1, world, view, projection);
+        }
+    }
+}

+ 18 - 0
Audio3D/Platforms/Android/AndroidManifest.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cartblanche.audio3d">
+  <application android:label="Audio3D" android:icon="@mipmap/icon">
+    <activity android:name="android.app.NativeActivity"
+              android:label="Audio3D"
+              android:configChanges="orientation|keyboardHidden|screenSize"
+              android:screenOrientation="landscape"
+              android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+  </application>
+  <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="34" />
+  <uses-feature android:glEsVersion="0x00020000" />
+  <uses-permission android:name="android.permission.INTERNET" />
+</manifest>

+ 21 - 0
Audio3D/Platforms/Android/Audio3D.Android.csproj

@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-android</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Audio3D.Android</RootNamespace>
+    <AssemblyTitle>Audio3D Android</AssemblyTitle>
+    <Description>Android platform for Audio3D MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>CartBlanche</Company>
+    <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Audio3D.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.Android" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 19 - 0
Audio3D/Platforms/Android/MainActivity.cs

@@ -0,0 +1,19 @@
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using Microsoft.Xna.Framework;
+
+namespace Audio3D.Android
+{
+    [Activity(Label = "Audio3D", MainLauncher = true, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden | ConfigChanges.ScreenSize, ScreenOrientation = ScreenOrientation.Landscape)]
+    public class MainActivity : AndroidGameActivity
+    {
+        protected override void OnCreate(Bundle bundle)
+        {
+            base.OnCreate(bundle);
+            var g = new Audio3DGame();
+            SetContentView((g.Services.GetService(typeof(View))) as View);
+            g.Run();
+        }
+    }
+}

+ 21 - 0
Audio3D/Platforms/DesktopGL/Audio3D.DesktopGL.csproj

@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0</TargetFramework>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>Audio3D.DesktopGL</RootNamespace>
+    <AssemblyTitle>Audio3D DesktopGL</AssemblyTitle>
+    <Description>DesktopGL platform for Audio3D MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>CartBlanche</Company>
+    <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Audio3D.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 14 - 0
Audio3D/Platforms/DesktopGL/Program.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Audio3D.DesktopGL
+{
+    public static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            using (var game = new Audio3DGame())
+                game.Run();
+        }
+    }
+}

+ 22 - 0
Audio3D/Platforms/Windows/Audio3D.Windows.csproj

@@ -0,0 +1,22 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-windows</TargetFramework>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>Audio3D.Windows</RootNamespace>
+    <AssemblyTitle>Audio3D Windows</AssemblyTitle>
+    <Description>Windows platform for Audio3D MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>CartBlanche</Company>
+    <UseWindowsForms>true</UseWindowsForms>
+    <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Audio3D.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.WindowsDX" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 14 - 0
Audio3D/Platforms/Windows/Program.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace Audio3D.Windows
+{
+    public static class Program
+    {
+        [STAThread]
+        static void Main()
+        {
+            using (var game = new Audio3DGame())
+                game.Run();
+        }
+    }
+}

+ 21 - 0
Audio3D/Platforms/iOS/Audio3D.iOS.csproj

@@ -0,0 +1,21 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net8.0-ios</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Audio3D.iOS</RootNamespace>
+    <AssemblyTitle>Audio3D iOS</AssemblyTitle>
+    <Description>iOS platform for Audio3D MonoGame sample.</Description>
+    <Authors>CartBlanche</Authors>
+    <Company>CartBlanche</Company>
+    <GenerateAssemblyInfo>true</GenerateAssemblyInfo>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Audio3D.Core.csproj" />
+    <PackageReference Include="MonoGame.Framework.iOS" Version="3.8.*" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="..\..\Core\Content\**\*.xnb" Link="Content\%(RecursiveDir)%(Filename)%(Extension)">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </Content>
+  </ItemGroup>
+</Project>

+ 27 - 0
Audio3D/Platforms/iOS/Info.plist

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>CFBundleDisplayName</key>
+    <string>Audio3D</string>
+    <key>CFBundleIdentifier</key>
+    <string>com.cartblanche.audio3d</string>
+    <key>CFBundleVersion</key>
+    <string>1.0</string>
+    <key>CFBundleShortVersionString</key>
+    <string>1.0</string>
+    <key>UILaunchStoryboardName</key>
+    <string>LaunchScreen</string>
+    <key>UISupportedInterfaceOrientations</key>
+    <array>
+        <string>UIInterfaceOrientationLandscapeLeft</string>
+        <string>UIInterfaceOrientationLandscapeRight</string>
+    </array>
+    <key>UIRequiredDeviceCapabilities</key>
+    <array>
+        <string>armv7</string>
+    </array>
+    <key>LSRequiresIPhoneOS</key>
+    <true/>
+</dict>
+</plist>

+ 12 - 0
Audio3D/Platforms/iOS/Program.cs

@@ -0,0 +1,12 @@
+using UIKit;
+
+namespace Audio3D.iOS
+{
+    public class Application
+    {
+        static void Main(string[] args)
+        {
+            UIApplication.Main(args, null, typeof(AppDelegate));
+        }
+    }
+}

+ 37 - 0
Audio3D/README.md

@@ -0,0 +1,37 @@
+# Audio3D MonoGame Sample
+
+This project demonstrates 3D audio using MonoGame 3.8.* and .NET 8.0. It is structured for cross-platform builds with shared code in `/Core` and platform-specific projects in `/Platforms`.
+
+## Structure
+- `/Core`: Shared game logic and assets
+- `/Platforms/Windows`: Windows-specific entry point and project
+- `/Platforms/DesktopGL`: DesktopGL-specific entry point and project
+- `/Platforms/Android`: Android-specific entry point and project
+- `/Platforms/iOS`: iOS-specific entry point and project
+
+## Building
+- **Windows & DesktopGL**: Use VSCode or Visual Studio 2022+ to open the solution and build the desired platform project.
+- **Android & iOS**: Open the solution in Visual Studio 2022+ with Xamarin/MAUI workloads installed.
+
+## Running
+- Use the provided `launch.json` and `tasks.json` for building and running from VSCode.
+- Use the solution file for Visual Studio.
+
+## Content
+- Uses pre-built `.xnb` files in `/Content`.
+
+## Requirements
+- .NET 8.0 SDK
+- MonoGame 3.8.* NuGet packages
+
+## Platforms Supported
+- Windows
+- DesktopGL
+- Android
+- iOS
+
+## Not Supported
+- Linux, MacOS, PSMobile (per MonoGame 3.8.*)
+
+---
+For more details, see the individual platform project files.

+ 7 - 0
BackgroundThreadTester/.vscode/extensions.json

@@ -0,0 +1,7 @@
+{
+    "recommendations": [
+        "ms-dotnettools.csharp",
+        "ms-dotnettools.vscode-dotnet-runtime",
+        "ms-vscode.mono-debug"
+    ]
+}

+ 67 - 0
BackgroundThreadTester/.vscode/launch.json

@@ -0,0 +1,67 @@
+{
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Launch Windows",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-windows",
+            "program": "${workspaceFolder}/bin/Debug/net8.0-windows/BackgroundThreadTester.Windows.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            "console": "internalConsole",
+            "stopAtEntry": false,
+            "requireExactSource": false,
+            "justMyCode": false,
+            "env": {
+                "DOTNET_ENVIRONMENT": "Development"
+            }
+        },
+        {
+            "name": "Launch DesktopGL",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-desktopgl", 
+            "program": "${workspaceFolder}/bin/Debug/net8.0/BackgroundThreadTester.DesktopGL.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            "console": "internalConsole",
+            "stopAtEntry": false,
+            "requireExactSource": false,
+            "justMyCode": false,
+            "env": {
+                "DOTNET_ENVIRONMENT": "Development"
+            }
+        },
+        {
+            "name": "Attach to Process",
+            "type": "coreclr",
+            "request": "attach",
+            "processId": "${command:pickProcess}"
+        },
+        {
+            "name": "Launch Windows (External Console)",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-windows",
+            "program": "${workspaceFolder}/bin/Debug/net8.0-windows/BackgroundThreadTester.Windows.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            "console": "externalTerminal",
+            "stopAtEntry": false,
+            "requireExactSource": false
+        },
+        {
+            "name": "Launch DesktopGL (External Console)",
+            "type": "coreclr",
+            "request": "launch",
+            "preLaunchTask": "build-desktopgl",
+            "program": "${workspaceFolder}/bin/Debug/net8.0/BackgroundThreadTester.DesktopGL.exe",
+            "args": [],
+            "cwd": "${workspaceFolder}",
+            "console": "externalTerminal",
+            "stopAtEntry": false,
+            "requireExactSource": false
+        }
+    ]
+}

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff