diff --git a/cmake/AppleHelper.cmake b/cmake/AppleHelper.cmake index c38f88f..b331843 100644 --- a/cmake/AppleHelper.cmake +++ b/cmake/AppleHelper.cmake @@ -4,16 +4,20 @@ function(LinkAppleFrameworks TARGET) PUBLIC "-framework Foundation" PUBLIC "-framework CoreImage" PUBLIC "-framework CoreVideo" + PUBLIC "-framework CoreGraphics" PUBLIC "-framework Metal" PUBLIC "-framework MetalPerformanceShaders" + PUBLIC "-framework MetalKit" + PUBLIC "-framework IOSurface" + PUBLIC "-framework QuartzCore" PUBLIC "-lstdc++" PUBLIC c++ PUBLIC c ) if(IOS) - target_link_libraries(${TARGET} PUBLIC "-framework ARKit") - endif() + target_link_libraries(${TARGET} PUBLIC "-framework ARKit") + endif() # Locate system libraries on iOS find_library(UIKIT UIKit) @@ -30,10 +34,10 @@ function(LinkAppleFrameworks TARGET) target_link_libraries(${TARGET} PUBLIC ${UIKIT}) target_link_libraries(${TARGET} PUBLIC ${MOBILECORESERVICES}) else() - target_link_libraries(${TARGET} PUBLIC ${APPKIT}) - target_link_libraries(${TARGET} PUBLIC ${IOSURFACE}) - target_link_libraries(${TARGET} PUBLIC ${QUARTZ}) + target_link_libraries(${TARGET} PUBLIC ${APPKIT}) + target_link_libraries(${TARGET} PUBLIC ${QUARTZ}) endif() + target_link_libraries(${TARGET} PUBLIC ${IOSURFACE}) target_link_libraries(${TARGET} PUBLIC ${FOUNDATION}) target_link_libraries(${TARGET} PUBLIC ${CFNETWORK}) target_link_libraries(${TARGET} PUBLIC ${SYSTEMCONFIGURATION}) diff --git a/examples/ExampleAppList.hpp b/examples/ExampleAppList.hpp new file mode 100644 index 0000000..3308eb3 --- /dev/null +++ b/examples/ExampleAppList.hpp @@ -0,0 +1,23 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include "ExampleApps/CubesExampleApp.hpp" +#include "ExampleApps/MovingCubeApp.hpp" +#include "ExampleApps/TexturedCubeExampleApp.hpp" +#include "ExampleApps/BillboardExampleApp.hpp" +#include + +namespace OpenVulkano +{ + const std::vector> EXAMPLE_APPS = { + { "Cubes Example App", &CubesExampleApp::Create }, + { "Moving Cube Example App", &MovingCubeApp::Create }, + { "Textured Cube Example App", &TexturedCubeExampleApp::Create }, + { "Billboard Example App", &BillboardExampleApp::Create } + }; +} diff --git a/examples/Host/iOS/ExampleViewController.h b/examples/Host/iOS/ExampleViewController.h new file mode 100644 index 0000000..de2621c --- /dev/null +++ b/examples/Host/iOS/ExampleViewController.h @@ -0,0 +1,19 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#import +#import +#import "Host/iOS/OpenVulkanoViewController.h" + +@interface MainMenuViewController : UIViewController +@end + +@interface ExampleViewController : OpenVulkanoViewController +@property(nonatomic, strong)OpenVulkanoView* renderView; +@property size_t exampleId; +@end diff --git a/examples/Host/iOS/ExampleViewController.mm b/examples/Host/iOS/ExampleViewController.mm new file mode 100644 index 0000000..350c9c6 --- /dev/null +++ b/examples/Host/iOS/ExampleViewController.mm @@ -0,0 +1,75 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#import "ExampleViewController.h" + +#include "../../ExampleAppList.hpp" + +@implementation MainMenuViewController +- (void)viewDidLoad { + [super viewDidLoad]; + + self.view.backgroundColor = [UIColor whiteColor]; + + CGFloat buttonHeight = 50; + CGFloat buttonSpacing = 10; + CGFloat topMargin = 50; + + int i = 0; + for (const auto& app : OpenVulkano::EXAMPLE_APPS) + { + UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; + button.frame = CGRectMake(20, + topMargin + i * (buttonHeight + buttonSpacing), + self.view.bounds.size.width - 40, + buttonHeight); + [button setTitle:[NSString stringWithUTF8String:app.first] forState:UIControlStateNormal]; + button.tag = i; + [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; + [self.view addSubview:button]; + i++; + } + + self.view.frame = [UIScreen mainScreen].bounds; + self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; +} + +- (void)buttonPressed:(UIButton *)sender { + ExampleViewController* example = [[ExampleViewController alloc] init]; + example.exampleId = sender.tag; + example.modalPresentationStyle = UIModalPresentationFullScreen; + [self presentViewController:example animated:true completion:nil]; +} + +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + self.view.frame = self.view.superview.bounds; +} +@end + +@implementation ExampleViewController +- (void)viewDidLoad { + self.renderView = [[OpenVulkanoView alloc] initWithFrame:self.view.frame]; + self.openVulkanoView = self.renderView; + [self.view addSubview:self.renderView]; + [super viewDidLoad]; + + self.view.frame = [UIScreen mainScreen].bounds; + self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; +} + +- (void)viewDidLayoutSubviews { + [super viewDidLayoutSubviews]; + self.view.frame = self.view.superview.bounds; + self.renderView.frame = self.view.frame; +} + +- (BOOL)prefersStatusBarHidden { return true; } + +- (void *)makeGraphicsApp { + return OpenVulkano::EXAMPLE_APPS[self.exampleId].second(); +} +@end diff --git a/examples/Host/iOS/main.mm b/examples/Host/iOS/main.mm new file mode 100644 index 0000000..8bfea05 --- /dev/null +++ b/examples/Host/iOS/main.mm @@ -0,0 +1,57 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#import +#import +#import "ExampleViewController.h" +#import "Host/iOS/OpenVulkanoAppDelegate.h" + +#include "Base/Logger.hpp" + +@interface SceneDelegate : UIResponder +@end + +@implementation SceneDelegate +@synthesize window = _window; +- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { + if ([scene isKindOfClass:[UIWindowScene class]]) { + UIWindowScene* wScene = (UIWindowScene*)scene; + self.window = [[UIWindow alloc] initWithWindowScene:wScene]; + + MainMenuViewController* rootViewController = [[MainMenuViewController alloc] init]; + UINavigationController* navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; + + self.window.rootViewController = navigationController; + [self.window makeKeyAndVisible]; + } +} +@end + +@interface AppDelegate : OpenVulkanoAppDelegate +@end + +@implementation AppDelegate +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + +- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options { + UISceneConfiguration *configuration = [[UISceneConfiguration alloc] initWithName:nil sessionRole:UIWindowSceneSessionRoleApplication]; + configuration.delegateClass = SceneDelegate.class; + return configuration; +} +@end + +int main(int argCount, char** args) +{ + using namespace OpenVulkano; + Logger::SetupLogger(); + @autoreleasepool + { + return UIApplicationMain(argCount, args, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/examples/main.cpp b/examples/main.cpp index 388087e..002e431 100644 --- a/examples/main.cpp +++ b/examples/main.cpp @@ -5,10 +5,7 @@ */ #include "Host/GraphicsAppManager.hpp" -#include "ExampleApps/CubesExampleApp.hpp" -#include "ExampleApps/MovingCubeApp.hpp" -#include "ExampleApps/TexturedCubeExampleApp.hpp" -#include "ExampleApps/BillboardExampleApp.hpp" +#include "ExampleAppList.hpp" #include #include @@ -22,12 +19,11 @@ using namespace OpenVulkano; int main(int argc, char** argv) { - std::vector examples = { - "Cubes Example App", - "Moving Cube Example App", - "Textured Cube Example App", - "Billboard Example App" - }; + std::vector examples; + for (const auto& e : EXAMPLE_APPS) + { + examples.emplace_back(e.first); + } int selectedExample = 0; ftxui::MenuOption option; @@ -37,15 +33,9 @@ int main(int argc, char** argv) screen.Loop(menu); - std::unique_ptr app; - switch (selectedExample) - { - case 0: app = CubesExampleApp::CreateUnique(); break; - case 1: app = MovingCubeApp::CreateUnique(); break; - case 2: app = TexturedCubeExampleApp::CreateUnique(); break; - case 3: app = BillboardExampleApp::CreateUnique(); break; - default: throw std::runtime_error("Invalid menu selection!"); break; - } + if (selectedExample >= examples.size()) throw std::runtime_error("Invalid menu selection!"); + + std::unique_ptr app( EXAMPLE_APPS[selectedExample].second() ); GraphicsAppManager manager(app.get()); manager.Run();