Add updated iOS App support to the Vulkan examples (#1119)
* Fix clang Objective-C++ flags for macOS command line builds * Fix getAssetPath() and getShaderBasePath() for macOS command line builds * Protect debugUtilsMessageCallback() from failing when pMessageIdName is NULL * Fix a few clang function override and mismatched type warnings * Fix validation layer warnings on exit for computeraytracing example * Fix regression in text visibility toggle for textOverlay example * Support VK_USE_PLATFORM_METAL_EXT vs. deprecated VK_USE_PLATFORM_MACOS_MVK / DVK_USE_PLATFORM_IOS_MVK * Check dynamic state features before enabling capabilities in dynamicstate example * Fix vkCmdDraw() vertexCount argument (PARTICLE_COUNT) in particlesystem example * Update examples list and restore benchmarking script (to top level) * Fix validation warning in descriptorindexing example * Fix device max recursion depth validation warnings in ray tracing examples * Fix OpenMP build settings for texture3d example on all platforms * Update and simplify build instructions for macOS * Update CI script with correct library path for libomp on macOS x86_64 * Update CI scipt to install libomp prior to macOS builds * Trying one more time to get the CI script working for macOS libomp * Fix vertexCount argument using calculated size in particlesystem example * Fix combined image descriptor offset calculation in descriptorbuffer example * Add iOS App support for Vulkan examples on simulator and physical devices * Add continuous integration (CI) script for iOS * Update CI script to build iOS using Xcode 14 via macos-12 runner-image * Update iOS project docs for Xcode 14 and rename ios folder to apple * Update macOS docs and CI script to use LIBOMP_PREFIX for OpenMP library path * Delete benchmark-all-validate.py Delete benchmark script as per feedback from Sascha Willems * Update debugprintf example documentation in examples.h
This commit is contained in:
parent
3d4446fa15
commit
ba927eab6c
38 changed files with 2755 additions and 9 deletions
16
apple/ios/AppDelegate.h
Normal file
16
apple/ios/AppDelegate.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* AppDelegate.h
|
||||
*
|
||||
* Copyright (c) 2016-2017 The Brenwill Workshop Ltd.
|
||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
@property (strong, nonatomic) UIViewController *viewController;
|
||||
|
||||
@end
|
||||
|
||||
46
apple/ios/AppDelegate.m
Normal file
46
apple/ios/AppDelegate.m
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* AppDelegate.m
|
||||
*
|
||||
* Copyright (c) 2016-2017 The Brenwill Workshop Ltd.
|
||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
#import "DemoViewController.h"
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
// Override point for customization after application launch.
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application {
|
||||
// Sent 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.
|
||||
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||||
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(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.
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
[(DemoViewController *)_viewController shutdownExample];
|
||||
}
|
||||
|
||||
@end
|
||||
26
apple/ios/DemoViewController.h
Normal file
26
apple/ios/DemoViewController.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* DemoViewController.h
|
||||
*
|
||||
* Copyright (c) 2016-2017 The Brenwill Workshop Ltd.
|
||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark DemoViewController
|
||||
|
||||
/** The main view controller for the demo storyboard. */
|
||||
@interface DemoViewController : UIViewController <UIKeyInput>
|
||||
-(void) shutdownExample;
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark DemoView
|
||||
|
||||
/** The Metal-compatibile view for the demo Storyboard. */
|
||||
@interface DemoView : UIView
|
||||
@end
|
||||
|
||||
224
apple/ios/DemoViewController.mm
Normal file
224
apple/ios/DemoViewController.mm
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* DemoViewController.mm
|
||||
*
|
||||
* Copyright (c) 2016-2017 The Brenwill Workshop Ltd.
|
||||
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#import "DemoViewController.h"
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#include "MVKExample.h"
|
||||
|
||||
const std::string getAssetPath() {
|
||||
return [NSBundle.mainBundle.resourcePath stringByAppendingString: @"/assets/"].UTF8String;
|
||||
}
|
||||
|
||||
const std::string getShaderBasePath() {
|
||||
return [NSBundle.mainBundle.resourcePath stringByAppendingString: @"/shaders/"].UTF8String;
|
||||
}
|
||||
|
||||
CALayer* layer;
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark DemoViewController
|
||||
|
||||
@implementation DemoViewController {
|
||||
MVKExample* _mvkExample;
|
||||
CADisplayLink* _displayLink;
|
||||
BOOL _viewHasAppeared;
|
||||
CGPoint _startPoint;
|
||||
}
|
||||
|
||||
/** Since this is a single-view app, init Vulkan when the view is loaded. */
|
||||
-(void) viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
layer = [self.view layer]; // SRS - When creating a Vulkan Metal surface, need the layer backing the view
|
||||
|
||||
self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale;
|
||||
|
||||
_mvkExample = new MVKExample(self.view, 1.0f); // SRS - Use 1x scale factor for UIOverlay on iOS
|
||||
|
||||
// SRS - Enable AppDelegate to call into DemoViewController for handling app lifecycle events (e.g. termination)
|
||||
auto appDelegate = (AppDelegate *)UIApplication.sharedApplication.delegate;
|
||||
appDelegate.viewController = self;
|
||||
|
||||
uint32_t fps = 60;
|
||||
_displayLink = [CADisplayLink displayLinkWithTarget: self selector: @selector(renderFrame)];
|
||||
[_displayLink setFrameInterval: 60 / fps];
|
||||
[_displayLink addToRunLoop: NSRunLoop.currentRunLoop forMode: NSDefaultRunLoopMode];
|
||||
|
||||
// Setup double tap gesture to toggle virtual keyboard
|
||||
UITapGestureRecognizer* tapSelector = [[[UITapGestureRecognizer alloc]
|
||||
initWithTarget: self action: @selector(handleTapGesture:)] autorelease];
|
||||
tapSelector.numberOfTapsRequired = 2;
|
||||
tapSelector.cancelsTouchesInView = YES;
|
||||
tapSelector.requiresExclusiveTouchType = YES;
|
||||
[self.view addGestureRecognizer: tapSelector];
|
||||
|
||||
// SRS - Setup pan gesture to detect and activate translation
|
||||
UIPanGestureRecognizer* panSelector = [[[UIPanGestureRecognizer alloc]
|
||||
initWithTarget: self action: @selector(handlePanGesture:)] autorelease];
|
||||
panSelector.minimumNumberOfTouches = 2;
|
||||
panSelector.cancelsTouchesInView = YES;
|
||||
panSelector.requiresExclusiveTouchType = YES;
|
||||
[self.view addGestureRecognizer: panSelector];
|
||||
|
||||
// SRS - Setup pinch gesture to detect and activate zoom
|
||||
UIPinchGestureRecognizer* pinchSelector = [[[UIPinchGestureRecognizer alloc]
|
||||
initWithTarget: self action: @selector(handlePinchGesture:)] autorelease];
|
||||
pinchSelector.cancelsTouchesInView = YES;
|
||||
pinchSelector.requiresExclusiveTouchType = YES;
|
||||
[self.view addGestureRecognizer: pinchSelector];
|
||||
|
||||
_viewHasAppeared = NO;
|
||||
}
|
||||
|
||||
-(void) viewDidAppear: (BOOL) animated {
|
||||
[super viewDidAppear: animated];
|
||||
_viewHasAppeared = YES;
|
||||
}
|
||||
|
||||
-(BOOL) canBecomeFirstResponder { return _viewHasAppeared; }
|
||||
|
||||
-(void) renderFrame {
|
||||
//_mvkExample->renderFrame();
|
||||
_mvkExample->displayLinkOutputCb(); // SRS - Call displayLinkOutputCb() to animate frames vs. renderFrame() for static image
|
||||
}
|
||||
|
||||
-(void) shutdownExample {
|
||||
[_displayLink invalidate];
|
||||
delete _mvkExample;
|
||||
}
|
||||
|
||||
// Toggle the display of the virtual keyboard
|
||||
-(void) toggleKeyboard {
|
||||
if (self.isFirstResponder) {
|
||||
[self resignFirstResponder];
|
||||
} else {
|
||||
[self becomeFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
// Display and hide the keyboard by double tapping on the view
|
||||
-(void) handleTapGesture: (UITapGestureRecognizer*) gestureRecognizer {
|
||||
if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
|
||||
[self toggleKeyboard];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark UIKeyInput methods
|
||||
|
||||
// Returns whether text is available
|
||||
-(BOOL) hasText { return YES; }
|
||||
|
||||
// A key on the keyboard has been pressed.
|
||||
-(void) insertText: (NSString*) text {
|
||||
unichar keychar = (text.length > 0) ? [text.lowercaseString characterAtIndex: 0] : 0;
|
||||
_mvkExample->keyPressed(keychar);
|
||||
}
|
||||
|
||||
// The delete backward key has been pressed.
|
||||
-(void) deleteBackward {
|
||||
_mvkExample->keyPressed(KEY_DELETE);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark UITouch methods
|
||||
|
||||
-(CGPoint) getTouchLocalPoint:(UIEvent*) theEvent {
|
||||
UITouch *touch = [[theEvent allTouches] anyObject];
|
||||
CGPoint point = [touch locationInView: self.view];
|
||||
point.x *= self.view.contentScaleFactor;
|
||||
point.y *= self.view.contentScaleFactor;
|
||||
return point;
|
||||
}
|
||||
|
||||
// SRS - Handle touch events
|
||||
-(void) touchesBegan:(NSSet*) touches withEvent:(UIEvent*) theEvent {
|
||||
if (touches.count == 1) {
|
||||
auto point = [self getTouchLocalPoint: theEvent];
|
||||
_mvkExample->mouseDown(point.x, point.y);
|
||||
}
|
||||
}
|
||||
|
||||
-(void) touchesMoved:(NSSet*) touches withEvent:(UIEvent*) theEvent {
|
||||
if (touches.count == 1) {
|
||||
auto point = [self getTouchLocalPoint: theEvent];
|
||||
_mvkExample->mouseDragged(point.x, point.y);
|
||||
}
|
||||
}
|
||||
|
||||
-(void) touchesEnded:(NSSet*) touches withEvent:(UIEvent*) theEvent {
|
||||
_mvkExample->mouseUp();
|
||||
}
|
||||
|
||||
-(void) touchesCancelled:(NSSet*) touches withEvent:(UIEvent*) theEvent {
|
||||
_mvkExample->mouseUp();
|
||||
}
|
||||
|
||||
#pragma mark UIGesture methods
|
||||
|
||||
-(CGPoint) getGestureLocalPoint:(UIGestureRecognizer*) gestureRecognizer {
|
||||
CGPoint point = [gestureRecognizer locationInView: self.view];
|
||||
point.x *= self.view.contentScaleFactor;
|
||||
point.y *= self.view.contentScaleFactor;
|
||||
return point;
|
||||
}
|
||||
|
||||
// SRS - Respond to pan gestures for translation
|
||||
-(void) handlePanGesture: (UIPanGestureRecognizer*) gestureRecognizer {
|
||||
switch (gestureRecognizer.state) {
|
||||
case UIGestureRecognizerStateBegan: {
|
||||
_startPoint = [self getGestureLocalPoint: gestureRecognizer];
|
||||
_mvkExample->otherMouseDown(_startPoint.x, _startPoint.y);
|
||||
break;
|
||||
}
|
||||
case UIGestureRecognizerStateChanged: {
|
||||
auto translation = [gestureRecognizer translationInView: self.view];
|
||||
translation.x *= self.view.contentScaleFactor;
|
||||
translation.y *= self.view.contentScaleFactor;
|
||||
_mvkExample->mouseDragged(_startPoint.x + translation.x, _startPoint.y + translation.y);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
_mvkExample->otherMouseUp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SRS - Respond to pinch gestures for zoom
|
||||
-(void) handlePinchGesture: (UIPinchGestureRecognizer*) gestureRecognizer {
|
||||
switch (gestureRecognizer.state) {
|
||||
case UIGestureRecognizerStateBegan: {
|
||||
_startPoint = [self getGestureLocalPoint: gestureRecognizer];
|
||||
_mvkExample->rightMouseDown(_startPoint.x, _startPoint.y);
|
||||
break;
|
||||
}
|
||||
case UIGestureRecognizerStateChanged: {
|
||||
_mvkExample->mouseDragged(_startPoint.x, _startPoint.y - self.view.frame.size.height * log(gestureRecognizer.scale));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
_mvkExample->rightMouseUp();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark DemoView
|
||||
|
||||
@implementation DemoView
|
||||
|
||||
/** Returns a Metal-compatible layer. */
|
||||
+(Class) layerClass { return [CAMetalLayer class]; }
|
||||
|
||||
@end
|
||||
|
||||
46
apple/ios/Info.plist
Normal file
46
apple/ios/Info.plist
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?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>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>iOS/Resources/Icon.png</string>
|
||||
<key>CFBundleIcons~ipad</key>
|
||||
<dict/>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string></string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiresFullScreen</key>
|
||||
<true/>
|
||||
<key>UIStatusBarHidden</key>
|
||||
<true/>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
apple/ios/Resources/Default-568h@2x.png
Executable file
BIN
apple/ios/Resources/Default-568h@2x.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
BIN
apple/ios/Resources/Default~ipad.png
Executable file
BIN
apple/ios/Resources/Default~ipad.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
BIN
apple/ios/Resources/Icon.png
Executable file
BIN
apple/ios/Resources/Icon.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 KiB |
26
apple/ios/Resources/Main.storyboard
Normal file
26
apple/ios/Resources/Main.storyboard
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9060" systemVersion="15A279b" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="vmV-Wi-8wg">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Demo View Controller-->
|
||||
<scene sceneID="UPC-Y9-dN2">
|
||||
<objects>
|
||||
<viewController id="vmV-Wi-8wg" customClass="DemoViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="klr-UD-pWY"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="lMV-Es-kLU"/>
|
||||
</layoutGuides>
|
||||
<view key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="xKx-Gc-5Is" customClass="DemoView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<animations/>
|
||||
</view>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="ERB-qy-6pP" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="404" y="555"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
||||
14
apple/ios/main.m
Normal file
14
apple/ios/main.m
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* main.m
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, @"AppDelegate");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue