From 2992642a3ca94bf52b066eed18bcc1df631ec67e Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sat, 30 Mar 2019 11:52:35 -0700 Subject: Enabled Vulkan mode on iOS (close https://github.com/DiligentGraphics/DiligentCore/issues/46) --- .../Apple/Data/iOS/Base.lproj/LaunchScreen.xib | 21 +-- .../Apple/Data/iOS/Base.lproj/Main.storyboard | 79 +++++++++- .../Data/iOS/Images.xcassets/opengles-logo.png | Bin 0 -> 39013 bytes .../Apple/Data/iOS/Images.xcassets/vulkan-logo.png | Bin 0 -> 35692 bytes .../Apple/Source/Classes/iOS/AppDelegate.h | 3 - .../Apple/Source/Classes/iOS/AppDelegate.m | 27 ++-- .../Apple/Source/Classes/iOS/AppViewBase.h | 16 ++ .../Apple/Source/Classes/iOS/AppViewBase.m | 166 +++++++++++++++++++++ .../NativeApp/Apple/Source/Classes/iOS/BaseView.h | 12 ++ .../NativeApp/Apple/Source/Classes/iOS/BaseView.m | 21 +++ .../NativeApp/Apple/Source/Classes/iOS/EAGLView.h | 11 +- .../NativeApp/Apple/Source/Classes/iOS/EAGLView.m | 157 +++---------------- .../NativeApp/Apple/Source/Classes/iOS/MetalView.h | 7 + .../NativeApp/Apple/Source/Classes/iOS/MetalView.m | 39 +++++ .../Classes/iOS/ModeSelectionViewController.h | 29 ++++ .../Classes/iOS/ModeSelectionViewController.mm | 64 ++++++++ Common/NativeApp/CMakeLists.txt | 26 +++- Common/NativeApp/include/IOS/IOSAppBase.h | 2 +- 18 files changed, 485 insertions(+), 195 deletions(-) create mode 100755 Common/NativeApp/Apple/Data/iOS/Images.xcassets/opengles-logo.png create mode 100644 Common/NativeApp/Apple/Data/iOS/Images.xcassets/vulkan-logo.png create mode 100644 Common/NativeApp/Apple/Source/Classes/iOS/AppViewBase.h create mode 100644 Common/NativeApp/Apple/Source/Classes/iOS/AppViewBase.m create mode 100644 Common/NativeApp/Apple/Source/Classes/iOS/BaseView.h create mode 100644 Common/NativeApp/Apple/Source/Classes/iOS/BaseView.m create mode 100644 Common/NativeApp/Apple/Source/Classes/iOS/MetalView.h create mode 100644 Common/NativeApp/Apple/Source/Classes/iOS/MetalView.m create mode 100644 Common/NativeApp/Apple/Source/Classes/iOS/ModeSelectionViewController.h create mode 100644 Common/NativeApp/Apple/Source/Classes/iOS/ModeSelectionViewController.mm (limited to 'Common/NativeApp') diff --git a/Common/NativeApp/Apple/Data/iOS/Base.lproj/LaunchScreen.xib b/Common/NativeApp/Apple/Data/iOS/Base.lproj/LaunchScreen.xib index 5569812..42589b0 100644 --- a/Common/NativeApp/Apple/Data/iOS/Base.lproj/LaunchScreen.xib +++ b/Common/NativeApp/Apple/Data/iOS/Base.lproj/LaunchScreen.xib @@ -1,9 +1,12 @@ - - + + + + + - - + + @@ -12,20 +15,20 @@ - - + diff --git a/Common/NativeApp/Apple/Data/iOS/Base.lproj/Main.storyboard b/Common/NativeApp/Apple/Data/iOS/Base.lproj/Main.storyboard index 0dc87c1..026129a 100644 --- a/Common/NativeApp/Apple/Data/iOS/Base.lproj/Main.storyboard +++ b/Common/NativeApp/Apple/Data/iOS/Base.lproj/Main.storyboard @@ -1,26 +1,89 @@ - - + + + + + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - + + + + + + diff --git a/Common/NativeApp/Apple/Data/iOS/Images.xcassets/opengles-logo.png b/Common/NativeApp/Apple/Data/iOS/Images.xcassets/opengles-logo.png new file mode 100755 index 0000000..88b6983 Binary files /dev/null and b/Common/NativeApp/Apple/Data/iOS/Images.xcassets/opengles-logo.png differ diff --git a/Common/NativeApp/Apple/Data/iOS/Images.xcassets/vulkan-logo.png b/Common/NativeApp/Apple/Data/iOS/Images.xcassets/vulkan-logo.png new file mode 100644 index 0000000..8a15b9e Binary files /dev/null and b/Common/NativeApp/Apple/Data/iOS/Images.xcassets/vulkan-logo.png differ diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/AppDelegate.h b/Common/NativeApp/Apple/Source/Classes/iOS/AppDelegate.h index bbb1f04..3839faa 100644 --- a/Common/NativeApp/Apple/Source/Classes/iOS/AppDelegate.h +++ b/Common/NativeApp/Apple/Source/Classes/iOS/AppDelegate.h @@ -9,9 +9,6 @@ #import -@class EAGLView; -@class MainViewController; - @interface AppDelegate : NSObject { } diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/AppDelegate.m b/Common/NativeApp/Apple/Source/Classes/iOS/AppDelegate.m index 6aa6648..5e1745c 100644 --- a/Common/NativeApp/Apple/Source/Classes/iOS/AppDelegate.m +++ b/Common/NativeApp/Apple/Source/Classes/iOS/AppDelegate.m @@ -7,7 +7,7 @@ */ #import "AppDelegate.h" -#import "EAGLView.h" +#import "BaseView.h" @implementation AppDelegate @@ -15,19 +15,12 @@ #pragma mark Application lifecycle - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ +{ // Override point for customization after application launch. - + [self.window makeKeyAndVisible]; - - NSString *error = [(EAGLView*)self.window.rootViewController.view getError]; - if(error != nil) - { - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failed to start the application" message:error delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Whatever", nil]; - [alert show]; - } - [(EAGLView*)self.window.rootViewController.view startAnimation]; + [(BaseView*)self.window.rootViewController.view startAnimation]; return YES; } @@ -40,7 +33,7 @@ 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. */ - [(EAGLView*)self.window.rootViewController.view stopAnimation]; + [(BaseView*)self.window.rootViewController.view stopAnimation]; } @@ -50,7 +43,7 @@ If your application supports background execution, called instead of applicationWillTerminate: when the user quits. */ - [(EAGLView*)self.window.rootViewController.view stopAnimation]; + [(BaseView*)self.window.rootViewController.view stopAnimation]; } @@ -59,7 +52,7 @@ Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background. */ - [(EAGLView*)self.window.rootViewController.view startAnimation]; + [(BaseView*)self.window.rootViewController.view startAnimation]; } @@ -69,7 +62,7 @@ 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. */ - [(EAGLView*)self.window.rootViewController.view startAnimation]; + [(BaseView*)self.window.rootViewController.view startAnimation]; } @@ -79,8 +72,8 @@ See also applicationDidEnterBackground:. */ - [(EAGLView*)self.window.rootViewController.view stopAnimation]; - [(EAGLView*)self.window.rootViewController.view terminate]; + [(BaseView*)self.window.rootViewController.view stopAnimation]; + [(BaseView*)self.window.rootViewController.view terminate]; } diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/AppViewBase.h b/Common/NativeApp/Apple/Source/Classes/iOS/AppViewBase.h new file mode 100644 index 0000000..e6273e9 --- /dev/null +++ b/Common/NativeApp/Apple/Source/Classes/iOS/AppViewBase.h @@ -0,0 +1,16 @@ + +#import +#import "BaseView.h" + +@interface AppViewBase : BaseView + +@property (nonatomic) NSInteger animationFrameInterval; + +- (void) initApp:(int)deviceType; +- (void) startAnimation; +- (void) stopAnimation; +- (void) terminate; +- (void) render; +- (NSString*)getError; + +@end diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/AppViewBase.m b/Common/NativeApp/Apple/Source/Classes/iOS/AppViewBase.m new file mode 100644 index 0000000..e7d4c57 --- /dev/null +++ b/Common/NativeApp/Apple/Source/Classes/iOS/AppViewBase.m @@ -0,0 +1,166 @@ + +#import "AppViewBase.h" + +#include "NativeAppBase.h" +#include +#include + +@interface AppViewBase () +{ + std::unique_ptr _theApp; + NSInteger _animationFrameInterval; + CADisplayLink* _displayLink; + std::string _error; +} +@end + +@implementation AppViewBase + +- (void) initApp:(int)deviceType; +{ + try + { + _theApp.reset(Diligent::CreateApplication()); + // Init our renderer. + _theApp->Initialize(deviceType, (__bridge void*)self.layer); + } + catch(std::runtime_error &err) + { + _error = err.what(); + _theApp.reset(); + } + + [super stopAnimation]; + _animationFrameInterval = 1; + _displayLink = nil; +} + +- (void) render +{ + if(_theApp) + { + _theApp->Update(); + _theApp->Render(); + _theApp->Present(); + } +} + +- (void) layoutSubviews +{ + auto bounds = [self.layer bounds]; + auto scale = [self.layer contentsScale]; + + if(_theApp) + { + _theApp->WindowResize(bounds.size.width * scale, bounds.size.height * scale); + } +} + +- (NSInteger) animationFrameInterval +{ + return _animationFrameInterval; +} + +- (void) setAnimationFrameInterval:(NSInteger)frameInterval +{ + // Frame interval defines how many display frames must pass between each time the + // display link fires. The display link will only fire 30 times a second when the + // frame internal is two on a display that refreshes 60 times a second. The default + // frame interval setting of one will fire 60 times a second when the display refreshes + // at 60 times a second. A frame interval setting of less than one results in undefined + // behavior. + if (frameInterval >= 1) + { + _animationFrameInterval = frameInterval; + + if (self.animating) + { + [self stopAnimation]; + [self startAnimation]; + } + } +} + +- (void) startAnimation +{ + if (!self.animating) + { + // Create the display link and set the callback to our drawView method + _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView:)]; + + // Set it to our _animationFrameInterval + [_displayLink setFrameInterval:_animationFrameInterval]; + + // Have the display link run on the default runn loop (and the main thread) + [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + + [super startAnimation]; + } +} + +- (void)stopAnimation +{ + if (self.animating) + { + [_displayLink invalidate]; + _displayLink = nil; + [super stopAnimation]; + } +} + +- (void)terminate +{ + _theApp.reset(); + [super terminate]; +} + +- (NSString*)getError +{ + return _error.empty() ? nil : [NSString stringWithFormat:@"%s", _error.c_str()]; +} + +- (void)touchesBegan:(NSSet *)touches + withEvent:(UIEvent *)event; +{ + UITouch *firstTouch = touches.allObjects[0]; + CGPoint location = [firstTouch locationInView:self]; + if(_theApp) + { + _theApp->OnTouchBegan(location.x, location.y); + } +} + +- (void)touchesMoved:(NSSet *)touches + withEvent:(UIEvent *)event; +{ + UITouch *firstTouch = touches.allObjects[0]; + CGPoint location = [firstTouch locationInView:self]; + if(_theApp) + { + _theApp->OnTouchMoved(location.x, location.y); + } +} + +- (void)touchesEnded:(NSSet *)touches + withEvent:(UIEvent *)event; +{ + UITouch *firstTouch = touches.allObjects[0]; + CGPoint location = [firstTouch locationInView:self]; + if(_theApp) + { + _theApp->OnTouchEnded(location.x, location.y); + } +} + +- (void)touchesCancelled:(NSSet *)touches + withEvent:(UIEvent *)event; +{ + UITouch *firstTouch = touches.allObjects[0]; + CGPoint location = [firstTouch locationInView:self]; + if(_theApp) + { + _theApp->OnTouchEnded(location.x, location.y); + } +} + +@end diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/BaseView.h b/Common/NativeApp/Apple/Source/Classes/iOS/BaseView.h new file mode 100644 index 0000000..9e8b99e --- /dev/null +++ b/Common/NativeApp/Apple/Source/Classes/iOS/BaseView.h @@ -0,0 +1,12 @@ + +#import + +@interface BaseView : UIView + +@property (readonly, nonatomic, getter=isAnimating) BOOL animating; + +- (void) startAnimation; +- (void) stopAnimation; +- (void) terminate; + +@end diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/BaseView.m b/Common/NativeApp/Apple/Source/Classes/iOS/BaseView.m new file mode 100644 index 0000000..c87e5cd --- /dev/null +++ b/Common/NativeApp/Apple/Source/Classes/iOS/BaseView.m @@ -0,0 +1,21 @@ + +#import "BaseView.h" + +@implementation BaseView + +- (void) startAnimation +{ + _animating = TRUE; +} + +- (void)stopAnimation +{ + _animating = FALSE; +} + +- (void) terminate +{ + +} + +@end diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/EAGLView.h b/Common/NativeApp/Apple/Source/Classes/iOS/EAGLView.h index fd6b9b9..e5ba68a 100644 --- a/Common/NativeApp/Apple/Source/Classes/iOS/EAGLView.h +++ b/Common/NativeApp/Apple/Source/Classes/iOS/EAGLView.h @@ -6,20 +6,13 @@ The EAGLView class is a UIView subclass that renders OpenGL scene. */ -#import +#import "AppViewBase.h" // This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass. // The view content is basically an EAGL surface you render your OpenGL scene into. // Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel. -@interface EAGLView : UIView +@interface EAGLView : AppViewBase -@property (readonly, nonatomic, getter=isAnimating) BOOL animating; -@property (nonatomic) NSInteger animationFrameInterval; - -- (void) startAnimation; -- (void) stopAnimation; -- (void) terminate; - (void) drawView:(id)sender; -- (NSString*)getError; @end diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/EAGLView.m b/Common/NativeApp/Apple/Source/Classes/iOS/EAGLView.m index 9120e99..ff02820 100644 --- a/Common/NativeApp/Apple/Source/Classes/iOS/EAGLView.m +++ b/Common/NativeApp/Apple/Source/Classes/iOS/EAGLView.m @@ -8,17 +8,11 @@ #import "EAGLView.h" -#include "NativeAppBase.h" -#include -#include +#include "DeviceCaps.h" @interface EAGLView () { - std::unique_ptr _theApp; EAGLContext* _context; - NSInteger _animationFrameInterval; - CADisplayLink* _displayLink; - std::string _error; } @end @@ -32,166 +26,49 @@ // The GL view is stored in the storyboard file. When it's unarchived it's sent -initWithCoder: - (instancetype) initWithCoder:(NSCoder*)coder -{ +{ if ((self = [super initWithCoder:coder])) { // Get the layer CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; - + eaglLayer.opaque = TRUE; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; - - + _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; - + if (!_context || ![EAGLContext setCurrentContext:_context]) { return nil; } - - try - { - _theApp.reset(Diligent::CreateApplication()); - // Init our renderer. - _theApp->OnGLContextCreated((__bridge void*)self.layer); - } - catch(std::runtime_error &err) - { - _error = err.what(); - _theApp.reset(); - } - - _animating = FALSE; - _animationFrameInterval = 1; - _displayLink = nil; + + [self initApp:(int)Diligent::DeviceType::OpenGLES]; } - + return self; } - (void) drawView:(id)sender -{ - [EAGLContext setCurrentContext:_context]; - if(_theApp) +{ + [EAGLContext setCurrentContext:_context]; + + // There is no autorelease pool when this method is called + // because it will be called from a background thread. + // It's important to create one or app can leak objects. + @autoreleasepool { - _theApp->Update(); - _theApp->Render(); - _theApp->Present(); + [self render]; } } -- (void) layoutSubviews -{ - if(_theApp) - _theApp->WindowResize(0, 0); - [self drawView:nil]; -} - -- (NSInteger) animationFrameInterval -{ - return _animationFrameInterval; -} - -- (void) setAnimationFrameInterval:(NSInteger)frameInterval -{ - // Frame interval defines how many display frames must pass between each time the - // display link fires. The display link will only fire 30 times a second when the - // frame internal is two on a display that refreshes 60 times a second. The default - // frame interval setting of one will fire 60 times a second when the display refreshes - // at 60 times a second. A frame interval setting of less than one results in undefined - // behavior. - if (frameInterval >= 1) - { - _animationFrameInterval = frameInterval; - - if (_animating) - { - [self stopAnimation]; - [self startAnimation]; - } - } -} - -- (void) startAnimation -{ - if (!_animating) - { - // Create the display link and set the callback to our drawView method - _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView:)]; - - // Set it to our _animationFrameInterval - [_displayLink setFrameInterval:_animationFrameInterval]; - - // Have the display link run on the default runn loop (and the main thread) - [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; - - _animating = TRUE; - } -} - -- (void)stopAnimation -{ - if (_animating) - { - [_displayLink invalidate]; - _displayLink = nil; - _animating = FALSE; - } -} - -- (void)terminate -{ - _theApp.reset(); -} - - (void) dealloc { [self terminate]; // tear down context - if ([EAGLContext currentContext] == _context) + if ([EAGLContext currentContext] == _context) [EAGLContext setCurrentContext:nil]; } -- (NSString*)getError -{ - return _error.empty() ? nil : [NSString stringWithFormat:@"%s", _error.c_str()]; -} - -- (void)touchesBegan:(NSSet *)touches - withEvent:(UIEvent *)event; -{ - UITouch *firstTouch = touches.allObjects[0]; - CGPoint location = [firstTouch locationInView:self]; - if(_theApp) - _theApp->OnTouchBegan(location.x, location.y); -} - -- (void)touchesMoved:(NSSet *)touches - withEvent:(UIEvent *)event; -{ - UITouch *firstTouch = touches.allObjects[0]; - CGPoint location = [firstTouch locationInView:self]; - if(_theApp) - _theApp->OnTouchMoved(location.x, location.y); -} - -- (void)touchesEnded:(NSSet *)touches - withEvent:(UIEvent *)event; -{ - UITouch *firstTouch = touches.allObjects[0]; - CGPoint location = [firstTouch locationInView:self]; - if(_theApp) - _theApp->OnTouchEnded(location.x, location.y);} - -- (void)touchesCancelled:(NSSet *)touches - withEvent:(UIEvent *)event; -{ - UITouch *firstTouch = touches.allObjects[0]; - CGPoint location = [firstTouch locationInView:self]; - if(_theApp) - _theApp->OnTouchEnded(location.x, location.y); -} - @end diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/MetalView.h b/Common/NativeApp/Apple/Source/Classes/iOS/MetalView.h new file mode 100644 index 0000000..a485b27 --- /dev/null +++ b/Common/NativeApp/Apple/Source/Classes/iOS/MetalView.h @@ -0,0 +1,7 @@ +#import "AppViewBase.h" + +@interface MetalView : AppViewBase + +- (void) drawView:(id)sender; + +@end diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/MetalView.m b/Common/NativeApp/Apple/Source/Classes/iOS/MetalView.m new file mode 100644 index 0000000..3c8b198 --- /dev/null +++ b/Common/NativeApp/Apple/Source/Classes/iOS/MetalView.m @@ -0,0 +1,39 @@ +#import "MetalView.h" +#import + +#include "DeviceCaps.h" + +@implementation MetalView + ++ (Class) layerClass +{ + return [CAMetalLayer class]; +} + +- (instancetype) initWithCoder:(NSCoder*)coder +{ + if ((self = [super initWithCoder:coder])) + { + [self initApp:(int)Diligent::DeviceType::Vulkan]; + } + + return self; +} + +- (void) drawView:(id)sender +{ + // There is no autorelease pool when this method is called + // because it will be called from a background thread. + // It's important to create one or app can leak objects. + @autoreleasepool + { + [self render]; + } +} + +- (void) dealloc +{ + [self terminate]; +} + +@end diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/ModeSelectionViewController.h b/Common/NativeApp/Apple/Source/Classes/iOS/ModeSelectionViewController.h new file mode 100644 index 0000000..4a08d7d --- /dev/null +++ b/Common/NativeApp/Apple/Source/Classes/iOS/ModeSelectionViewController.h @@ -0,0 +1,29 @@ +/* Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#import + +@interface ModeSelectionViewController : UIViewController +{ +} +@end diff --git a/Common/NativeApp/Apple/Source/Classes/iOS/ModeSelectionViewController.mm b/Common/NativeApp/Apple/Source/Classes/iOS/ModeSelectionViewController.mm new file mode 100644 index 0000000..8958c10 --- /dev/null +++ b/Common/NativeApp/Apple/Source/Classes/iOS/ModeSelectionViewController.mm @@ -0,0 +1,64 @@ +/* Copyright 2015-2019 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#import "ModeSelectionViewController.h" +#import "BaseView.h" +#import "AppViewBase.h" + +@implementation ModeSelectionViewController +{ +} + +-(void)selectViewController:(NSString*)controllerID +{ + auto animating = ((BaseView*)self.view).animating; + + UIViewController* viewController = [self.storyboard instantiateViewControllerWithIdentifier:controllerID]; + self.view.window.rootViewController = viewController; + + NSString *error = [(AppViewBase*)viewController.view getError]; + if(error != nil) + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failed to start the application" message:error delegate:self cancelButtonTitle:@"OK" otherButtonTitles:@"Whatever", nil]; + [alert show]; + } + + if(animating) + { + [(BaseView*)viewController.view startAnimation]; + } +} + +- (IBAction)goOpenGLES:(id)sender +{ + [self selectViewController:@"EAGLViewControllerID"]; +} + +- (IBAction)goVulkan:(id)sender +{ +#if VULKAN_SUPPORTED + [self selectViewController:@"MetalViewControllerID"]; +#endif +} + +@end diff --git a/Common/NativeApp/CMakeLists.txt b/Common/NativeApp/CMakeLists.txt index b01877c..6fa1db4 100644 --- a/Common/NativeApp/CMakeLists.txt +++ b/Common/NativeApp/CMakeLists.txt @@ -13,7 +13,7 @@ if(PLATFORM_WIN32) function(add_win32_app TARGET_NAME SOURCE INCLUDE ASSETS) add_executable(${TARGET_NAME} WIN32 ${SOURCE} ${INCLUDE} ${ASSETS}) - + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") # libmingw32 must be included BEFORE NativeAppBase that contains the definition of WinMain. # otherwise WinMain will be stripped out of NativeAppBase and will be unresolved. @@ -192,7 +192,6 @@ elseif(PLATFORM_MACOS) if (NOT CORE_VIDEO) message(FATAL_ERROR "CoreVideo is not found") endif() - target_link_libraries(${TARGET_NAME} PRIVATE ) find_library(METAL_FRAMEWORK Metal) if (NOT METAL_FRAMEWORK) @@ -227,21 +226,32 @@ elseif(PLATFORM_IOS) set(APPLE_SOURCE ${NATIVE_APP_SOURCE_DIR}/Apple/Source/main.m ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/AppDelegate.m + ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/BaseView.m ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/EAGLView.m + ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/AppViewBase.m + ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/ModeSelectionViewController.mm + ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/MetalView.m ) + set_source_files_properties(${APPLE_SOURCE} PROPERTIES COMPILE_FLAGS "-x objective-c++" ) set(APPLE_INCLUDE ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/AppDelegate.h + ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/BaseView.h ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/EAGLView.h + ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/AppViewBase.h + ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/ModeSelectionViewController.h + ${NATIVE_APP_SOURCE_DIR}/Apple/Source/Classes/iOS/MetalView.h ) set(APPLE_RESOURCES ${NATIVE_APP_SOURCE_DIR}/Apple/Data/iOS/Base.lproj/Main.storyboard ${NATIVE_APP_SOURCE_DIR}/Apple/Data/iOS/Base.lproj/LaunchScreen.xib ${NATIVE_APP_SOURCE_DIR}/Apple/Data/iOS/Images.xcassets/AppIcon.appiconset/dg-icon.png + ${NATIVE_APP_SOURCE_DIR}/Apple/Data/iOS/Images.xcassets/opengles-logo.png + ${NATIVE_APP_SOURCE_DIR}/Apple/Data/iOS/Images.xcassets/vulkan-logo.png ) set(APPLE_INFO_PLIST @@ -267,13 +277,13 @@ elseif(PLATFORM_IOS) target_include_directories(${TARGET_NAME} PRIVATE ${APPLE_INCLUDE_DIRS}) find_library(OPENGLES OpenGLES) - if (NOT OPENGLES) - message(FATAL_ERROR "OpenGLES is not found") - endif() + if (NOT OPENGLES) + message(FATAL_ERROR "OpenGLES is not found") + endif() find_library(UIKIT UIKit) if (NOT UIKIT) - message(FATAL_ERROR "UIKIT is not found") + message(FATAL_ERROR "UIKIT is not found") endif() find_library(CORE_ANIMATION QuartzCore) @@ -309,7 +319,7 @@ PUBLIC if(MSVC) target_compile_options(NativeAppBase PRIVATE -DUNICODE) - + if(PLATFORM_UNIVERSAL_WINDOWS) # Disable w4189: local variable is initialized but not referenced # Disable w4063: case is not a valid value for switch of enum @@ -332,7 +342,7 @@ if(PLATFORM_WIN32) ) elseif(PLATFORM_UNIVERSAL_WINDOWS) - + target_include_directories(NativeAppBase PUBLIC include/UWP diff --git a/Common/NativeApp/include/IOS/IOSAppBase.h b/Common/NativeApp/include/IOS/IOSAppBase.h index 2efe4ab..847052a 100644 --- a/Common/NativeApp/include/IOS/IOSAppBase.h +++ b/Common/NativeApp/include/IOS/IOSAppBase.h @@ -34,7 +34,7 @@ class IOSAppBase : public AppBase public: using AppBase::Update; void Update(); - virtual void OnGLContextCreated(void* eaglLayer) = 0; + virtual void Initialize(int deviceType, void* layer) = 0; virtual void OnTouchBegan(float x, float y){} virtual void OnTouchMoved(float x, float y){} virtual void OnTouchEnded(float x, float y){} -- cgit v1.2.3