Родитель
2b733ae79c
Коммит
df51d134c0
|
@ -340,6 +340,7 @@ Copyright (C) 2014 Xamarin. All rights reserved.
|
||||||
TargetFrameworkIdentifier="$(TargetFrameworkIdentifier)"
|
TargetFrameworkIdentifier="$(TargetFrameworkIdentifier)"
|
||||||
ResourcePrefix="$(XamMacResourcePrefix)"
|
ResourcePrefix="$(XamMacResourcePrefix)"
|
||||||
SdkDevPath="$(_SdkDevPath)"
|
SdkDevPath="$(_SdkDevPath)"
|
||||||
|
SdkIsSimulator="false"
|
||||||
SdkRoot="$(_SdkRoot)"
|
SdkRoot="$(_SdkRoot)"
|
||||||
SdkVersion="$(MacOSXSdkVersion)"
|
SdkVersion="$(MacOSXSdkVersion)"
|
||||||
SourceFile="@(Metal)">
|
SourceFile="@(Metal)">
|
||||||
|
|
|
@ -33,6 +33,9 @@ namespace Xamarin.MacDev.Tasks
|
||||||
[Required]
|
[Required]
|
||||||
public string SdkVersion { get; set; }
|
public string SdkVersion { get; set; }
|
||||||
|
|
||||||
|
[Required]
|
||||||
|
public bool SdkIsSimulator { get; set; }
|
||||||
|
|
||||||
[Required]
|
[Required]
|
||||||
public string SdkRoot { get; set; }
|
public string SdkRoot { get; set; }
|
||||||
|
|
||||||
|
@ -55,13 +58,13 @@ namespace Xamarin.MacDev.Tasks
|
||||||
get {
|
get {
|
||||||
switch (PlatformFrameworkHelper.GetFramework (TargetFrameworkIdentifier)) {
|
switch (PlatformFrameworkHelper.GetFramework (TargetFrameworkIdentifier)) {
|
||||||
case PlatformFramework.WatchOS:
|
case PlatformFramework.WatchOS:
|
||||||
return "watchos";
|
return SdkIsSimulator ? "watchos-simulator" : "watchos";
|
||||||
case PlatformFramework.TVOS:
|
case PlatformFramework.TVOS:
|
||||||
return "tvos";
|
return SdkIsSimulator ? "tvos-simulator" : "tvos";
|
||||||
case PlatformFramework.MacOS:
|
case PlatformFramework.MacOS:
|
||||||
return "macosx";
|
return "macosx";
|
||||||
case PlatformFramework.iOS:
|
case PlatformFramework.iOS:
|
||||||
return "ios";
|
return SdkIsSimulator ? "iphonesimulator" : "ios";
|
||||||
default:
|
default:
|
||||||
Log.LogError ($"Unknown target framework identifier: {TargetFrameworkIdentifier}.");
|
Log.LogError ($"Unknown target framework identifier: {TargetFrameworkIdentifier}.");
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
|
|
|
@ -602,8 +602,6 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="_SmeltMetal" Condition="'$(_CanOutputAppBundle)' == 'true' And '@(Metal)' != ''" DependsOnTargets="_DetectSdkLocations">
|
<Target Name="_SmeltMetal" Condition="'$(_CanOutputAppBundle)' == 'true' And '@(Metal)' != ''" DependsOnTargets="_DetectSdkLocations">
|
||||||
<Error Condition="'$(ComputedPlatform)' == 'iPhoneSimulator'" Text="The iOS Simulator does not support metal. Build for a device instead."/>
|
|
||||||
|
|
||||||
<Metal
|
<Metal
|
||||||
SessionId="$(BuildSessionId)"
|
SessionId="$(BuildSessionId)"
|
||||||
Condition="'$(IsMacEnabled)' == 'true' and '%(Metal.Identity)' != ''"
|
Condition="'$(IsMacEnabled)' == 'true' and '%(Metal.Identity)' != ''"
|
||||||
|
@ -613,6 +611,7 @@ Copyright (C) 2013-2016 Xamarin. All rights reserved.
|
||||||
TargetFrameworkIdentifier="$(TargetFrameworkIdentifier)"
|
TargetFrameworkIdentifier="$(TargetFrameworkIdentifier)"
|
||||||
ResourcePrefix="$(IPhoneResourcePrefix)"
|
ResourcePrefix="$(IPhoneResourcePrefix)"
|
||||||
SdkDevPath="$(_SdkDevPath)"
|
SdkDevPath="$(_SdkDevPath)"
|
||||||
|
SdkIsSimulator="$(_SdkIsSimulator)"
|
||||||
SdkRoot="$(_SdkRoot)"
|
SdkRoot="$(_SdkRoot)"
|
||||||
SdkVersion="$(MtouchSdkVersion)"
|
SdkVersion="$(MtouchSdkVersion)"
|
||||||
SourceFile="@(Metal)">
|
SourceFile="@(Metal)">
|
||||||
|
|
|
@ -208,6 +208,8 @@ namespace MyMetalGame
|
||||||
// If we need a depth texture and don't have one, or if the depth texture we have is the wrong size
|
// If we need a depth texture and don't have one, or if the depth texture we have is the wrong size
|
||||||
// Then allocate one of the proper size
|
// Then allocate one of the proper size
|
||||||
MTLTextureDescriptor desc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.Depth32Float, texture.Width, texture.Height, false);
|
MTLTextureDescriptor desc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.Depth32Float, texture.Width, texture.Height, false);
|
||||||
|
if (ObjCRuntime.Runtime.Arch == ObjCRuntime.Arch.SIMULATOR)
|
||||||
|
desc.StorageMode = MTLStorageMode.Private;
|
||||||
depthTex = device.CreateTexture (desc);
|
depthTex = device.CreateTexture (desc);
|
||||||
depthTex.Label = "Depth";
|
depthTex.Label = "Depth";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyMetalGame", "MyMetalGame.csproj", "{4598E620-3F15-4F66-B01A-B7F9E45CE659}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||||
|
Release|iPhoneSimulator = Release|iPhoneSimulator
|
||||||
|
Debug|iPhone = Debug|iPhone
|
||||||
|
Release|iPhone = Release|iPhone
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{4598E620-3F15-4F66-B01A-B7F9E45CE659}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||||
|
{4598E620-3F15-4F66-B01A-B7F9E45CE659}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||||
|
{4598E620-3F15-4F66-B01A-B7F9E45CE659}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||||
|
{4598E620-3F15-4F66-B01A-B7F9E45CE659}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||||
|
{4598E620-3F15-4F66-B01A-B7F9E45CE659}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||||
|
{4598E620-3F15-4F66-B01A-B7F9E45CE659}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||||
|
{4598E620-3F15-4F66-B01A-B7F9E45CE659}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||||
|
{4598E620-3F15-4F66-B01A-B7F9E45CE659}.Release|iPhone.Build.0 = Release|iPhone
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,56 @@
|
||||||
|
using Foundation;
|
||||||
|
using UIKit;
|
||||||
|
|
||||||
|
namespace MyTVMetalGame {
|
||||||
|
// The UIApplicationDelegate for the application. This class is responsible for launching the
|
||||||
|
// User Interface of the application, as well as listening (and optionally responding) to application events from iOS.
|
||||||
|
[Register ("AppDelegate")]
|
||||||
|
public class AppDelegate : UIApplicationDelegate {
|
||||||
|
// class-level declarations
|
||||||
|
|
||||||
|
public override UIWindow Window {
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
|
||||||
|
{
|
||||||
|
// Override point for customization after application launch.
|
||||||
|
// If not required for your application you can safely delete this method
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnResignActivation (UIApplication application)
|
||||||
|
{
|
||||||
|
// Invoked when the application is about to move from active to inactive state.
|
||||||
|
// This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message)
|
||||||
|
// or when the user quits the application and it begins the transition to the background state.
|
||||||
|
// Games should use this method to pause the game.
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DidEnterBackground (UIApplication application)
|
||||||
|
{
|
||||||
|
// Use this method to release shared resources, save user data, invalidate timers and store the application state.
|
||||||
|
// If your application supports background exection this method is called instead of WillTerminate when the user quits.
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WillEnterForeground (UIApplication application)
|
||||||
|
{
|
||||||
|
// Called as part of the transiton from background to active state.
|
||||||
|
// Here you can undo many of the changes made on entering the background.
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnActivated (UIApplication application)
|
||||||
|
{
|
||||||
|
// Restart any tasks that were paused (or not yet started) while the application was inactive.
|
||||||
|
// If the application was previously in the background, optionally refresh the user interface.
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WillTerminate (UIApplication application)
|
||||||
|
{
|
||||||
|
// Called when the application is about to terminate. Save data, if needed. See also DidEnterBackground.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subtype": "retina4",
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"version": 1,
|
||||||
|
"author": "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"layers" : [
|
||||||
|
{
|
||||||
|
"filename" : "Front.imagestacklayer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Middle.imagestacklayer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Back.imagestacklayer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subtype": "retina4",
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"version": 1,
|
||||||
|
"author": "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subtype": "retina4",
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"version": 1,
|
||||||
|
"author": "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subtype": "retina4",
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"version": 1,
|
||||||
|
"author": "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"layers" : [
|
||||||
|
{
|
||||||
|
"filename" : "Front.imagestacklayer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Middle.imagestacklayer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Back.imagestacklayer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subtype": "retina4",
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"version": 1,
|
||||||
|
"author": "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subtype": "retina4",
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"version": 1,
|
||||||
|
"author": "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"assets" : [
|
||||||
|
{
|
||||||
|
"size" : "1280x768",
|
||||||
|
"idiom" : "tv",
|
||||||
|
"filename" : "App Icon - Large.imagestack",
|
||||||
|
"role" : "primary-app-icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "400x240",
|
||||||
|
"idiom" : "tv",
|
||||||
|
"filename" : "App Icon - Small.imagestack",
|
||||||
|
"role" : "primary-app-icon"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "2320x720",
|
||||||
|
"idiom" : "tv",
|
||||||
|
"filename" : "Top Shelf Image Wide.imageset",
|
||||||
|
"role" : "top-shelf-image-wide"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "1920x720",
|
||||||
|
"idiom" : "tv",
|
||||||
|
"filename" : "Top Shelf Image.imageset",
|
||||||
|
"role" : "top-shelf-image"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subtype": "retina4",
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"version": 1,
|
||||||
|
"author": "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"images": [
|
||||||
|
{
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"subtype": "retina4",
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "3x",
|
||||||
|
"idiom": "iphone"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "1x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"scale": "2x",
|
||||||
|
"idiom": "ipad"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info": {
|
||||||
|
"version": 1,
|
||||||
|
"author": "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?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>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,366 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
using CoreAnimation;
|
||||||
|
using CoreGraphics;
|
||||||
|
using Foundation;
|
||||||
|
using OpenTK;
|
||||||
|
using Metal;
|
||||||
|
using UIKit;
|
||||||
|
|
||||||
|
namespace MyTVMetalGame {
|
||||||
|
public partial class GameViewController : UIViewController {
|
||||||
|
struct Uniforms {
|
||||||
|
public Matrix4 ModelviewProjectionMatrix;
|
||||||
|
public Matrix4 NormalMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The max number of command buffers in flight
|
||||||
|
const int max_inflight_buffers = 3;
|
||||||
|
|
||||||
|
// Max API memory buffer size
|
||||||
|
const int max_bytes_per_frame = 1024 * 1024;
|
||||||
|
|
||||||
|
float [] cubeVertexData = {
|
||||||
|
// Data layout for each line below is:
|
||||||
|
// positionX, positionY, positionZ, normalX, normalY, normalZ,
|
||||||
|
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f,
|
||||||
|
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f,
|
||||||
|
|
||||||
|
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
|
||||||
|
|
||||||
|
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f,
|
||||||
|
|
||||||
|
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
|
||||||
|
|
||||||
|
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
// Layer
|
||||||
|
CAMetalLayer metalLayer;
|
||||||
|
MTLRenderPassDescriptor renderPassDescriptor;
|
||||||
|
|
||||||
|
// Controller
|
||||||
|
CADisplayLink timer;
|
||||||
|
Semaphore inflightSemaphore;
|
||||||
|
IMTLBuffer dynamicConstantBuffer;
|
||||||
|
byte constantDataBufferIndex;
|
||||||
|
|
||||||
|
// Renderer
|
||||||
|
IMTLDevice device;
|
||||||
|
IMTLCommandQueue commandQueue;
|
||||||
|
IMTLLibrary defaultLibrary;
|
||||||
|
IMTLRenderPipelineState pipelineState;
|
||||||
|
IMTLBuffer vertexBuffer;
|
||||||
|
IMTLDepthStencilState depthState;
|
||||||
|
IMTLTexture depthTex;
|
||||||
|
|
||||||
|
// Uniforms
|
||||||
|
Matrix4 projectionMatrix;
|
||||||
|
Matrix4 viewMatrix;
|
||||||
|
Uniforms uniformBuffer;
|
||||||
|
float rotation;
|
||||||
|
|
||||||
|
public GameViewController (IntPtr handle) : base (handle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ViewDidLoad ()
|
||||||
|
{
|
||||||
|
base.ViewDidLoad ();
|
||||||
|
|
||||||
|
constantDataBufferIndex = 0;
|
||||||
|
inflightSemaphore = new Semaphore (max_inflight_buffers, max_inflight_buffers);
|
||||||
|
|
||||||
|
SetupMetal ();
|
||||||
|
LoadAssets ();
|
||||||
|
|
||||||
|
timer = CADisplayLink.Create (Gameloop);
|
||||||
|
timer.FrameInterval = 1;
|
||||||
|
timer.AddToRunLoop (NSRunLoop.Main, NSRunLoop.NSDefaultRunLoopMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DidReceiveMemoryWarning ()
|
||||||
|
{
|
||||||
|
base.DidReceiveMemoryWarning ();
|
||||||
|
// Dispose of any resources that can be recreated.
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupMetal ()
|
||||||
|
{
|
||||||
|
// Find a usable device
|
||||||
|
device = MTLDevice.SystemDefault;
|
||||||
|
|
||||||
|
// Create a new command queue
|
||||||
|
commandQueue = device.CreateCommandQueue ();
|
||||||
|
|
||||||
|
// Load all the shader files with a metal file extension in the project
|
||||||
|
NSError error;
|
||||||
|
|
||||||
|
defaultLibrary = device.CreateLibrary ("default.metallib", out error);
|
||||||
|
|
||||||
|
// Setup metal layer and add as sub layer to view
|
||||||
|
metalLayer = new CAMetalLayer ();
|
||||||
|
metalLayer.Device = device;
|
||||||
|
metalLayer.PixelFormat = MTLPixelFormat.BGRA8Unorm;
|
||||||
|
|
||||||
|
// Change this to NO if the compute encoder is used as the last pass on the drawable texture
|
||||||
|
metalLayer.FramebufferOnly = true;
|
||||||
|
|
||||||
|
// Add metal layer to the views layer hierarchy
|
||||||
|
metalLayer.Frame = View.Layer.Frame;
|
||||||
|
View.Layer.AddSublayer (metalLayer);
|
||||||
|
|
||||||
|
View.Opaque = true;
|
||||||
|
View.BackgroundColor = null;
|
||||||
|
View.ContentScaleFactor = UIScreen.MainScreen.Scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadAssets ()
|
||||||
|
{
|
||||||
|
// Allocate one region of memory for the uniform buffer
|
||||||
|
dynamicConstantBuffer = device.CreateBuffer (max_bytes_per_frame, 0);
|
||||||
|
dynamicConstantBuffer.Label = "UniformBuffer";
|
||||||
|
|
||||||
|
// Load the fragment program into the library
|
||||||
|
IMTLFunction fragmentProgram = defaultLibrary.CreateFunction ("lighting_fragment");
|
||||||
|
|
||||||
|
// Load the vertex program into the library
|
||||||
|
IMTLFunction vertexProgram = defaultLibrary.CreateFunction ("lighting_vertex");
|
||||||
|
|
||||||
|
// Setup the vertex buffers
|
||||||
|
vertexBuffer = device.CreateBuffer<float> (cubeVertexData, (MTLResourceOptions)0);
|
||||||
|
vertexBuffer.Label = "Vertices";
|
||||||
|
|
||||||
|
// Create a reusable pipeline state
|
||||||
|
var pipelineStateDescriptor = new MTLRenderPipelineDescriptor {
|
||||||
|
Label = "MyPipeline",
|
||||||
|
SampleCount = 1,
|
||||||
|
VertexFunction = vertexProgram,
|
||||||
|
FragmentFunction = fragmentProgram,
|
||||||
|
DepthAttachmentPixelFormat = MTLPixelFormat.Depth32Float
|
||||||
|
};
|
||||||
|
|
||||||
|
pipelineStateDescriptor.ColorAttachments [0].PixelFormat = MTLPixelFormat.BGRA8Unorm;
|
||||||
|
|
||||||
|
NSError error;
|
||||||
|
|
||||||
|
pipelineState = device.CreateRenderPipelineState (pipelineStateDescriptor, out error);
|
||||||
|
|
||||||
|
if (pipelineState == null)
|
||||||
|
Console.WriteLine ("Failed to created pipeline state, error " + error);
|
||||||
|
|
||||||
|
var depthStateDesc = new MTLDepthStencilDescriptor {
|
||||||
|
DepthCompareFunction = MTLCompareFunction.Less,
|
||||||
|
DepthWriteEnabled = true
|
||||||
|
};
|
||||||
|
|
||||||
|
depthState = device.CreateDepthStencilState (depthStateDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupRenderPassDescriptorForTexture (IMTLTexture texture)
|
||||||
|
{
|
||||||
|
if (renderPassDescriptor == null)
|
||||||
|
renderPassDescriptor = MTLRenderPassDescriptor.CreateRenderPassDescriptor ();
|
||||||
|
|
||||||
|
renderPassDescriptor.ColorAttachments [0].Texture = texture;
|
||||||
|
renderPassDescriptor.ColorAttachments [0].LoadAction = MTLLoadAction.Clear;
|
||||||
|
renderPassDescriptor.ColorAttachments [0].ClearColor = new MTLClearColor (0.65f, 0.65f, 0.65f, 1.0f);
|
||||||
|
renderPassDescriptor.ColorAttachments [0].StoreAction = MTLStoreAction.Store;
|
||||||
|
|
||||||
|
if (depthTex == null || (depthTex.Width != texture.Width || depthTex.Height != texture.Height)) {
|
||||||
|
// If we need a depth texture and don't have one, or if the depth texture we have is the wrong size
|
||||||
|
// Then allocate one of the proper size
|
||||||
|
MTLTextureDescriptor desc = MTLTextureDescriptor.CreateTexture2DDescriptor (MTLPixelFormat.Depth32Float, texture.Width, texture.Height, false);
|
||||||
|
if (ObjCRuntime.Runtime.Arch == ObjCRuntime.Arch.SIMULATOR)
|
||||||
|
desc.StorageMode = MTLStorageMode.Private; depthTex = device.CreateTexture (desc);
|
||||||
|
depthTex.Label = "Depth";
|
||||||
|
|
||||||
|
renderPassDescriptor.DepthAttachment.Texture = depthTex;
|
||||||
|
renderPassDescriptor.DepthAttachment.LoadAction = MTLLoadAction.Clear;
|
||||||
|
renderPassDescriptor.DepthAttachment.ClearDepth = 1.0f;
|
||||||
|
renderPassDescriptor.DepthAttachment.StoreAction = MTLStoreAction.DontCare;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Render ()
|
||||||
|
{
|
||||||
|
inflightSemaphore.WaitOne ();
|
||||||
|
|
||||||
|
Update ();
|
||||||
|
|
||||||
|
// Create a new command buffer for each renderpass to the current drawable
|
||||||
|
IMTLCommandBuffer commandBuffer = commandQueue.CommandBuffer ();
|
||||||
|
commandBuffer.Label = "MyCommand";
|
||||||
|
|
||||||
|
// Obtain a drawable texture for this render pass and set up the renderpass descriptor for the command encoder to render into
|
||||||
|
ICAMetalDrawable drawable = GetCurrentDrawable ();
|
||||||
|
|
||||||
|
SetupRenderPassDescriptorForTexture (drawable.Texture);
|
||||||
|
|
||||||
|
// Create a render command encoder so we can render into something
|
||||||
|
IMTLRenderCommandEncoder renderEncoder = commandBuffer.CreateRenderCommandEncoder (renderPassDescriptor);
|
||||||
|
renderEncoder.Label = "MyRenderEncoder";
|
||||||
|
renderEncoder.SetDepthStencilState (depthState);
|
||||||
|
|
||||||
|
// Set context state
|
||||||
|
renderEncoder.PushDebugGroup ("DrawCube");
|
||||||
|
renderEncoder.SetRenderPipelineState (pipelineState);
|
||||||
|
renderEncoder.SetVertexBuffer (vertexBuffer, 0, 0);
|
||||||
|
renderEncoder.SetVertexBuffer (dynamicConstantBuffer, (nuint)(Marshal.SizeOf (typeof (Uniforms)) * constantDataBufferIndex), 1);
|
||||||
|
|
||||||
|
// Tell the render context we want to draw our primitives
|
||||||
|
renderEncoder.DrawPrimitives (MTLPrimitiveType.Triangle, 0, 36, 1);
|
||||||
|
renderEncoder.PopDebugGroup ();
|
||||||
|
|
||||||
|
// We're done encoding commands
|
||||||
|
renderEncoder.EndEncoding ();
|
||||||
|
|
||||||
|
// Call the view's completion handler which is required by the view since it will signal its semaphore and set up the next buffer
|
||||||
|
commandBuffer.AddCompletedHandler (buffer => {
|
||||||
|
drawable.Dispose ();
|
||||||
|
inflightSemaphore.Release ();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Schedule a present once the framebuffer is complete
|
||||||
|
commandBuffer.PresentDrawable (drawable);
|
||||||
|
|
||||||
|
// Finalize rendering here & push the command buffer to the GPU
|
||||||
|
commandBuffer.Commit ();
|
||||||
|
|
||||||
|
// The renderview assumes it can now increment the buffer index and that the previous index won't be touched until we cycle back around to the same index
|
||||||
|
constantDataBufferIndex = (byte)((constantDataBufferIndex + 1) % max_inflight_buffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reshape ()
|
||||||
|
{
|
||||||
|
// When reshape is called, update the view and projection matricies since this means the view orientation or size changed
|
||||||
|
var aspect = (float)(View.Bounds.Size.Width / View.Bounds.Size.Height);
|
||||||
|
projectionMatrix = CreateMatrixFromPerspective (65.0f * ((float)Math.PI / 180.0f), aspect, 0.1f, 100.0f);
|
||||||
|
|
||||||
|
viewMatrix = Matrix4.Identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update ()
|
||||||
|
{
|
||||||
|
var baseModel = Matrix4.Mult (CreateMatrixFromTranslation (0.0f, 0.0f, 5.0f), CreateMatrixFromRotation (rotation, 0.0f, 1.0f, 0.0f));
|
||||||
|
var baseMv = Matrix4.Mult (viewMatrix, baseModel);
|
||||||
|
var modelViewMatrix = Matrix4.Mult (baseMv, CreateMatrixFromRotation (rotation, 1.0f, 1.0f, 1.0f));
|
||||||
|
|
||||||
|
uniformBuffer.NormalMatrix = Matrix4.Invert (Matrix4.Transpose (modelViewMatrix));
|
||||||
|
uniformBuffer.ModelviewProjectionMatrix = Matrix4.Transpose (Matrix4.Mult (projectionMatrix, modelViewMatrix));
|
||||||
|
|
||||||
|
// Copy uniformBuffer's content into dynamicConstantBuffer.Contents
|
||||||
|
int rawsize = Marshal.SizeOf (typeof (Uniforms));
|
||||||
|
var rawdata = new byte [rawsize];
|
||||||
|
IntPtr ptr = Marshal.AllocHGlobal (rawsize);
|
||||||
|
Marshal.StructureToPtr (uniformBuffer, ptr, false);
|
||||||
|
Marshal.Copy (ptr, rawdata, 0, rawsize);
|
||||||
|
Marshal.FreeHGlobal (ptr);
|
||||||
|
|
||||||
|
Marshal.Copy (rawdata, 0, dynamicConstantBuffer.Contents + rawsize * constantDataBufferIndex, rawsize);
|
||||||
|
|
||||||
|
rotation += 0.01f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The main game loop called by the CADisplayLine timer
|
||||||
|
public void Gameloop ()
|
||||||
|
{
|
||||||
|
Render ();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called whenever view changes orientation or layout is changed
|
||||||
|
public override void ViewDidLayoutSubviews ()
|
||||||
|
{
|
||||||
|
Reshape ();
|
||||||
|
}
|
||||||
|
|
||||||
|
ICAMetalDrawable GetCurrentDrawable ()
|
||||||
|
{
|
||||||
|
ICAMetalDrawable currentDrawable = null;
|
||||||
|
|
||||||
|
while (currentDrawable == null) {
|
||||||
|
currentDrawable = metalLayer.NextDrawable ();
|
||||||
|
if (currentDrawable == null)
|
||||||
|
Console.WriteLine ("CurrentDrawable is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentDrawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Matrix4 CreateMatrixFromPerspective (float fovY, float aspect, float nearZ, float farZ)
|
||||||
|
{
|
||||||
|
float yscale = 1.0f / (float)Math.Tan (fovY * 0.5f);
|
||||||
|
float xscale = yscale / aspect;
|
||||||
|
float q = farZ / (farZ - nearZ);
|
||||||
|
|
||||||
|
var m = new Matrix4 {
|
||||||
|
Row0 = new Vector4 (xscale, 0.0f, 0.0f, 0.0f),
|
||||||
|
Row1 = new Vector4 (0.0f, yscale, 0.0f, 0.0f),
|
||||||
|
Row2 = new Vector4 (0.0f, 0.0f, q, q * -nearZ),
|
||||||
|
Row3 = new Vector4 (0.0f, 0.0f, 1.0f, 0.0f)
|
||||||
|
};
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Matrix4 CreateMatrixFromTranslation (float x, float y, float z)
|
||||||
|
{
|
||||||
|
var m = Matrix4.Identity;
|
||||||
|
m.Row0.W = x;
|
||||||
|
m.Row1.W = y;
|
||||||
|
m.Row2.W = z;
|
||||||
|
m.Row3.W = 1.0f;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Matrix4 CreateMatrixFromRotation (float radians, float x, float y, float z)
|
||||||
|
{
|
||||||
|
Vector3 v = Vector3.Normalize (new Vector3 (x, y, z));
|
||||||
|
var cos = (float)Math.Cos (radians);
|
||||||
|
var sin = (float)Math.Sin (radians);
|
||||||
|
float cosp = 1.0f - cos;
|
||||||
|
|
||||||
|
var m = new Matrix4 {
|
||||||
|
Row0 = new Vector4 (cos + cosp * v.X * v.X, cosp * v.X * v.Y - v.Z * sin, cosp * v.X * v.Z + v.Y * sin, 0.0f),
|
||||||
|
Row1 = new Vector4 (cosp * v.X * v.Y + v.Z * sin, cos + cosp * v.Y * v.Y, cosp * v.Y * v.Z - v.X * sin, 0.0f),
|
||||||
|
Row2 = new Vector4 (cosp * v.X * v.Z - v.Y * sin, cosp * v.Y * v.Z + v.X * sin, cos + cosp * v.Z * v.Z, 0.0f),
|
||||||
|
Row3 = new Vector4 (0.0f, 0.0f, 0.0f, 1.0f)
|
||||||
|
};
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
using Foundation;
|
||||||
|
using System.CodeDom.Compiler;
|
||||||
|
|
||||||
|
namespace MyTVMetalGame {
|
||||||
|
[Register ("GameViewController")]
|
||||||
|
partial class GameViewController {
|
||||||
|
void ReleaseDesignerOutlets ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?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>MyTVMetalGame</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>MyTVMetalGame</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.xamarin.MyTVMetalGame</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>13.0</string>
|
||||||
|
<key>UIDeviceFamily</key>
|
||||||
|
<array>
|
||||||
|
<integer>3</integer>
|
||||||
|
</array>
|
||||||
|
<key>UIMainStoryboardFile</key>
|
||||||
|
<string>Main</string>
|
||||||
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>GCSupportedGameControllers</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>ProfileName</key>
|
||||||
|
<string>ExtendedGamepad</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>ProfileName</key>
|
||||||
|
<string>MicroGamepad</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>GCSupportsControllerUserInteraction</key>
|
||||||
|
<true/>
|
||||||
|
<key>XSAppIconAssets</key>
|
||||||
|
<string>Assets.xcassets/App Icon & Top Shelf Image.brandassets</string>
|
||||||
|
<key>XSLaunchImageAssets</key>
|
||||||
|
<string>Assets.xcassets/LaunchImages.launchimage</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,13 @@
|
||||||
|
using UIKit;
|
||||||
|
|
||||||
|
namespace MyTVMetalGame {
|
||||||
|
public class Application {
|
||||||
|
// This is the main entry point of the application.
|
||||||
|
static void Main (string [] args)
|
||||||
|
{
|
||||||
|
// if you want to use a different Application Delegate class from "AppDelegate"
|
||||||
|
// you can specify it here.
|
||||||
|
UIApplication.Main (args, null, "AppDelegate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BV1-FR-VrT">
|
||||||
|
<dependencies>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--Game View Controller-->
|
||||||
|
<scene sceneID="tXr-a1-R10">
|
||||||
|
<objects>
|
||||||
|
<viewController id="BV1-FR-VrT" customClass="GameViewController" customModuleProvider="" sceneMemberID="viewController">
|
||||||
|
<layoutGuides>
|
||||||
|
<viewControllerLayoutGuide type="top" id="8aa-yV-Osq"/>
|
||||||
|
<viewControllerLayoutGuide type="bottom" id="qHh-Mt-9TT"/>
|
||||||
|
</layoutGuides>
|
||||||
|
<view key="view" contentMode="scaleToFill" id="3se-qz-xqx">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="SZV-WD-TEh" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
|
@ -0,0 +1,125 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
|
||||||
|
<ProjectGuid>{CE09F37A-C1E9-488D-B72D-26269D735ECD}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{06FA79CB-D6CD-4721-BB4B-1BD202089C55};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<RootNamespace>MyTVMetalGame</RootNamespace>
|
||||||
|
<AssemblyName>MyTVMetalGame</AssemblyName>
|
||||||
|
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<CodesignKey>iPhone Developer</CodesignKey>
|
||||||
|
<MtouchDebug>true</MtouchDebug>
|
||||||
|
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
|
||||||
|
<MtouchFastDev>true</MtouchFastDev>
|
||||||
|
<IOSDebuggerPort>51092</IOSDebuggerPort>
|
||||||
|
<MtouchLink>None</MtouchLink>
|
||||||
|
<MtouchArch>x86_64</MtouchArch>
|
||||||
|
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\iPhone\Release</OutputPath>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<CodesignKey>iPhone Developer</CodesignKey>
|
||||||
|
<MtouchUseLlvm>true</MtouchUseLlvm>
|
||||||
|
<MtouchFloat32>true</MtouchFloat32>
|
||||||
|
<MtouchEnableBitcode>true</MtouchEnableBitcode>
|
||||||
|
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||||
|
<MtouchLink>SdkOnly</MtouchLink>
|
||||||
|
<MtouchArch>ARM64</MtouchArch>
|
||||||
|
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<CodesignKey>iPhone Developer</CodesignKey>
|
||||||
|
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
|
||||||
|
<MtouchLink>None</MtouchLink>
|
||||||
|
<MtouchArch>x86_64</MtouchArch>
|
||||||
|
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\iPhone\Debug</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<CodesignKey>iPhone Developer</CodesignKey>
|
||||||
|
<DeviceSpecificBuild>true</DeviceSpecificBuild>
|
||||||
|
<MtouchDebug>true</MtouchDebug>
|
||||||
|
<MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
|
||||||
|
<MtouchFastDev>true</MtouchFastDev>
|
||||||
|
<MtouchFloat32>true</MtouchFloat32>
|
||||||
|
<CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
|
||||||
|
<IOSDebuggerPort>39926</IOSDebuggerPort>
|
||||||
|
<MtouchLink>SdkOnly</MtouchLink>
|
||||||
|
<MtouchArch>ARM64</MtouchArch>
|
||||||
|
<MtouchHttpClientHandler>NSUrlSessionHandler</MtouchHttpClientHandler>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="Xamarin.TVOS" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Large.imagestack\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Large.imagestack\Back.imagestacklayer\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Large.imagestack\Back.imagestacklayer\Content.imageset\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Large.imagestack\Front.imagestacklayer\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Large.imagestack\Front.imagestacklayer\Content.imageset\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Large.imagestack\Middle.imagestacklayer\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Large.imagestack\Middle.imagestacklayer\Content.imageset\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Small.imagestack\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Small.imagestack\Back.imagestacklayer\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Small.imagestack\Back.imagestacklayer\Content.imageset\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Small.imagestack\Front.imagestacklayer\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Small.imagestack\Front.imagestacklayer\Content.imageset\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Small.imagestack\Middle.imagestacklayer\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\App Icon - Small.imagestack\Middle.imagestacklayer\Content.imageset\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\Top Shelf Image Wide.imageset\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\App Icon & Top Shelf Image.brandassets\Top Shelf Image.imageset\Contents.json" />
|
||||||
|
<ImageAsset Include="Assets.xcassets\Contents.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Resources\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Metal Include="Shaders.metal" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Info.plist" />
|
||||||
|
<None Include="Entitlements.plist" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Main.cs" />
|
||||||
|
<Compile Include="AppDelegate.cs" />
|
||||||
|
<Compile Include="GameViewController.cs" />
|
||||||
|
<Compile Include="GameViewController.designer.cs">
|
||||||
|
<DependentUpon>GameViewController.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<InterfaceDefinition Include="Main.storyboard" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\TVOS\Xamarin.TVOS.CSharp.targets" />
|
||||||
|
</Project>
|
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyTVMetalGame", "MyTVMetalGame.csproj", "{CE09F37A-C1E9-488D-B72D-26269D735ECD}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|iPhoneSimulator = Debug|iPhoneSimulator
|
||||||
|
Release|iPhone = Release|iPhone
|
||||||
|
Release|iPhoneSimulator = Release|iPhoneSimulator
|
||||||
|
Debug|iPhone = Debug|iPhone
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{CE09F37A-C1E9-488D-B72D-26269D735ECD}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
|
||||||
|
{CE09F37A-C1E9-488D-B72D-26269D735ECD}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
|
||||||
|
{CE09F37A-C1E9-488D-B72D-26269D735ECD}.Release|iPhone.ActiveCfg = Release|iPhone
|
||||||
|
{CE09F37A-C1E9-488D-B72D-26269D735ECD}.Release|iPhone.Build.0 = Release|iPhone
|
||||||
|
{CE09F37A-C1E9-488D-B72D-26269D735ECD}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
|
||||||
|
{CE09F37A-C1E9-488D-B72D-26269D735ECD}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
|
||||||
|
{CE09F37A-C1E9-488D-B72D-26269D735ECD}.Debug|iPhone.ActiveCfg = Debug|iPhone
|
||||||
|
{CE09F37A-C1E9-488D-B72D-26269D735ECD}.Debug|iPhone.Build.0 = Debug|iPhone
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,53 @@
|
||||||
|
#include <metal_stdlib>
|
||||||
|
#include <simd/simd.h>
|
||||||
|
|
||||||
|
using namespace metal;
|
||||||
|
|
||||||
|
// Variables in constant address space
|
||||||
|
constant float3 light_position = float3(0.0, 1.0, -1.0);
|
||||||
|
constant float4 ambient_color = float4(0.18, 0.24, 0.8, 1.0);
|
||||||
|
constant float4 diffuse_color = float4(0.4, 0.4, 1.0, 1.0);
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float4x4 modelview_projection_matrix;
|
||||||
|
float4x4 normal_matrix;
|
||||||
|
} uniforms_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
packed_float3 position;
|
||||||
|
packed_float3 normal;
|
||||||
|
} vertex_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float4 position [[position]];
|
||||||
|
half4 color;
|
||||||
|
} ColorInOut;
|
||||||
|
|
||||||
|
// Vertex shader function
|
||||||
|
vertex ColorInOut lighting_vertex(device vertex_t* vertex_array [[ buffer(0) ]],
|
||||||
|
constant uniforms_t& uniforms [[ buffer(1) ]],
|
||||||
|
unsigned int vid [[ vertex_id ]])
|
||||||
|
{
|
||||||
|
ColorInOut out;
|
||||||
|
|
||||||
|
float4 in_position = float4(float3(vertex_array[vid].position), 1.0);
|
||||||
|
out.position = uniforms.modelview_projection_matrix * in_position;
|
||||||
|
|
||||||
|
|
||||||
|
float3 normal = vertex_array[vid].normal;
|
||||||
|
float4 eye_normal = normalize(uniforms.normal_matrix * float4(normal, 0.0));
|
||||||
|
float n_dot_l = dot(eye_normal.rgb, normalize(light_position));
|
||||||
|
n_dot_l = fmax(0.0, n_dot_l);
|
||||||
|
|
||||||
|
out.color = half4(ambient_color + diffuse_color * n_dot_l);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fragment shader function
|
||||||
|
fragment half4 lighting_fragment(ColorInOut in [[stage_in]])
|
||||||
|
{
|
||||||
|
return in.color;
|
||||||
|
}
|
|
@ -17,13 +17,8 @@ namespace Xamarin.iOS.Tasks {
|
||||||
[Test]
|
[Test]
|
||||||
public void BasicTest ()
|
public void BasicTest ()
|
||||||
{
|
{
|
||||||
if (Platform == "iPhoneSimulator") {
|
if (Platform == "iPhoneSimulator" && Environment.OSVersion.Version.Major < 19) // Environment.OSVersion = 19.* in macOS Catalina.
|
||||||
// Note: we expect an error due to Metal not being supported on iPhoneSimulator
|
Assert.Ignore ("Metal support is not available in the simulator until macOS 10.15.");
|
||||||
// Note 2: msbuild now is aware that Metal is device-only and throws an error thus this test becomes device-only for time being
|
|
||||||
//this.BuildExtension ("MyMetalGame", "MyKeyboardExtension", Platform, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.BuildExtension ("MyMetalGame", "MyKeyboardExtension", Platform, "Debug");
|
this.BuildExtension ("MyMetalGame", "MyKeyboardExtension", Platform, "Debug");
|
||||||
this.TestStoryboardC (AppBundlePath);
|
this.TestStoryboardC (AppBundlePath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using NUnit.Framework;
|
using System;
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Xamarin.iOS.Tasks
|
namespace Xamarin.iOS.Tasks
|
||||||
{
|
{
|
||||||
|
@ -13,6 +15,8 @@ namespace Xamarin.iOS.Tasks
|
||||||
[Test]
|
[Test]
|
||||||
public void BasicTest()
|
public void BasicTest()
|
||||||
{
|
{
|
||||||
|
if (Platform == "iPhoneSimulator" && Environment.OSVersion.Version.Major < 19) // Environment.OSVersion = 19.* in macOS Catalina.
|
||||||
|
Assert.Ignore ("Metal support is not available in the simulator until macOS 10.15.");
|
||||||
BuildExtension ("MyTVApp", "MyTVServicesExtension", Platform, "Debug");
|
BuildExtension ("MyTVApp", "MyTVServicesExtension", Platform, "Debug");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace Xamarin.iOS.Tasks {
|
||||||
|
[TestFixture ("iPhone")]
|
||||||
|
[TestFixture ("iPhoneSimulator")]
|
||||||
|
public class TVMetalGameTests : ProjectTest {
|
||||||
|
public TVMetalGameTests (string platform) : base (platform)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void BasicTest ()
|
||||||
|
{
|
||||||
|
if (Platform == "iPhoneSimulator" && Environment.OSVersion.Version.Major < 19) // Environment.OSVersion = 19.* in macOS Catalina.
|
||||||
|
Assert.Ignore ("Metal support is not available in the simulator until macOS 10.15.");
|
||||||
|
BuildProject ("MyTVMetalGame", Platform, "Debug");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string TargetFrameworkIdentifier {
|
||||||
|
get {
|
||||||
|
return "Xamarin.TVOS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче