diff --git a/build/Stride.Build.props b/build/Stride.Build.props index 59262d47c..df7a57c9f 100644 --- a/build/Stride.Build.props +++ b/build/Stride.Build.props @@ -2,7 +2,7 @@ Stride - Windows + Windows;Android Direct3D11 diff --git a/deps/OpenTK/.gitignore b/deps/OpenTK/.gitignore deleted file mode 100644 index 348b3e356..000000000 --- a/deps/OpenTK/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.pdb -*.nupkg \ No newline at end of file diff --git a/deps/OpenTK/Android/OpenTK-1.1.dll b/deps/OpenTK/Android/OpenTK-1.1.dll deleted file mode 100644 index 7d6ead3ef..000000000 --- a/deps/OpenTK/Android/OpenTK-1.1.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d21d9811e85755709093f047afdd015af2407b1d09fa326e0337962993fd8412 -size 1732096 diff --git a/deps/OpenTK/CoreCLR/Linux/OpenTK.dll b/deps/OpenTK/CoreCLR/Linux/OpenTK.dll deleted file mode 100644 index db135da8e..000000000 --- a/deps/OpenTK/CoreCLR/Linux/OpenTK.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:02727386ebfacb0c7702ee9742116ccf9bebd83dced385163c59110326607a32 -size 4407808 diff --git a/deps/OpenTK/CoreCLR/Windows/OpenTK.dll b/deps/OpenTK/CoreCLR/Windows/OpenTK.dll deleted file mode 100644 index fb041afb1..000000000 --- a/deps/OpenTK/CoreCLR/Windows/OpenTK.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b72c6c6d110a9f4fbeffbe25d45172e96aea96137d881fe05b4277d7e88bd3d5 -size 4408320 diff --git a/deps/OpenTK/CoreCLR/macOS/OpenTK.dll b/deps/OpenTK/CoreCLR/macOS/OpenTK.dll deleted file mode 100644 index 1b7e7ac45..000000000 --- a/deps/OpenTK/CoreCLR/macOS/OpenTK.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f15eee117c1aa3656b3fc642bb6e79819bec9b52dfdf638f9f551b2a1241f335 -size 4407808 diff --git a/deps/OpenTK/OpenTK.dll b/deps/OpenTK/OpenTK.dll deleted file mode 100644 index 9ceff7915..000000000 --- a/deps/OpenTK/OpenTK.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e96b4f836d579244f0ee90a5603a20561417daae942a534600a62ee20fc6aca3 -size 4616192 diff --git a/deps/OpenTK/OpenTK.dll.config b/deps/OpenTK/OpenTK.dll.config deleted file mode 100644 index 7098d39e9..000000000 --- a/deps/OpenTK/OpenTK.dll.config +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/deps/OpenTK/Stride.OpenTK.nuspec b/deps/OpenTK/Stride.OpenTK.nuspec deleted file mode 100644 index 91bc32d22..000000000 --- a/deps/OpenTK/Stride.OpenTK.nuspec +++ /dev/null @@ -1,26 +0,0 @@ - - - - Stride.OpenTK - 1.0.3 - Stride contributors and OpenTK team - Stride contributors and OpenTK team - false - OpenTK for Stride - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/deps/OpenTK/build-debug.bat b/deps/OpenTK/build-debug.bat deleted file mode 100644 index 5af814a99..000000000 --- a/deps/OpenTK/build-debug.bat +++ /dev/null @@ -1,10 +0,0 @@ -@echo off - -rem If not already loaded, setup VisualStudio -if "%VisualStudioVersion%" EQ "" call "%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\vc\vcvarsall.bat" x86 - -msbuild ..\..\externals\opentk\OpenTK.sln /Property:Configuration=Debug;Platform="Any CPU" -copy ..\..\externals\opentk\Binaries\OpenTK\Debug\OpenTK.dll . -copy ..\..\externals\opentk\Binaries\OpenTK\Debug\OpenTK.pdb . -copy ..\..\externals\opentk\Binaries\OpenTK\Debug\OpenTK.GLControl.dll . -copy ..\..\externals\opentk\Binaries\OpenTK\Debug\OpenTK.GLControl.pdb . diff --git a/deps/OpenTK/build.bat b/deps/OpenTK/build.bat deleted file mode 100644 index 0e9c06ed5..000000000 --- a/deps/OpenTK/build.bat +++ /dev/null @@ -1,28 +0,0 @@ -@echo off - -rem If not already loaded, setup VisualStudio -call "%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\vc\vcvarsall.bat" x86 - -set opentk=..\..\externals\opentk - -pushd %opentk% -..\..\build\.nuget\NuGet.exe restore OpenTK.sln -..\..\build\.nuget\NuGet.exe restore source\OpenTK\OpenTK.NETStandard.csproj -popd - -REM NET Standard -msbuild %opentk%\source\OpenTK\OpenTK.NETStandard.csproj /Property:Configuration=Release;Platform="AnyCPU" -copy /Y %opentk%\Binaries\OpenTK\Release\netstandard2.0\OpenTK.dll . -copy /Y %opentk%\Binaries\OpenTK\Release\netstandard2.0\OpenTK.pdb . - -REM Android -msbuild %opentk%\OpenTK.Android.sln /Property:Configuration=Release;Platform="Any CPU" -if not exist Android mkdir Android -copy /Y %opentk%\Binaries\Android\Release\OpenTK-1.1.dll Android -copy /Y %opentk%\Binaries\Android\Release\OpenTK-1.1.dll.mdb Android - -REM iOS -msbuild %opentk%\OpenTK.iOS.sln /Property:Configuration=Release;Platform="Any CPU" -if not exist iOS mkdir iOS -copy /Y %opentk%\Binaries\iOS\Release\OpenTK-1.1.dll iOS -copy /Y %opentk%\Binaries\iOS\Release\OpenTK-1.1.dll.mdb iOS diff --git a/deps/OpenTK/checkout.bat b/deps/OpenTK/checkout.bat deleted file mode 100644 index bd3a27399..000000000 --- a/deps/OpenTK/checkout.bat +++ /dev/null @@ -1,15 +0,0 @@ -@echo OFF -setlocal -set HOME=%USERPROFILE% -CALL ..\find_git.cmd -IF NOT ERRORLEVEL 0 ( - ECHO "Could not find git.exe" - EXIT /B %ERRORLEVEL% -) -%GIT_CMD% clone git@github.com:stride3d/opentk ../../externals/opentk -b develop -if NOT ERRORLEVEL 0 pause -pushd ..\..\externals\opentk -%GIT_CMD% remote add upstream git@github.com:opentk/opentk.git -%GIT_CMD% fetch --all -popd -if NOT ERRORLEVEL 0 pause \ No newline at end of file diff --git a/deps/OpenTK/iOS/OpenTK-1.1.dll b/deps/OpenTK/iOS/OpenTK-1.1.dll deleted file mode 100644 index a2366ee94..000000000 --- a/deps/OpenTK/iOS/OpenTK-1.1.dll +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce8fb17099a496a07a4481b9663b06da7ce02f7e065fe177b82551f8b2136ba4 -size 457216 diff --git a/deps/OpenTK/iOS/link.bat b/deps/OpenTK/iOS/link.bat deleted file mode 100644 index 35a028cf6..000000000 --- a/deps/OpenTK/iOS/link.bat +++ /dev/null @@ -1,5 +0,0 @@ -pushd ..\..\..\bin\iOS-OpenGLES -..\..\deps\monolinker\monolinker -a Stride.Engine.dll -a Stride.Games.dll -a Stride.Input.dll -a Stride.Graphics.dll -p link OpenTK-1.1 -u copy -b true -d "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Xamarin.iOS\v1.0" -popd - -copy ..\..\..\bin\iOS-OpenGLES\output\OpenTK-1.1.dll . \ No newline at end of file diff --git a/deps/OpenTK/license.txt b/deps/OpenTK/license.txt deleted file mode 100644 index 61edfe258..000000000 --- a/deps/OpenTK/license.txt +++ /dev/null @@ -1,27 +0,0 @@ -Source: http://www.opentk.com/project/license - -The Open Toolkit library license -Copyright (c) 2006 - 2013 Stefanos Apostolopoulos (stapostol@gmail.com) for the Open Toolkit library. -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -Third parties -OpenTK.Platform.Windows and OpenTK.Platform.X11 include portions of the Mono class library. These portions are covered by the following license: -Copyright (c) 2004 Novell, Inc. -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -OpenTK.Compatibility includes portions of the Tao Framework library (Tao.OpenGl, Tao.OpenAl and Tao.Platform.Windows.SimpleOpenGlControl). These portions are covered by the following license: -Copyright (c) 2003-2007 Tao Framework Team -http://www.taoframework.com -All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -OpenTK.Half offers Half-to-Single and Single-to-Half conversions based on OpenEXR source code, which is covered by the following license: -Copyright (c) 2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC. All rights reserved. -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -* Neither the name of Industrial Light & Magic nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/sources/core/Stride.Core/Reflection/ModuleRuntimeHelpers.cs b/sources/core/Stride.Core/Reflection/ModuleRuntimeHelpers.cs index 8edd5c553..977d2c235 100644 --- a/sources/core/Stride.Core/Reflection/ModuleRuntimeHelpers.cs +++ b/sources/core/Stride.Core/Reflection/ModuleRuntimeHelpers.cs @@ -1,6 +1,8 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using System; +using System.Linq; using System.Reflection; using Stride.Core.Annotations; @@ -10,7 +12,16 @@ namespace Stride.Core.Reflection { public static void RunModuleConstructor([NotNull] Module module) { - System.Runtime.CompilerServices.RuntimeHelpers.RunModuleConstructor(module.ModuleHandle); + // On some platforms such as Android, ModuleHandle is not set + if (module.ModuleHandle == ModuleHandle.EmptyHandle) + { + // Instead, initialize any type + System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(module.Assembly.DefinedTypes.First().TypeHandle); + } + else + { + System.Runtime.CompilerServices.RuntimeHelpers.RunModuleConstructor(module.ModuleHandle); + } } } } diff --git a/sources/core/Stride.Core/build/Stride.Core.targets b/sources/core/Stride.Core/build/Stride.Core.targets index 05cf0eff0..9b9841a05 100644 --- a/sources/core/Stride.Core/build/Stride.Core.targets +++ b/sources/core/Stride.Core/build/Stride.Core.targets @@ -27,8 +27,10 @@ UWP - Android - iOS + Android + iOS + macOS + Linux Windows diff --git a/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/$PackageGameNameShort$Activity.cs.t4 b/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/$PackageGameNameShort$Activity.cs.t4 index 0c897ef1b..b840d3f66 100644 --- a/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/$PackageGameNameShort$Activity.cs.t4 +++ b/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/$PackageGameNameShort$Activity.cs.t4 @@ -27,12 +27,15 @@ namespace <#= Properties.Namespace #> [Activity(MainLauncher = true, Icon = "@mipmap/gameicon", ScreenOrientation = ScreenOrientation.<#= androidOrientation #>, + Theme = "@android:style/Theme.NoTitleBar", ConfigurationChanges = ConfigChanges.UiMode | ConfigChanges.Orientation | ConfigChanges.KeyboardHidden | ConfigChanges.ScreenSize)] - public class <#= Properties.PackageGameNameShort #>Activity : AndroidStrideActivity + public class <#= Properties.PackageGameNameShort #>Activity : StrideActivity { - protected override void OnCreate(Bundle bundle) + protected Game Game; + + protected override void OnRun() { - base.OnCreate(bundle); + base.OnRun(); Game = new Game(); Game.Run(GameContext); diff --git a/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/ProjectExecutable.Android.ttproj b/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/ProjectExecutable.Android.ttproj index 06f3e8377..726f3d3e5 100644 --- a/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/ProjectExecutable.Android.ttproj +++ b/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/ProjectExecutable.Android.ttproj @@ -5,3 +5,4 @@ Files: - {Source: AndroidManifest.xml.t4, Target: AndroidManifest.xml, IsTemplate: true} - {Source: Resources\mipmap-mdpi\gameicon.png, Target: Resources\mipmap-mdpi\gameicon.png } - {Source: Resources\layout\activity_main.xml, Target: Resources\layout\activity_main.xml } + - {Source: Resources\values\strings.xml, Target: Resources\values\strings.xml } diff --git a/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/Resources/Resource.Designer.cs.t4 b/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/Resources/Resource.Designer.cs.t4 deleted file mode 100644 index 19252fa37..000000000 --- a/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/Resources/Resource.Designer.cs.t4 +++ /dev/null @@ -1,7 +0,0 @@ -<#@ template inherits="ProjectTemplateTransformation" language="C#" #> -#pragma warning disable 1591 -//------------------------------------------------------------------------------ -// Build your Android project to generate this file -//------------------------------------------------------------------------------ - -#pragma warning restore 1591 diff --git a/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/Resources/values/strings.xml b/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/Resources/values/strings.xml new file mode 100644 index 000000000..6c877a39f --- /dev/null +++ b/sources/editor/Stride.Assets.Presentation/Templates/Core/ProjectExecutable.Android/Resources/values/strings.xml @@ -0,0 +1,3 @@ + + <#= Properties.PackageGameDisplayName #> + diff --git a/sources/engine/Stride.Games/Android/AndroidStrideGameView.cs b/sources/engine/Stride.Games/Android/AndroidStrideGameView.cs deleted file mode 100644 index 17e3a202f..000000000 --- a/sources/engine/Stride.Games/Android/AndroidStrideGameView.cs +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_PLATFORM_ANDROID -using System; -using Stride.Graphics; -using Stride.Graphics.OpenGL; -using Android.Content; -using OpenTK.Graphics; -using OpenTK.Platform.Android; -using OpenTK.Graphics.ES30; -using Stride.Data; -using PixelFormat = Stride.Graphics.PixelFormat; - -namespace Stride.Games.Android -{ - public class AndroidStrideGameView : AndroidGameView - { - public EventHandler OnPause; - public EventHandler OnResume; - - public AndroidStrideGameView(Context context) : base(context) - { - RequestedBackBufferFormat = PixelFormat.R8G8B8A8_UNorm; - RequestedGraphicsProfile = new [] { GraphicsProfile.Level_10_0, GraphicsProfile.Level_9_1 }; - } - - /// - /// Gets or sets the requested back buffer format. - /// - /// - /// The requested back buffer format. - /// - public PixelFormat RequestedBackBufferFormat { get; set; } - - /// - /// Gets or Sets the requested graphics profiles. - /// - /// - /// The requested graphics profiles. - /// - public GraphicsProfile[] RequestedGraphicsProfile { get; set; } - - public override void Pause() - { - base.Pause(); - - var handler = OnPause; - handler?.Invoke(this, EventArgs.Empty); - } - - public override void Resume() - { - base.Resume(); - - var handler = OnResume; - handler?.Invoke(this, EventArgs.Empty); - } - - protected override void CreateFrameBuffer() - { - ColorFormat requestedColorFormat = 32; - - switch (RequestedBackBufferFormat) - { - case PixelFormat.R8G8B8A8_UNorm: - case PixelFormat.B8G8R8A8_UNorm: - requestedColorFormat = 32; - break; - case PixelFormat.B8G8R8X8_UNorm: - requestedColorFormat = 24; - break; - case PixelFormat.B5G6R5_UNorm: - requestedColorFormat = new ColorFormat(5, 6, 5, 0); - break; - case PixelFormat.B5G5R5A1_UNorm: - requestedColorFormat = new ColorFormat(5, 5, 5, 1); - break; - default: - throw new NotSupportedException("RequestedBackBufferFormat"); - } - - // Query first the maximum supported profile, as some devices are crashing if we try to instantiate a 3.0 on a device supporting only 2.0 - var maximumVersion = GetMaximumSupportedProfile(); - - foreach (var profile in RequestedGraphicsProfile) - { - var version = OpenGLUtils.GetGLVersion(profile); - if (version > maximumVersion) - { - continue; - } - ContextRenderingApi = version; - GraphicsMode = new GraphicsMode(requestedColorFormat, 0, 0); - base.CreateFrameBuffer(); - return; - } - - throw new Exception("Unable to create a graphics context on the device. Maybe you should lower the preferred GraphicsProfile."); - } - - private GLVersion GetMaximumSupportedProfile() - { - var window = ((AndroidWindow)this.WindowInfo); - using (var context = new OpenTK.Graphics.GraphicsContext(GraphicsMode.Default, window, (int)GLVersion.ES2, 0, GraphicsContextFlags.Embedded)) - { - context.MakeCurrent(window); - - PlatformConfigurations.RendererName = GL.GetString(StringName.Renderer); - - int version; - if (!OpenGLUtils.GetCurrentGLVersion(out version)) - { - version = 200; - } - - context.MakeCurrent(null); - window.DestroySurface(); - - if (version >= 300) - { - return GLVersion.ES3; - } - return GLVersion.ES2; - } - } - } -} -#endif diff --git a/sources/engine/Stride.Games/Android/GamePlatformAndroid.cs b/sources/engine/Stride.Games/Android/GamePlatformAndroid.cs index e4954546b..3b15f220a 100644 --- a/sources/engine/Stride.Games/Android/GamePlatformAndroid.cs +++ b/sources/engine/Stride.Games/Android/GamePlatformAndroid.cs @@ -46,7 +46,7 @@ namespace Stride.Games { if (type == AppContextType.Android) { - return new GameWindowAndroid(); + return new GameWindowSDL(); } else { @@ -56,7 +56,7 @@ namespace Stride.Games public override List FindBestDevices(GameGraphicsParameters preferredParameters) { - var gameWindowAndroid = gameWindow as GameWindowAndroid; + var gameWindowAndroid = gameWindow as GameWindowSDL; if (gameWindowAndroid != null) { var graphicsAdapter = GraphicsAdapterFactory.Default; diff --git a/sources/engine/Stride.Games/Android/GameWindowAndroid.cs b/sources/engine/Stride.Games/Android/GameWindowAndroid.cs deleted file mode 100644 index 8487d68ca..000000000 --- a/sources/engine/Stride.Games/Android/GameWindowAndroid.cs +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_PLATFORM_ANDROID -using System; -using System.Diagnostics; -using System.Drawing; -using Android.App; -using Android.Content; -using Android.Content.Res; -using Android.Views; -using Android.Views.InputMethods; -using OpenTK; -using Stride.Core; -using Stride.Games.Android; -using Stride.Graphics; -using Rectangle = Stride.Core.Mathematics.Rectangle; -using OpenTK.Platform.Android; -using Configuration = Android.Content.Res.Configuration; -using Android.Hardware; -using Android.Runtime; -using Activity = Android.App.Activity; - -namespace Stride.Games -{ - /// - /// An abstract window. - /// - internal class GameWindowAndroid : GameWindow - { - public AndroidStrideGameView StrideGameForm; - private WindowHandle nativeWindow; - - public override WindowHandle NativeWindow => nativeWindow; - - public override void BeginScreenDeviceChange(bool willBeFullScreen) - { - } - - public override void EndScreenDeviceChange(int clientWidth, int clientHeight) - { - - } - - protected internal override void SetSupportedOrientations(DisplayOrientation orientations) - { - // Desktop doesn't have orientation (unless on Windows 8?) - } - - private Activity GetActivity() - { - var context = StrideGameForm.Context; - while (context is ContextWrapper) { - var activity = context as Activity; - if (activity != null) { - return activity; - } - context = ((ContextWrapper)context).BaseContext; - } - return null; - } - - protected override void Initialize(GameContext gameContext) - { - StrideGameForm = gameContext.Control; - nativeWindow = new WindowHandle(AppContextType.Android, StrideGameForm, StrideGameForm.Handle); - - StrideGameForm.Load += gameForm_Load; - StrideGameForm.OnPause += gameForm_OnPause; - StrideGameForm.OnResume += gameForm_OnResume; - StrideGameForm.RenderFrame += gameForm_RenderFrame; - StrideGameForm.Resize += gameForm_Resize; - - // Setup the initial size of the window - var width = gameContext.RequestedWidth; - if (width == 0) - { - width = StrideGameForm.Width; - } - - var height = gameContext.RequestedHeight; - if (height == 0) - { - height = StrideGameForm.Height; - } - - // Transmit requested back buffer and depth stencil formats to OpenTK - StrideGameForm.RequestedBackBufferFormat = gameContext.RequestedBackBufferFormat; - StrideGameForm.RequestedGraphicsProfile = gameContext.RequestedGraphicsProfile; - - StrideGameForm.Size = new Size(width, height); - } - - private SurfaceOrientation currentOrientation; - - private void gameForm_Resize(object sender, EventArgs e) - { - var windowManager = StrideGameForm.Context.GetSystemService(Context.WindowService).JavaCast(); - if (windowManager != null) - { - var newOrientation = windowManager.DefaultDisplay.Rotation; - - if (currentOrientation != newOrientation) - { - currentOrientation = newOrientation; - OnOrientationChanged(this, EventArgs.Empty); - } - } - } - - void gameForm_Load(object sender, EventArgs e) - { - // Call InitCallback only first time - if (InitCallback != null) - { - InitCallback(); - InitCallback = null; - } - StrideGameForm.Run(); - } - - void gameForm_OnResume(object sender, EventArgs e) - { - OnResume(); - } - - void gameForm_OnPause(object sender, EventArgs e) - { - // Hide android soft keyboard (doesn't work anymore if done during Unload) - var inputMethodManager = (InputMethodManager)PlatformAndroid.Context.GetSystemService(Context.InputMethodService); - inputMethodManager.HideSoftInputFromWindow(GameContext.Control.RootView.WindowToken, HideSoftInputFlags.None); - - OnPause(); - } - - void gameForm_RenderFrame(object sender, OpenTK.FrameEventArgs e) - { - RunCallback(); - } - - internal override void Run() - { - Debug.Assert(InitCallback != null); - Debug.Assert(RunCallback != null); - - if (StrideGameForm.GraphicsContext != null) - { - throw new NotImplementedException("Only supports not yet initialized AndroidStrideGameView."); - } - } - - /// - /// Gets or sets a value indicating whether this is visible. - /// - /// true if visible; otherwise, false. - public override bool Visible - { - get - { - return StrideGameForm.Visible; - } - set - { - StrideGameForm.Visible = value; - } - } - - protected override void SetTitle(string title) - { - StrideGameForm.Title = title; - } - - internal override void Resize(int width, int height) - { - StrideGameForm.Size = new Size(width, height); - } - - public override bool IsBorderLess - { - get - { - return true; - } - set - { - } - } - - public override bool AllowUserResizing - { - get - { - return true; - } - set - { - } - } - - public override Rectangle ClientBounds => new Rectangle(0, 0, StrideGameForm.Size.Width, StrideGameForm.Size.Height); - - public override DisplayOrientation CurrentOrientation - { - get - { - switch (currentOrientation) - { - case SurfaceOrientation.Rotation0: - return DisplayOrientation.Portrait; - case SurfaceOrientation.Rotation180: - return DisplayOrientation.Portrait; - case SurfaceOrientation.Rotation270: - return DisplayOrientation.LandscapeRight; - case SurfaceOrientation.Rotation90: - return DisplayOrientation.LandscapeLeft; - default: - throw new ArgumentOutOfRangeException(); - } - } - } - - public override bool IsMinimized => StrideGameForm.WindowState == OpenTK.WindowState.Minimized; - - public override bool Focused => StrideGameForm.WindowState != OpenTK.WindowState.Minimized; - - public override bool IsMouseVisible - { - get { return false; } - set { } - } - - protected override void Destroy() - { - if (StrideGameForm != null) - { - StrideGameForm.Load -= gameForm_Load; - StrideGameForm.OnPause -= gameForm_OnPause; - StrideGameForm.OnResume -= gameForm_OnResume; - StrideGameForm.RenderFrame -= gameForm_RenderFrame; - - if (StrideGameForm.GraphicsContext != null) - { - StrideGameForm.GraphicsContext.MakeCurrent(null); - StrideGameForm.GraphicsContext.Dispose(); - } - ((AndroidWindow)StrideGameForm.WindowInfo).TerminateDisplay(); - //strideGameForm.Close(); // bug in xamarin - StrideGameForm.Holder.RemoveCallback(StrideGameForm); - StrideGameForm.Dispose(); - StrideGameForm = null; - } - - base.Destroy(); - } - } -} - -#endif diff --git a/sources/engine/Stride.Games/GameContextAndroid.cs b/sources/engine/Stride.Games/GameContextAndroid.cs index 31df5e70c..ea9bbb294 100644 --- a/sources/engine/Stride.Games/GameContextAndroid.cs +++ b/sources/engine/Stride.Games/GameContextAndroid.cs @@ -2,19 +2,18 @@ // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. #if STRIDE_PLATFORM_ANDROID using Android.Widget; -using OpenTK.Platform.Android; -using Stride.Games.Android; +using Stride.Graphics.SDL; namespace Stride.Games { /// - /// A to use for rendering to an existing WinForm . + /// A to use for rendering to an existing . /// - public partial class GameContextAndroid : GameContext + public partial class GameContextAndroid : GameContextSDL { /// - public GameContextAndroid(AndroidStrideGameView control, RelativeLayout editTextLayout, int requestedWidth = 0, int requestedHeight = 0) - : base(control, requestedWidth, requestedHeight) + public GameContextAndroid(Window control, RelativeLayout editTextLayout) + : base(control) { EditTextLayout = editTextLayout; ContextType = AppContextType.Android; diff --git a/sources/engine/Stride.Games/Starter/AndroidStrideActivity.cs b/sources/engine/Stride.Games/Starter/AndroidStrideActivity.cs deleted file mode 100644 index 8f938ecd5..000000000 --- a/sources/engine/Stride.Games/Starter/AndroidStrideActivity.cs +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#if STRIDE_PLATFORM_ANDROID -using System; -using Android.App; -using Android.Graphics; -using Android.OS; -using Android.Views; -using Android.Widget; -using Android.Content; -using Android.Media; -using Android.Runtime; -using OpenTK.Graphics; -using OpenTK.Platform.Android; -using Stride.Core; -using Stride.Games; -using Stride.Games.Android; -using Stride.Graphics.OpenGL; - -namespace Stride.Starter -{ - using Resource = Stride.Games.Resource; - - // NOTE: the class should implement View.IOnSystemUiVisibilityChangeListener but doing so will prevent the engine to work on Android below 3.0 (API Level 11 is mandatory). - // So the methods are implemented but the class does not implement View.IOnSystemUiVisibilityChangeListener. - // Maybe this will change when support for API Level 10 is dropped - // TODO: make this class implement View.IOnSystemUiVisibilityChangeListener when support of Android < 3.0 is dropped. - public class AndroidStrideActivity : Activity - { - /// - /// The game view, internally a SurfaceView - /// - protected AndroidStrideGameView GameView; - - /// - /// The game context of the game instance. - /// - protected GameContextAndroid GameContext; - - /// - /// The instance of the game to run. - /// - protected GameBase Game; - - private Action setFullscreenViewCallback; - private StatusBarVisibility lastVisibility; - private RelativeLayout mainLayout; - private RingerModeIntentReceiver ringerModeIntentReceiver; - - protected override void OnCreate(Bundle bundle) - { - base.OnCreate(bundle); - - // Set the android global context - if (PlatformAndroid.Context == null) - PlatformAndroid.Context = this; - - // Remove the title bar - RequestWindowFeature(WindowFeatures.NoTitle); - - // Unpack the files contained in the apk - //await VirtualFileSystem.UnpackAPK(); - - // Create the Android OpenGl view - GameView = new AndroidStrideGameView(this); - - // setup the application view and stride game context - SetupGameViewAndGameContext(); - - // set up a listener to the android ringer mode (Normal/Silent/Vibrate) - ringerModeIntentReceiver = new RingerModeIntentReceiver((AudioManager)GetSystemService(AudioService)); - RegisterReceiver(ringerModeIntentReceiver, new IntentFilter(AudioManager.RingerModeChangedAction)); - - SetFullscreenView(); - InitializeFullscreenViewCallback(); - } - - public void OnSystemUiVisibilityChange(StatusBarVisibility visibility) - { - //Log.Debug("Stride", "OnSystemUiVisibilityChange: visibility=0x{0:X8}", (int)visibility); - var diffVisibility = lastVisibility ^ visibility; - lastVisibility = visibility; - if ((((int)diffVisibility & (int)SystemUiFlags.LowProfile) != 0) && (((int)visibility & (int)SystemUiFlags.LowProfile) == 0)) - { - // visibility has changed out of low profile mode; change it back, which requires a delay to work properly: - // http://stackoverflow.com/questions/11027193/maintaining-lights-out-mode-view-setsystemuivisibility-across-restarts - RemoveFullscreenViewCallback(); - PostFullscreenViewCallback(); - } - } - - public override void OnWindowFocusChanged(bool hasFocus) - { - //Log.Debug("Stride", "OnWindowFocusChanged: hasFocus={0}", hasFocus); - base.OnWindowFocusChanged(hasFocus); - if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat) - { - // use fullscreen immersive mode - if (hasFocus) - { - SetFullscreenView(); - } - } - // TODO: uncomment this once the class implements View.IOnSystemUiVisibilityChangeListener. - /*else if (Build.VERSION.SdkInt >= BuildVersionCodes.IceCreamSandwich) - { - // use fullscreen low profile mode, with a delay - if (hasFocus) - { - RemoveFullscreenViewCallback(); - PostFullscreenViewCallback(); - } - else - { - RemoveFullscreenViewCallback(); - } - }*/ - } - - private void SetupGameViewAndGameContext() - { - // Force the format of the window color buffer (avoid conversions) - // TODO: PDX-364: depth format is currently hard coded (need to investigate how it can be transmitted) - var windowColorBufferFormat = Format.Rgba8888; - - // Set the main view of the Game - var context = PlatformAndroid.Context; - if (context != this) - { - try - { - var windowManager = context.GetSystemService(WindowService).JavaCast(); - var mainView = LayoutInflater.From(context).Inflate(Resource.Layout.Game, null); - windowManager.AddView(mainView, new WindowManagerLayoutParams(WindowManagerTypes.SystemAlert, WindowManagerFlags.Fullscreen, windowColorBufferFormat)); - mainLayout = mainView.FindViewById(Resource.Id.GameViewLayout); - } - catch (Exception) {} // don't have the Alert permissions - } - if (mainLayout == null) - { - Window.SetFormat(windowColorBufferFormat); - SetContentView(Resource.Layout.Game); - mainLayout = FindViewById(Resource.Id.GameViewLayout); - } - - // Set the content of the view - mainLayout.AddView(GameView); - - // Create the Game context - GameContext = new GameContextAndroid(GameView, FindViewById(Resource.Id.EditTextLayout)); - } - - protected override void OnPause() - { - base.OnPause(); - - UnregisterReceiver(ringerModeIntentReceiver); - - GameView?.Pause(); - } - - protected override void OnResume() - { - base.OnResume(); - - RegisterReceiver(ringerModeIntentReceiver, new IntentFilter(AudioManager.RingerModeChangedAction)); - - GameView?.Resume(); - } - - private void InitializeFullscreenViewCallback() - { - //Log.Debug("Stride", "InitializeFullscreenViewCallback"); - if ((Build.VERSION.SdkInt >= BuildVersionCodes.IceCreamSandwich) && (Build.VERSION.SdkInt < BuildVersionCodes.Kitkat)) - { - setFullscreenViewCallback = SetFullscreenView; - // TODO: uncomment this once the class implements View.IOnSystemUiVisibilityChangeListener. Right now only Kitkat supports full screen - //Window.DecorView.SetOnSystemUiVisibilityChangeListener(this); - } - } - - private void PostFullscreenViewCallback() - { - //Log.Debug("Stride", "PostFullscreenViewCallback"); - var handler = Window.DecorView.Handler; - if (handler != null) - { - // post callback with delay, which needs to be longer than transient status bar timeout, otherwise it will have no effect! - handler.PostDelayed(setFullscreenViewCallback, 4000); - } - } - - private void RemoveFullscreenViewCallback() - { - //Log.Debug("Stride", "RemoveFullscreenViewCallback"); - var handler = Window.DecorView.Handler; - if (handler != null) - { - // remove any pending callbacks - handler.RemoveCallbacks(setFullscreenViewCallback); - } - } - - private void SetFullscreenView() - { - //Log.Debug("Stride", "SetFullscreenView"); - if (Build.VERSION.SdkInt >= BuildVersionCodes.IceCreamSandwich) // http://redth.codes/such-android-api-levels-much-confuse-wow/ - { - var view = Window.DecorView; - int flags = (int)view.SystemUiVisibility; - if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBean) - { - // http://developer.android.com/training/system-ui/status.html - flags |= (int)(SystemUiFlags.Fullscreen | SystemUiFlags.LayoutFullscreen | SystemUiFlags.LayoutStable); - } - if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat) - { - // http://developer.android.com/training/system-ui/immersive.html; the only mode that can really hide the nav bar - flags |= (int)(SystemUiFlags.HideNavigation | SystemUiFlags.ImmersiveSticky | SystemUiFlags.LayoutHideNavigation); - } - else - { - // http://developer.android.com/training/system-ui/dim.html; low profile or 'lights out' mode to minimize the nav bar - flags |= (int)SystemUiFlags.LowProfile; - } - view.SystemUiVisibility = (StatusBarVisibility)flags; - } - } - - private class RingerModeIntentReceiver : BroadcastReceiver - { - private readonly AudioManager audioManager; - - private int muteCounter; - - public RingerModeIntentReceiver(AudioManager audioManager) - { - this.audioManager = audioManager; - } - - public override void OnReceive(Context context, Intent intent) - { - UpdateMusicMuteStatus(); - } - - private void UpdateMusicMuteStatus() - { - switch (audioManager.RingerMode) - { - case RingerMode.Normal: - for (int i = 0; i < muteCounter; i++) - audioManager.SetStreamMute(Stream.Music, false); - muteCounter = 0; - break; - case RingerMode.Silent: - case RingerMode.Vibrate: - audioManager.SetStreamMute(Stream.Music, true); - ++muteCounter; - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - } - } -} -#endif diff --git a/sources/engine/Stride.Games/Starter/StrideActivity.cs b/sources/engine/Stride.Games/Starter/StrideActivity.cs new file mode 100644 index 000000000..a562a2655 --- /dev/null +++ b/sources/engine/Stride.Games/Starter/StrideActivity.cs @@ -0,0 +1,107 @@ +// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +#if STRIDE_PLATFORM_ANDROID +using System; +using Android.App; +using Android.Graphics; +using Android.OS; +using Android.Views; +using Android.Widget; +using Android.Content; +using Android.Media; +using Android.Runtime; +using Stride.Core; +using Stride.Games; +using Silk.NET.Windowing.Sdl.Android; + +namespace Stride.Starter +{ + using Resource = Stride.Games.Resource; + + public abstract class StrideActivity : SilkActivity + { + /// + /// The game context of the game instance. + /// + protected GameContextAndroid GameContext; + + private StatusBarVisibility lastVisibility; + private RelativeLayout mainLayout; + private RingerModeIntentReceiver ringerModeIntentReceiver; + + protected override void OnRun() + { + // set up a listener to the android ringer mode (Normal/Silent/Vibrate) + ringerModeIntentReceiver = new RingerModeIntentReceiver((AudioManager)GetSystemService(AudioService)); + RegisterReceiver(ringerModeIntentReceiver, new IntentFilter(AudioManager.RingerModeChangedAction)); + + // Set the android global context + if (PlatformAndroid.Context == null) + PlatformAndroid.Context = this; + + // Unpack the files contained in the apk + //await VirtualFileSystem.UnpackAPK(); + + // setup the application view and stride game context + SetupGameContext(); + } + + protected virtual void SetupGameContext() + { + // Create the Game context + GameContext = new GameContextAndroid(null, FindViewById(Resource.Id.EditTextLayout)); + } + + protected override void OnPause() + { + base.OnPause(); + + UnregisterReceiver(ringerModeIntentReceiver); + } + + protected override void OnResume() + { + base.OnResume(); + + RegisterReceiver(ringerModeIntentReceiver, new IntentFilter(AudioManager.RingerModeChangedAction)); + } + + private class RingerModeIntentReceiver : BroadcastReceiver + { + private readonly AudioManager audioManager; + + private int muteCounter; + + public RingerModeIntentReceiver(AudioManager audioManager) + { + this.audioManager = audioManager; + } + + public override void OnReceive(Context context, Intent intent) + { + UpdateMusicMuteStatus(); + } + + private void UpdateMusicMuteStatus() + { + switch (audioManager.RingerMode) + { + case RingerMode.Normal: + for (int i = 0; i < muteCounter; i++) + audioManager.SetStreamMute(Stream.Music, false); + muteCounter = 0; + break; + case RingerMode.Silent: + case RingerMode.Vibrate: + audioManager.SetStreamMute(Stream.Music, true); + ++muteCounter; + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + } + } +} +#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapter.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapter.OpenGL.cs index d7f8fa3e9..1b23ed6e8 100644 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapter.OpenGL.cs +++ b/sources/engine/Stride.Graphics/OpenGL/GraphicsAdapter.OpenGL.cs @@ -11,13 +11,15 @@ namespace Stride.Graphics /// /// Provides methods to retrieve and manipulate graphics adapters. /// - public partial class GraphicsAdapter + public unsafe partial class GraphicsAdapter { private GraphicsProfile supportedGraphicsProfile; internal int OpenGLVersion; internal string OpenGLRenderer; - internal unsafe GraphicsAdapter() + internal static Silk.NET.SDL.Window* DefaultWindow; + + internal GraphicsAdapter() { outputs = new [] { new GraphicsOutput() }; @@ -28,7 +30,11 @@ namespace Stride.Graphics int versionMajor, versionMinor; var SDL = Stride.Graphics.SDL.Window.SDL; - var sdlWindow = SDL.CreateWindow("Stride Hidden OpenGL", 50, 50, 1280, 720, (uint)(WindowFlags.WindowHidden | WindowFlags.WindowOpengl)); + // Some platforms (i.e. Android) can only have a single window + var sdlWindow = DefaultWindow; + if (sdlWindow == null) + sdlWindow = SDL.CreateWindow("Stride Hidden OpenGL", 50, 50, 1280, 720, (uint)(WindowFlags.WindowHidden | WindowFlags.WindowOpengl)); + using (var sdlContext = new SdlContext(SDL, sdlWindow)) using (var gl = GL.GetApi(sdlContext)) { @@ -44,7 +50,8 @@ namespace Stride.Graphics gl.GetInteger(GetPName.MajorVersion, out versionMajor); gl.GetInteger(GetPName.MinorVersion, out versionMinor); } - SDL.DestroyWindow(sdlWindow); + if (sdlWindow != DefaultWindow) + SDL.DestroyWindow(sdlWindow); // Stay close to D3D: Cut renderer after first / (ex: "GeForce 670/PCIe/SSE2") var rendererSlash = renderer.IndexOf('/'); diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsDevice.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsDevice.OpenGL.cs index f4c46d9ad..a927c6084 100644 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsDevice.OpenGL.cs +++ b/sources/engine/Stride.Graphics/OpenGL/GraphicsDevice.OpenGL.cs @@ -14,15 +14,12 @@ using Stride.Shaders; using Stride.Graphics.OpenGL; using Color4 = Stride.Core.Mathematics.Color4; #if STRIDE_PLATFORM_ANDROID -using System.Text; -using System.Runtime.InteropServices; +using Monitor = System.Threading.Monitor; #endif #if STRIDE_UI_SDL using Silk.NET.SDL; using WindowState = Stride.Graphics.SDL.FormWindowState; -#else -using WindowState = OpenTK.WindowState; #endif namespace Stride.Graphics @@ -79,10 +76,7 @@ namespace Stride.Graphics internal bool HasKhronosDebug; internal bool HasTimerQueries; -#if STRIDE_GRAPHICS_API_OPENGLES - internal bool HasKhronosDebugKHR; internal bool HasExtTextureFormatBGRA8888; -#endif private bool isFramebufferSRGB; @@ -111,17 +105,11 @@ namespace Stride.Graphics } } -#if STRIDE_PLATFORM_DESKTOP +#if STRIDE_UI_SDL private Stride.Graphics.SDL.Window gameWindow; internal IGLContext MainGraphicsContext; internal unsafe IntPtr CurrentGraphicsContext => (IntPtr)Graphics.SDL.Window.SDL.GLGetCurrentContext(); - -#elif STRIDE_PLATFORM_ANDROID - private AndroidGameView gameWindow; - - [DllImport("libEGL.dll", EntryPoint = "eglGetCurrentContext")] - internal static extern IntPtr EglGetCurrentContext(); #endif #if STRIDE_GRAPHICS_API_OPENGLES @@ -162,13 +150,6 @@ namespace Stride.Graphics { get { -#if STRIDE_PLATFORM_ANDROID - if (graphicsContext != gameWindow.GraphicsContext) - { - return GraphicsDeviceStatus.Reset; - } -#endif - // TODO implement GraphicsDeviceStatus for OpenGL return GraphicsDeviceStatus.Normal; } @@ -210,23 +191,6 @@ namespace Stride.Graphics { FrameCounter++; -#if STRIDE_PLATFORM_ANDROID - if (Workaround_Context_Tegra2_Tegra3) - { - Monitor.Enter(asyncCreationLockObject, ref asyncCreationLockTaken); - } - else - { - // On first set, check if context was not already set before, - // in which case we won't unset it during End(). - keepContextOnEnd = graphicsContextEglPtr == GraphicsDevice.EglGetCurrentContext(); - - if (keepContextOnEnd) - { - return; - } - } -#endif MainGraphicsContext.MakeCurrent(); } } @@ -243,25 +207,7 @@ namespace Stride.Graphics --contextBeginCounter; if (contextBeginCounter == 0) { -#if STRIDE_PLATFORM_ANDROID - if (Workaround_Context_Tegra2_Tegra3) - { - MainGraphicsContext.MakeCurrent(null); - - // Notify that main context can be used from now on - if (asyncCreationLockTaken) - { - Monitor.Exit(asyncCreationLockObject); - asyncCreationLockTaken = false; - } - } - else if (!keepContextOnEnd) - { - GraphicsDevice.UnbindGraphicsContext(graphicsContext); - } -#else UnbindGraphicsContext(MainGraphicsContext); -#endif } else if (contextBeginCounter < 0) { @@ -381,14 +327,9 @@ namespace Stride.Graphics internal void EnsureContextActive() { // TODO: Better checks (is active context the expected one?) -#if STRIDE_PLATFORM_ANDROID - if (EglGetCurrentContext() == IntPtr.Zero) + var context = CurrentGraphicsContext; + if (context == IntPtr.Zero) throw new InvalidOperationException("No OpenGL context bound."); -#else - var context = MainGraphicsContext.Handle; //static cannot be debugged easy - if (context == null) - throw new InvalidOperationException("No OpenGL context bound."); -#endif } public void ExecuteCommandList(CompiledCommandList commandList) @@ -711,31 +652,14 @@ namespace Stride.Graphics currentVersion = Adapter.OpenGLVersion; renderer = Adapter.OpenGLRenderer; -#if STRIDE_PLATFORM_DESKTOP - gameWindow = (Stride.Graphics.SDL.Window)windowHandle.NativeWindow; -#elif STRIDE_PLATFORM_ANDROID - gameWindow = (AndroidGameView)windowHandle.NativeWindow; +#if STRIDE_PLATFORM_ANDROID || STRIDE_PLATFORM_IOS + //gameWindow.Load += OnApplicationResumed; + //gameWindow.Unload += OnApplicationPaused; #endif - // Doesn't seems to be working on Android -#if STRIDE_PLATFORM_ANDROID || STRIDE_PLATFORM_IOS - MainGraphicsContext = gameWindow.GraphicsContext; - gameWindow.Load += OnApplicationResumed; - gameWindow.Unload += OnApplicationPaused; - - if (deviceCreationContext != null) - { - deviceCreationContext.Dispose(); - deviceCreationWindowInfo.Dispose(); - } +#if STRIDE_UI_SDL + gameWindow = (Stride.Graphics.SDL.Window)windowHandle.NativeWindow; - // Create PBuffer - ((AndroidWindow)deviceCreationWindowInfo).CreateSurface(graphicsContext.GraphicsMode.Index.Value); - - deviceCreationContext = new OpenTK.Graphics.GraphicsContext(graphicsContext.GraphicsMode, deviceCreationWindowInfo, version / 100, (version % 100) / 10, creationFlags); - - graphicsContextEglPtr = EglGetCurrentContext(); -#elif STRIDE_UI_SDL var SDL = Graphics.SDL.Window.SDL; #if STRIDE_GRAPHICS_API_OPENGLES @@ -752,8 +676,7 @@ namespace Stride.Graphics SDL.GLSetAttribute(GLattr.GLContextMajorVersion, currentVersion / 100); SDL.GLSetAttribute(GLattr.GLContextMinorVersion, (currentVersion / 10) % 10); - - MainGraphicsContext = new SdlContext(SDL, (Window*)gameWindow.SdlHandle); + MainGraphicsContext = new SdlContext(SDL, (Silk.NET.SDL.Window*)gameWindow.SdlHandle); ((SdlContext)MainGraphicsContext).Create(); if (MainGraphicsContext.Handle == IntPtr.Zero) { @@ -762,11 +685,13 @@ namespace Stride.Graphics // The context must be made current to initialize OpenGL MainGraphicsContext.MakeCurrent(); +#else +#error Creating context is only implemented for SDL #endif // Create shared context for creating graphics resources from other threads SDL.GLSetAttribute(GLattr.GLShareWithCurrentContext, 1); - deviceCreationContext = new SdlContext(SDL, (Window*)gameWindow.SdlHandle); + deviceCreationContext = new SdlContext(SDL, (Silk.NET.SDL.Window*)gameWindow.SdlHandle); ((SdlContext)deviceCreationContext).Create(); MainGraphicsContext.MakeCurrent(); @@ -839,8 +764,8 @@ namespace Stride.Graphics } #if STRIDE_PLATFORM_ANDROID || STRIDE_PLATFORM_IOS - gameWindow.Load -= OnApplicationResumed; - gameWindow.Unload -= OnApplicationPaused; + //gameWindow.Load -= OnApplicationResumed; + //gameWindow.Unload -= OnApplicationPaused; #endif } @@ -986,22 +911,6 @@ namespace Stride.Graphics } } -#if STRIDE_PLATFORM_ANDROID - // Execute pending asynchronous object creation - // (on android devices where we can't create background context such as Tegra2/Tegra3) - internal void ExecutePendingTasks() - { - // Unbind context - MainGraphicsContext.Clear(); - - // Release and reacquire lock - Monitor.Wait(asyncCreationLockObject); - - // Rebind context - MainGraphicsContext.MakeCurrent(); - } -#endif - internal struct FBOTexture : IEquatable { public readonly Texture Texture; diff --git a/sources/engine/Stride.Graphics/OpenGL/GraphicsDeviceFeatures.OpenGL.cs b/sources/engine/Stride.Graphics/OpenGL/GraphicsDeviceFeatures.OpenGL.cs index 2b0b2d56a..d336c27bb 100644 --- a/sources/engine/Stride.Graphics/OpenGL/GraphicsDeviceFeatures.OpenGL.cs +++ b/sources/engine/Stride.Graphics/OpenGL/GraphicsDeviceFeatures.OpenGL.cs @@ -116,12 +116,13 @@ namespace Stride.Graphics HasMultisampleDepthAsSRV = true; deviceRoot.HasDepthClamp = SupportedExtensions.Contains("GL_ARB_depth_clamp"); - + // TODO: from 3.1: draw indirect, separate shader object // TODO: check tessellation & geometry shaders: GL_ANDROID_extension_pack_es31a #else deviceRoot.HasDXT = SupportedExtensions.Contains("GL_EXT_texture_compression_s3tc"); deviceRoot.HasTextureBuffers = true; + deviceRoot.HasExtTextureFormatBGRA8888 = true; deviceRoot.HasKhronosDebug = deviceRoot.currentVersion >= 430 || SupportedExtensions.Contains("GL_KHR_debug"); deviceRoot.HasTimerQueries = deviceRoot.version >= 320; diff --git a/sources/engine/Stride.Graphics/OpenGL/OpenGLConvertExtensions.cs b/sources/engine/Stride.Graphics/OpenGL/OpenGLConvertExtensions.cs index ce304957a..a30cecc01 100644 --- a/sources/engine/Stride.Graphics/OpenGL/OpenGLConvertExtensions.cs +++ b/sources/engine/Stride.Graphics/OpenGL/OpenGLConvertExtensions.cs @@ -222,10 +222,8 @@ namespace Stride.Graphics pixelSize = 4; break; case PixelFormat.B8G8R8A8_UNorm: -#if STRIDE_GRAPHICS_API_OPENGLES if (!graphicsDevice.HasExtTextureFormatBGRA8888) throw new NotSupportedException(); -#endif internalFormat = (InternalFormat)PixelFormatGl.Bgra; format = PixelFormatGl.Bgra; diff --git a/sources/engine/Stride.Graphics/OpenGL/OpenGLUtils.cs b/sources/engine/Stride.Graphics/OpenGL/OpenGLUtils.cs index 6a9421281..071f68b2e 100644 --- a/sources/engine/Stride.Graphics/OpenGL/OpenGLUtils.cs +++ b/sources/engine/Stride.Graphics/OpenGL/OpenGLUtils.cs @@ -80,26 +80,6 @@ namespace Stride.Graphics.OpenGL } return GraphicsProfile.Level_9_1; } -#endif -#if STRIDE_PLATFORM_ANDROID - public static GLVersion GetGLVersion(GraphicsProfile graphicsProfile) - { - switch (graphicsProfile) - { - case GraphicsProfile.Level_9_1: - case GraphicsProfile.Level_9_2: - case GraphicsProfile.Level_9_3: - return GLVersion.ES2; - case GraphicsProfile.Level_10_0: - case GraphicsProfile.Level_10_1: - case GraphicsProfile.Level_11_0: - case GraphicsProfile.Level_11_1: - case GraphicsProfile.Level_11_2: - return GLVersion.ES3; - default: - throw new ArgumentOutOfRangeException("graphicsProfile"); - } - } #endif } } diff --git a/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.Android.cs b/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.Android.cs deleted file mode 100644 index 0f9c8becc..000000000 --- a/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.Android.cs +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_PLATFORM_ANDROID -using System; -using Stride.Core.Mathematics; -using OpenTK; -using OpenTK.Platform.Android; - -namespace Stride.Graphics -{ - public class SwapChainGraphicsPresenter : GraphicsPresenter - { - internal static Action ProcessPresentationParametersOverride; - - private AndroidGameView gameWindow; - private readonly Texture backBuffer; - private readonly GraphicsDevice graphicsDevice; - private readonly PresentationParameters startingPresentationParameters; - - public SwapChainGraphicsPresenter(GraphicsDevice device, PresentationParameters presentationParameters) : base(device, presentationParameters) - { - gameWindow = (AndroidGameView)Description.DeviceWindowHandle.NativeWindow; - - graphicsDevice = device; - startingPresentationParameters = presentationParameters; - device.InitDefaultRenderTarget(Description); - - backBuffer = Texture.New2D(device, Description.BackBufferWidth, Description.BackBufferHeight, presentationParameters.BackBufferFormat, TextureFlags.RenderTarget | TextureFlags.ShaderResource); - } - - public override Texture BackBuffer => backBuffer; - - public override object NativePresenter => null; - - public override bool IsFullScreen - { - get - { - return gameWindow.WindowState == WindowState.Fullscreen; - } - set - { - gameWindow.WindowState = value ? WindowState.Fullscreen : WindowState.Normal; - } - } - - public override void EndDraw(CommandList commandList, bool present) - { - if (present) - { - GraphicsDevice.WindowProvidedRenderTexture.InternalSetSize(gameWindow.Width, gameWindow.Height); - - // If we made a fake render target to avoid OpenGL limitations on window-provided back buffer, let's copy the rendering result to it - commandList.CopyScaler2D(backBuffer, GraphicsDevice.WindowProvidedRenderTexture, - new Rectangle(0, 0, backBuffer.Width, backBuffer.Height), - new Rectangle(0, 0, GraphicsDevice.WindowProvidedRenderTexture.Width, GraphicsDevice.WindowProvidedRenderTexture.Height), true); - - gameWindow.GraphicsContext.SwapBuffers(); - } - } - - public override void Present() - { - } - - protected override void ResizeBackBuffer(int width, int height, PixelFormat format) - { - graphicsDevice.OnDestroyed(); - - startingPresentationParameters.BackBufferWidth = width; - startingPresentationParameters.BackBufferHeight = height; - - graphicsDevice.InitDefaultRenderTarget(startingPresentationParameters); - - var newTextureDescrition = backBuffer.Description; - newTextureDescrition.Width = width; - newTextureDescrition.Height = height; - - // Manually update the texture - backBuffer.OnDestroyed(); - - // Put it in our back buffer texture - backBuffer.InitializeFrom(newTextureDescrition); - } - - protected override void ResizeDepthStencilBuffer(int width, int height, PixelFormat format) - { - var newTextureDescrition = DepthStencilBuffer.Description; - newTextureDescrition.Width = width; - newTextureDescrition.Height = height; - - // Manually update the texture - DepthStencilBuffer.OnDestroyed(); - - // Put it in our back buffer texture - DepthStencilBuffer.InitializeFrom(newTextureDescrition); - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.iOS.cs b/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenGL.cs similarity index 72% rename from sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.iOS.cs rename to sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenGL.cs index dfa93ba1f..d85966d73 100644 --- a/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.iOS.cs +++ b/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenGL.cs @@ -1,17 +1,14 @@ // Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_PLATFORM_IOS -using System.Drawing; -using OpenTK; -using OpenTK.Platform.iPhoneOS; +#if STRIDE_GRAPHICS_API_OPENGL using Rectangle = Stride.Core.Mathematics.Rectangle; - +using WindowState = Stride.Graphics.SDL.FormWindowState; +using Window = Stride.Graphics.SDL.Window; namespace Stride.Graphics { public class SwapChainGraphicsPresenter : GraphicsPresenter { - private readonly iPhoneOSGameView gameWindow; private readonly Texture backBuffer; private readonly GraphicsDevice graphicsDevice; private readonly PresentationParameters startingPresentationParameters; @@ -20,7 +17,6 @@ namespace Stride.Graphics { graphicsDevice = device; startingPresentationParameters = presentationParameters; - gameWindow = (iPhoneOSGameView)Description.DeviceWindowHandle.NativeWindow; device.InitDefaultRenderTarget(presentationParameters); backBuffer = Texture.New2D(device, Description.BackBufferWidth, Description.BackBufferHeight, presentationParameters.BackBufferFormat, TextureFlags.RenderTarget | TextureFlags.ShaderResource); @@ -34,11 +30,13 @@ namespace Stride.Graphics { get { - return gameWindow.WindowState == WindowState.Fullscreen; + return ((Window)Description.DeviceWindowHandle.NativeWindow).WindowState == WindowState.Fullscreen; } set { - gameWindow.WindowState = value ? WindowState.Fullscreen : WindowState.Normal; + var gameWindow = (Window)Description.DeviceWindowHandle.NativeWindow; + if (gameWindow.Exists) + gameWindow.WindowState = value ? WindowState.Fullscreen : WindowState.Normal; } } @@ -48,10 +46,14 @@ namespace Stride.Graphics { // If we made a fake render target to avoid OpenGL limitations on window-provided back buffer, let's copy the rendering result to it commandList.CopyScaler2D(backBuffer, GraphicsDevice.WindowProvidedRenderTexture, - new Rectangle(0, 0, backBuffer.Width, backBuffer.Height), - new Rectangle(0, 0, GraphicsDevice.WindowProvidedRenderTexture.Width, GraphicsDevice.WindowProvidedRenderTexture.Height), true); + new Rectangle(0, 0, backBuffer.Width, backBuffer.Height), + new Rectangle(0, 0, GraphicsDevice.WindowProvidedRenderTexture.Width, GraphicsDevice.WindowProvidedRenderTexture.Height), true); - gameWindow.SwapBuffers(); + // On macOS, `SwapBuffers` will swap whatever framebuffer is active and in our case it is not the window provided + // framebuffer, and in addition if the active framebuffer is single buffered, it won't do anything. Forcing a bind + // will ensure the window is updated. + commandList.GL.BindFramebuffer(FramebufferTarget.Framebuffer, GraphicsDevice.WindowProvidedFrameBuffer); + commandList.GraphicsDevice.MainGraphicsContext.SwapBuffers(); } } diff --git a/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenTK.cs b/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenTK.cs deleted file mode 100644 index c141c6ba0..000000000 --- a/sources/engine/Stride.Graphics/OpenGL/SwapChainGraphicsPresenter.OpenTK.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -#if STRIDE_PLATFORM_DESKTOP && STRIDE_GRAPHICS_API_OPENGL -using Stride.Core.Mathematics; -using Rectangle = Stride.Core.Mathematics.Rectangle; -#if STRIDE_UI_SDL -using WindowState = Stride.Graphics.SDL.FormWindowState; -using OpenGLWindow = Stride.Graphics.SDL.Window; -#else -using WindowState = OpenTK.WindowState; -using OpenGLWindow = OpenTK.GameWindow; -#endif - -namespace Stride.Graphics -{ - public class SwapChainGraphicsPresenter : GraphicsPresenter - { - private Texture backBuffer; - - public SwapChainGraphicsPresenter(GraphicsDevice device, PresentationParameters presentationParameters) : base(device, presentationParameters) - { - device.InitDefaultRenderTarget(presentationParameters); - backBuffer = Texture.New2D(device, Description.BackBufferWidth, Description.BackBufferHeight, presentationParameters.BackBufferFormat, TextureFlags.RenderTarget | TextureFlags.ShaderResource); - } - - public override Texture BackBuffer - { - get { return backBuffer; } - } - - public override object NativePresenter - { - get { return null; } - } - - public override bool IsFullScreen - { - get - { - return ((OpenGLWindow)Description.DeviceWindowHandle.NativeWindow).WindowState == WindowState.Fullscreen; - } - set - { - var gameWindow = (OpenGLWindow)Description.DeviceWindowHandle.NativeWindow; - if (gameWindow.Exists) - gameWindow.WindowState = value ? WindowState.Fullscreen : WindowState.Normal; - } - } - - public override void EndDraw(CommandList commandList, bool present) - { - if (present) - { - // If we made a fake render target to avoid OpenGL limitations on window-provided back buffer, let's copy the rendering result to it - commandList.CopyScaler2D(backBuffer, GraphicsDevice.WindowProvidedRenderTexture, - new Rectangle(0, 0, backBuffer.Width, backBuffer.Height), - new Rectangle(0, 0, GraphicsDevice.WindowProvidedRenderTexture.Width, GraphicsDevice.WindowProvidedRenderTexture.Height), true); - - // On macOS, `SwapBuffers` will swap whatever framebuffer is active and in our case it is not the window provided - // framebuffer, and in addition if the active framebuffer is single buffered, it won't do anything. Forcing a bind - // will ensure the window is updated. - commandList.GL.BindFramebuffer(FramebufferTarget.Framebuffer, GraphicsDevice.WindowProvidedFrameBuffer); - commandList.GraphicsDevice.MainGraphicsContext.SwapBuffers(); - } - } - - public override void Present() - { - } - - protected override void ResizeBackBuffer(int width, int height, PixelFormat format) - { - } - - protected override void ResizeDepthStencilBuffer(int width, int height, PixelFormat format) - { - ReleaseCurrentDepthStencilBuffer(); - } - } -} -#endif diff --git a/sources/engine/Stride.Graphics/SDL/Window.cs b/sources/engine/Stride.Graphics/SDL/Window.cs index cd77d4122..5406d2890 100644 --- a/sources/engine/Stride.Graphics/SDL/Window.cs +++ b/sources/engine/Stride.Graphics/SDL/Window.cs @@ -15,7 +15,7 @@ namespace Stride.Graphics.SDL private Silk.NET.SDL.Window* sdlHandle; - #region Initialization +#region Initialization /// /// Initializes static members of the class. @@ -39,16 +39,24 @@ namespace Stride.Graphics.SDL /// Title of the window, see Text property. public unsafe Window(string title) { + WindowFlags flags = WindowFlags.WindowAllowHighdpi; #if STRIDE_GRAPHICS_API_OPENGL - var flags = WindowFlags.WindowHidden | WindowFlags.WindowOpengl; + flags |= WindowFlags.WindowOpengl; #elif STRIDE_GRAPHICS_API_VULKAN - var flags = WindowFlags.WindowHidden | WindowFlags.WindowVulkan; + flags |= WindowFlags.WindowVulkan; +#endif +#if STRIDE_PLATFORM_ANDROID || STRIDE_PLATFORM_IOS + flags |= WindowFlags.WindowBorderless | WindowFlags.WindowFullscreen | WindowFlags.WindowShown; #else - var flags = WindowFlags.WindowHidden; + flags |= WindowFlags.WindowHidden | WindowFlags.WindowResizable; #endif // Create the SDL window and then extract the native handle. sdlHandle = SDL.CreateWindow(title, Sdl.WindowposUndefined, Sdl.WindowposUndefined, 640, 480, (uint)flags); +#if STRIDE_PLATFORM_ANDROID || STRIDE_PLATFORM_IOS + GraphicsAdapter.DefaultWindow = sdlHandle; +#endif + if (sdlHandle == null) { throw new Exception("Cannot allocate SDL Window: " + SDL.GetErrorS()); @@ -70,6 +78,11 @@ namespace Stride.Graphics.SDL Handle = (IntPtr)info.Info.X11.Window; Display = (IntPtr)info.Info.X11.Display; } + else if (Core.Platform.Type == Core.PlatformType.Android) + { + Handle = (IntPtr)info.Info.Android.Window; + Surface = (IntPtr)info.Info.Android.Surface; + } else if (Core.Platform.Type == Core.PlatformType.macOS) { Handle = (IntPtr)info.Info.Cocoa.Window; @@ -77,7 +90,7 @@ namespace Stride.Graphics.SDL Application.RegisterWindow(this); Application.ProcessEvents(); } - #endregion +#endregion /// /// Move window to back. @@ -575,6 +588,11 @@ namespace Stride.Graphics.SDL /// public IntPtr Display { get; private set; } + /// + /// Surface of current Window (valid only for Android). + /// + public IntPtr Surface { get; private set; } + /// /// The SDL window handle. /// @@ -588,7 +606,7 @@ namespace Stride.Graphics.SDL get { return SdlHandle != IntPtr.Zero; } } - #region Disposal +#region Disposal ~Window() { Dispose(false); diff --git a/sources/engine/Stride.Graphics/Stride.Graphics.csproj b/sources/engine/Stride.Graphics/Stride.Graphics.csproj index cd6ac4a01..892c9aad1 100644 --- a/sources/engine/Stride.Graphics/Stride.Graphics.csproj +++ b/sources/engine/Stride.Graphics/Stride.Graphics.csproj @@ -55,6 +55,7 @@ + diff --git a/sources/engine/Stride.Input/Android/InputSourceAndroid.cs b/sources/engine/Stride.Input/Android/InputSourceAndroid.cs index f7f8e58f7..b18abbc22 100644 --- a/sources/engine/Stride.Input/Android/InputSourceAndroid.cs +++ b/sources/engine/Stride.Input/Android/InputSourceAndroid.cs @@ -9,20 +9,15 @@ using System.Linq; using Android.Hardware; using Stride.Core.Mathematics; using Stride.Games; -using Stride.Games.Android; +using Window = Stride.Graphics.SDL.Window; namespace Stride.Input { /// - /// Provides support for pointer/keyboard/sensor input on Android + /// Provides support for sensor input on Android /// - internal class InputSourceAndroid : InputSourceBase + internal class InputSourceAndroid : InputSourceSDL { - private readonly AndroidStrideGameView uiControl; - - private KeyboardAndroid keyboard; - private PointerAndroid pointer; - private AndroidSensorListener accelerometerListener; private AndroidSensorListener gyroscopeListener; private AndroidSensorListener linearAccelerationListener; @@ -39,18 +34,13 @@ namespace Stride.Input private float[] quaternionArray = new float[4]; private float[] rotationVector = new float[3]; - public InputSourceAndroid(AndroidStrideGameView uiControl) + public InputSourceAndroid(Window uiControl) : base(uiControl) { - this.uiControl = uiControl ?? throw new ArgumentNullException(nameof(uiControl)); } public override void Initialize(InputManager inputManager) { - // Create android pointer and keyboard - keyboard = new KeyboardAndroid(this, uiControl); - pointer = new PointerAndroid(this, uiControl); - RegisterDevice(keyboard); - RegisterDevice(pointer); + base.Initialize(inputManager); // Create android sensors if ((accelerometerListener = TryGetSensorListener(SensorType.Accelerometer)) != null) @@ -171,6 +161,8 @@ namespace Stride.Input public override void Pause() { + base.Pause(); + // Disable all sensors when application is paused accelerometerListener?.Disable(); gyroscopeListener?.Disable(); diff --git a/sources/engine/Stride.Input/Android/KeyboardAndroid.cs b/sources/engine/Stride.Input/Android/KeyboardAndroid.cs deleted file mode 100644 index 0dbf8b53d..000000000 --- a/sources/engine/Stride.Input/Android/KeyboardAndroid.cs +++ /dev/null @@ -1,436 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#if STRIDE_PLATFORM_ANDROID - -using System; -using Android.Views; -using Stride.Games.Android; -using Keycode = Android.Views.Keycode; - -namespace Stride.Input -{ - internal class KeyboardAndroid : KeyboardDeviceBase, IDisposable - { - private readonly AndroidStrideGameView gameView; - - public KeyboardAndroid(InputSourceAndroid source, AndroidStrideGameView gameView) - { - Source = source; - this.gameView = gameView; - var listener = new Listener(this); - gameView.SetOnKeyListener(listener); - } - - public override string Name => "Android Keyboard"; - - public override Guid Id => new Guid("98468e4a-2895-4f87-b750-5ffe2dd943ae"); - - public override IInputSource Source { get; } - - public void Dispose() - { - gameView.SetOnKeyListener(null); - } - - protected class Listener : Java.Lang.Object, View.IOnKeyListener - { - private readonly KeyboardAndroid keyboard; - - public Listener(KeyboardAndroid keyboard) - { - this.keyboard = keyboard; - } - - public bool OnKey(View v, Keycode keyCode, Android.Views.KeyEvent e) - { - var strideKey = ConvertKeyFromAndroid(keyCode); - - if (e.Action == KeyEventActions.Down) - { - keyboard.HandleKeyDown(strideKey); - } - else - { - keyboard.HandleKeyUp(strideKey); - } - - return true; - } - - private Keys ConvertKeyFromAndroid(Keycode key) - { - switch (key) - { - case Keycode.Num0: - return Keys.D0; - case Keycode.Num1: - return Keys.D1; - case Keycode.Num2: - return Keys.D2; - case Keycode.Num3: - return Keys.D3; - case Keycode.Num4: - return Keys.D4; - case Keycode.Num5: - return Keys.D5; - case Keycode.Num6: - return Keys.D6; - case Keycode.Num7: - return Keys.D7; - case Keycode.Num8: - return Keys.D8; - case Keycode.Num9: - return Keys.D9; - case Keycode.A: - return Keys.A; - case Keycode.B: - return Keys.B; - case Keycode.C: - return Keys.C; - case Keycode.D: - return Keys.D; - case Keycode.E: - return Keys.E; - case Keycode.F: - return Keys.F; - case Keycode.G: - return Keys.G; - case Keycode.H: - return Keys.H; - case Keycode.I: - return Keys.I; - case Keycode.J: - return Keys.J; - case Keycode.K: - return Keys.K; - case Keycode.L: - return Keys.L; - case Keycode.M: - return Keys.M; - case Keycode.N: - return Keys.N; - case Keycode.O: - return Keys.O; - case Keycode.P: - return Keys.P; - case Keycode.Q: - return Keys.Q; - case Keycode.R: - return Keys.R; - case Keycode.S: - return Keys.S; - case Keycode.T: - return Keys.T; - case Keycode.U: - return Keys.U; - case Keycode.V: - return Keys.V; - case Keycode.W: - return Keys.W; - case Keycode.X: - return Keys.X; - case Keycode.Y: - return Keys.Y; - case Keycode.Z: - return Keys.Z; - case Keycode.AltLeft: - return Keys.LeftAlt; - case Keycode.AltRight: - return Keys.RightAlt; - case Keycode.ShiftLeft: - return Keys.LeftShift; - case Keycode.ShiftRight: - return Keys.RightShift; - case Keycode.Enter: - return Keys.Enter; - case Keycode.Back: - return Keys.Back; - case Keycode.Tab: - return Keys.Tab; - case Keycode.Del: - return Keys.Delete; - case Keycode.PageUp: - return Keys.PageUp; - case Keycode.PageDown: - return Keys.PageDown; - case Keycode.DpadUp: - return Keys.Up; - case Keycode.DpadDown: - return Keys.Down; - case Keycode.DpadLeft: - return Keys.Right; - case Keycode.DpadRight: - return Keys.Right; - case Keycode.CapsLock: - return Keys.CapsLock; - case Keycode.Backslash: - return Keys.OemBackslash; - case Keycode.Clear: - return Keys.Clear; - case Keycode.Comma: - return Keys.OemComma; - case Keycode.CtrlLeft: - return Keys.LeftCtrl; - case Keycode.CtrlRight: - return Keys.RightCtrl; - case Keycode.Escape: - return Keys.Escape; - case Keycode.F1: - return Keys.F1; - case Keycode.F2: - return Keys.F2; - case Keycode.F3: - return Keys.F3; - case Keycode.F4: - return Keys.F4; - case Keycode.F5: - return Keys.F5; - case Keycode.F6: - return Keys.F6; - case Keycode.F7: - return Keys.F7; - case Keycode.F8: - return Keys.F8; - case Keycode.F9: - return Keys.F9; - case Keycode.F10: - return Keys.F10; - case Keycode.F11: - return Keys.F11; - case Keycode.F12: - return Keys.F12; - case Keycode.Home: - return Keys.Home; - case Keycode.Insert: - return Keys.Insert; - case Keycode.Kana: - return Keys.KanaMode; - case Keycode.Minus: - return Keys.OemMinus; - case Keycode.Mute: - return Keys.VolumeMute; - case Keycode.NumLock: - return Keys.NumLock; - case Keycode.Numpad0: - return Keys.NumPad0; - case Keycode.Numpad1: - return Keys.NumPad1; - case Keycode.Numpad2: - return Keys.NumPad2; - case Keycode.Numpad3: - return Keys.NumPad3; - case Keycode.Numpad4: - return Keys.NumPad4; - case Keycode.Numpad5: - return Keys.NumPad5; - case Keycode.Numpad6: - return Keys.NumPad6; - case Keycode.Numpad7: - return Keys.NumPad7; - case Keycode.Numpad8: - return Keys.NumPad8; - case Keycode.Numpad9: - return Keys.NumPad9; - case Keycode.NumpadAdd: - return Keys.Add; - case Keycode.NumpadComma: - return Keys.OemComma; - case Keycode.NumpadDivide: - return Keys.Divide; - case Keycode.NumpadDot: - return Keys.NumPadDecimal; - case Keycode.NumpadEnter: - return Keys.NumPadEnter; - case Keycode.NumpadMultiply: - return Keys.Multiply; - case Keycode.NumpadSubtract: - return Keys.Subtract; - case Keycode.Period: - return Keys.OemPeriod; - case Keycode.Plus: - return Keys.OemPlus; - case Keycode.LeftBracket: - return Keys.OemOpenBrackets; - case Keycode.RightBracket: - return Keys.OemCloseBrackets; - case Keycode.Semicolon: - return Keys.OemSemicolon; - case Keycode.Sleep: - return Keys.Sleep; - case Keycode.Space: - return Keys.Space; - case Keycode.Star: - return Keys.Multiply; - case Keycode.VolumeDown: - return Keys.VolumeDown; - case Keycode.VolumeMute: - return Keys.VolumeMute; - case Keycode.VolumeUp: - return Keys.VolumeUp; - case Keycode.K11: - case Keycode.K12: - case Keycode.ThreeDMode: - case Keycode.Apostrophe: - case Keycode.AppSwitch: - case Keycode.Assist: - case Keycode.At: - case Keycode.AvrInput: - case Keycode.AvrPower: - case Keycode.Bookmark: - case Keycode.Break: - case Keycode.BrightnessDown: - case Keycode.BrightnessUp: - case Keycode.Button1: - case Keycode.Button2: - case Keycode.Button3: - case Keycode.Button4: - case Keycode.Button5: - case Keycode.Button6: - case Keycode.Button7: - case Keycode.Button8: - case Keycode.Button9: - case Keycode.Button10: - case Keycode.Button11: - case Keycode.Button12: - case Keycode.Button13: - case Keycode.Button14: - case Keycode.Button15: - case Keycode.Button16: - case Keycode.ButtonA: - case Keycode.ButtonB: - case Keycode.ButtonC: - case Keycode.ButtonL1: - case Keycode.ButtonL2: - case Keycode.ButtonMode: - case Keycode.ButtonR1: - case Keycode.ButtonR2: - case Keycode.ButtonSelect: - case Keycode.ButtonStart: - case Keycode.ButtonThumbl: - case Keycode.ButtonThumbr: - case Keycode.ButtonX: - case Keycode.ButtonY: - case Keycode.ButtonZ: - case Keycode.Calculator: - case Keycode.Calendar: - case Keycode.Call: - case Keycode.Camera: - case Keycode.Captions: - case Keycode.ChannelDown: - case Keycode.ChannelUp: - case Keycode.Contacts: - case Keycode.DpadCenter: - case Keycode.Dvr: - case Keycode.Eisu: - case Keycode.Endcall: - case Keycode.Envelope: - case Keycode.Equals: - case Keycode.Explorer: - case Keycode.Focus: - case Keycode.Forward: - case Keycode.ForwardDel: - case Keycode.Function: - case Keycode.Grave: - case Keycode.Guide: - case Keycode.Headsethook: - case Keycode.Help: - case Keycode.Henkan: - case Keycode.Info: - case Keycode.KatakanaHiragana: - case Keycode.LanguageSwitch: - case Keycode.LastChannel: - case Keycode.MannerMode: - case Keycode.MediaAudioTrack: - case Keycode.MediaClose: - case Keycode.MediaEject: - case Keycode.MediaFastForward: - case Keycode.MediaNext: - case Keycode.MediaPause: - case Keycode.MediaPlay: - case Keycode.MediaPlayPause: - case Keycode.MediaPrevious: - case Keycode.MediaRecord: - case Keycode.MediaRewind: - case Keycode.MediaStop: - case Keycode.MediaTopMenu: - case Keycode.Menu: - case Keycode.MetaLeft: - case Keycode.MetaRight: - case Keycode.MoveEnd: - case Keycode.MoveHome: - case Keycode.Muhenkan: - case Keycode.Music: - case Keycode.Notification: - case Keycode.Num: - case Keycode.NumpadEquals: - case Keycode.NumpadLeftParen: - case Keycode.NumpadRightParen: - case Keycode.Pairing: - case Keycode.Pictsymbols: - case Keycode.Pound: - case Keycode.Power: - case Keycode.ProgBlue: - case Keycode.ProgGreen: - case Keycode.ProgRed: - case Keycode.ProgYellow: - case Keycode.Ro: - case Keycode.ScrollLock: - case Keycode.Search: - case Keycode.Settings: - case Keycode.Slash: - case Keycode.SoftLeft: - case Keycode.SoftRight: - case Keycode.StbInput: - case Keycode.StbPower: - case Keycode.SwitchCharset: - case Keycode.Sym: - case Keycode.Sysrq: - case Keycode.Tv: - case Keycode.TvAntennaCable: - case Keycode.TvAudioDescription: - case Keycode.TvAudioDescriptionMixDown: - case Keycode.TvAudioDescriptionMixUp: - case Keycode.TvContentsMenu: - case Keycode.TvDataService: - case Keycode.TvInput: - case Keycode.TvInputComponent1: - case Keycode.TvInputComponent2: - case Keycode.TvInputComposite1: - case Keycode.TvInputComposite2: - case Keycode.TvInputHdmi1: - case Keycode.TvInputHdmi2: - case Keycode.TvInputHdmi3: - case Keycode.TvInputHdmi4: - case Keycode.TvInputVga1: - case Keycode.TvMediaContextMenu: - case Keycode.TvNetwork: - case Keycode.TvNumberEntry: - case Keycode.TvPower: - case Keycode.TvRadioService: - case Keycode.TvSatellite: - case Keycode.TvSatelliteBs: - case Keycode.TvSatelliteCs: - case Keycode.TvSatelliteService: - case Keycode.TvTeletext: - case Keycode.TvTerrestrialAnalog: - case Keycode.TvTerrestrialDigital: - case Keycode.TvTimerProgramming: - case Keycode.TvZoomMode: - case Keycode.Unknown: - case Keycode.VoiceAssist: - case Keycode.Wakeup: - case Keycode.Window: - case Keycode.Yen: - case Keycode.ZenkakuHankaku: - case Keycode.ZoomIn: - case Keycode.ZoomOut: - default: - return (Keys)(-1); - } - } - } - } -} - -#endif diff --git a/sources/engine/Stride.Input/Android/PointerAndroid.cs b/sources/engine/Stride.Input/Android/PointerAndroid.cs deleted file mode 100644 index 80ca05105..000000000 --- a/sources/engine/Stride.Input/Android/PointerAndroid.cs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. - -#if STRIDE_PLATFORM_ANDROID -using System; -using System.Collections.Generic; -using Android.Views; -using Stride.Core.Mathematics; -using Stride.Games.Android; - -namespace Stride.Input -{ - internal class PointerAndroid : PointerDeviceBase, IDisposable - { - private readonly AndroidStrideGameView uiControl; - - public PointerAndroid(InputSourceAndroid source, AndroidStrideGameView uiControl) - { - Source = source; - this.uiControl = uiControl; - var listener = new Listener(this); - uiControl.Resize += OnResize; - uiControl.SetOnTouchListener(listener); - - OnResize(this, null); - } - - public void Dispose() - { - uiControl.Resize -= OnResize; - uiControl.SetOnTouchListener(null); - } - - public override string Name => "Android Pointer"; - - public override Guid Id => new Guid("21370b00-aaf9-4ecf-afb2-575dde6c6c56"); - - public override IInputSource Source { get; } - - private void OnResize(object sender, EventArgs eventArgs) - { - SetSurfaceSize(new Vector2(uiControl.Size.Width, uiControl.Size.Height)); - } - - private void AddPointerEvent(PointerDeviceState.InputEvent evt) - { - PointerState.PointerInputEvents.Add(evt); - } - - protected class Listener : Java.Lang.Object, View.IOnTouchListener - { - private readonly PointerAndroid pointer; - - public Listener(PointerAndroid pointer) - { - this.pointer = pointer; - } - - public bool OnTouch(View v, MotionEvent e) - { - // Choose action type - PointerEventType actionType; - switch (e.ActionMasked) - { - case MotionEventActions.Down: - case MotionEventActions.Pointer1Down: - actionType = PointerEventType.Pressed; - break; - - case MotionEventActions.Outside: - case MotionEventActions.Cancel: - actionType = PointerEventType.Canceled; - break; - - case MotionEventActions.Up: - case MotionEventActions.Pointer1Up: - actionType = PointerEventType.Released; - break; - - default: - actionType = PointerEventType.Moved; - break; - } - - if (actionType != PointerEventType.Moved) - { - pointer.AddPointerEvent(new PointerDeviceState.InputEvent - { - Id = e.GetPointerId(e.ActionIndex), - Position = pointer.Normalize(new Vector2(e.GetX(e.ActionIndex), e.GetY(e.ActionIndex))), - Type = actionType - }); - } - else - { - for (int i = 0; i < e.PointerCount; i++) - { - pointer.AddPointerEvent(new PointerDeviceState.InputEvent - { - Id = e.GetPointerId(i), - Position = pointer.Normalize(new Vector2(e.GetX(i), e.GetY(i))), - Type = actionType - }); - } - } - - return true; - } - } - } -} -#endif diff --git a/sources/engine/Stride.Video/VideoInstance.MediaCodec.cs b/sources/engine/Stride.Video/VideoInstance.MediaCodec.cs index 268c6a427..d779646f3 100644 --- a/sources/engine/Stride.Video/VideoInstance.MediaCodec.cs +++ b/sources/engine/Stride.Video/VideoInstance.MediaCodec.cs @@ -174,7 +174,7 @@ namespace Stride.Video //The texture is set as external (GlTextureExternalOes): the mediaCodec API will create it and fill it //We don't know its size and format (size / format will depend on the media and on the device implementation) TextureExternal = Texture.NewExternalOES(GraphicsDevice); // TODO: Can we just allocate a mip mapped texture for this? - int textureId = TextureExternal.TextureId; + var textureId = (int)TextureExternal.TextureId; VideoSurfaceTexture = new SurfaceTexture(textureId); VideoSurface = new Surface(VideoSurfaceTexture); diff --git a/sources/presentation/Stride.Core.Presentation.Graph/Stride.Core.Presentation.Graph_thkfichk_wpftmp.csproj b/sources/presentation/Stride.Core.Presentation.Graph/Stride.Core.Presentation.Graph_thkfichk_wpftmp.csproj new file mode 100644 index 000000000..5efc722ab --- /dev/null +++ b/sources/presentation/Stride.Core.Presentation.Graph/Stride.Core.Presentation.Graph_thkfichk_wpftmp.csproj @@ -0,0 +1,263 @@ + + + Stride.Core.Presentation.Graph + obj\Debug\ + obj\ + C:\dev\stride\sources\presentation\Stride.Core.Presentation.Graph\obj\ + <_TargetAssemblyProjectName>Stride.Core.Presentation.Graph + + + + 8.0.30703 + 2.0 + WindowsTools + $(StrideEditorTargetFramework) + true + --auto-module-initializer --serialization + ..\..\..\..\build\ + true + true + false + + + + + + + Properties\SharedAssemblyInfo.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sources/targets/Stride.props b/sources/targets/Stride.props index 613cd02f6..b81ccec54 100644 --- a/sources/targets/Stride.props +++ b/sources/targets/Stride.props @@ -80,7 +80,7 @@ - SDL + SDL $(StrideUI);WINFORMS;WPF $(DefineConstants);STRIDE_UI_SDL