From ec18bcdb986230a16f7811c2de42229d3ec4d1cc Mon Sep 17 00:00:00 2001 From: GeorgH93 Date: Sun, 30 May 2021 15:35:11 +0200 Subject: [PATCH] Add iOS window host --- .../Host/iOS/OpenVulkanoViewController.h | 24 +++ .../Host/iOS/OpenVulkanoViewController.mm | 141 ++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 openVulkanoCpp/Host/iOS/OpenVulkanoViewController.h create mode 100644 openVulkanoCpp/Host/iOS/OpenVulkanoViewController.mm diff --git a/openVulkanoCpp/Host/iOS/OpenVulkanoViewController.h b/openVulkanoCpp/Host/iOS/OpenVulkanoViewController.h new file mode 100644 index 0000000..8b107f9 --- /dev/null +++ b/openVulkanoCpp/Host/iOS/OpenVulkanoViewController.h @@ -0,0 +1,24 @@ +/* + * 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 + + +#pragma mark - +#pragma mark OpenVulkanoViewController + +/** The main view controller for the demo storyboard. */ +@interface OpenVulkanoViewController : UIViewController +@end + + +#pragma mark - +#pragma mark DemoView + +/** The Metal-compatibile view for the demo Storyboard. */ +@interface DemoView : UIView +@end + diff --git a/openVulkanoCpp/Host/iOS/OpenVulkanoViewController.mm b/openVulkanoCpp/Host/iOS/OpenVulkanoViewController.mm new file mode 100644 index 0000000..61fe611 --- /dev/null +++ b/openVulkanoCpp/Host/iOS/OpenVulkanoViewController.mm @@ -0,0 +1,141 @@ +/* + * 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 "OpenVulkanoViewController.h" + +#include +#include "Host/GraphicsAppManager.hpp" +#include "ExampleApps/CubesExampleApp.hpp" +#include "Base/UI/IVulkanWindow.hpp" + + +#pragma mark - +#pragma mark OpenVulkanoViewController + +using namespace openVulkanoCpp; + +class ViewWindow final : public IVulkanWindow +{ + WindowConfiguration windowConf; + IWindowHandler* handler = nullptr; + void* caMetalLayer = nullptr; + +public: + void Init(RenderAPI::RenderApi renderApi) override {} + void Init(void* metalLayer, Math::Vector2ui size) + { + caMetalLayer = metalLayer; + windowConf.size = size; + } + + void SetMetalLayer(void* metalLayer) { caMetalLayer = metalLayer; } + + bool HasTitle() override { return false; } + const std::string& GetTitle() override { return windowConf.title; } + void SetTitle(const std::string& title) override {} + + WindowMode GetWindowMode() override { return FULLSCREEN; } + void SetWindowMode(WindowMode) override {} + + const WindowConfiguration & GetWindowConfiguration() override { return windowConf; } + void SetSize(uint32_t width, uint32_t height) override {} + void SetSizeLimits(int minWidth, int minHeight, int maxWidth, int maxHeight) override {} + + Math::Vector2i GetPosition() override { return { 0,0 }; } + void SetPosition(int posX, int posY) override {} + + void Show() override {} + void Hide() override {} + void Show(bool show) override {} + + IWindowHandler * GetWindowHandler() override { return handler; } + void SetWindowHandler(IWindowHandler *handler) override { this->handler = handler; } + uint32_t GetWindowId() const override { return 0; } + + IOpenGlWindow * GetOpenGlWindow() override { return nullptr; } + IVulkanWindow * GetVulkanWindow() override { return this; } + + vk::SurfaceKHR CreateSurface(const vk::Instance &instance, const vk::AllocationCallbacks *pAllocator = nullptr) override + { + VkMetalSurfaceCreateInfoEXT surfaceCreateInfo; + surfaceCreateInfo.sType = VK_STRUCTURE_TYPE_METAL_SURFACE_CREATE_INFO_EXT; + surfaceCreateInfo.pNext = NULL; + surfaceCreateInfo.flags = 0; + surfaceCreateInfo.pLayer = (CAMetalLayer*)caMetalLayer; + + VkSurfaceKHR surface; + auto err = vkCreateMetalSurfaceEXT(static_cast(instance), &surfaceCreateInfo, NULL, &surface); + return { surface }; + } + + std::vector GetRequiredInstanceExtensions() override + { + return {}; + } + + Math::Vector2ui GetSize() override { return windowConf.size;} + + void Close() override {} +}; + +@implementation OpenVulkanoViewController { + CADisplayLink* _displayLink; + GraphicsAppManager* manager; + ViewWindow window; + std::unique_ptr app; +} + +-(void) dealloc { + manager->ShutDown(); + [_displayLink release]; + [super dealloc]; +} + +/** Since this is a single-view app, init Vulkan when the view is loaded. */ +-(void) viewDidLoad { + [super viewDidLoad]; + + self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale; + + auto size = self.view.bounds.size; + auto sizeX = size.width * self.view.contentScaleFactor; + auto sizeY = size.height * self.view.contentScaleFactor; + window.Init(self.view.layer, {sizeX, sizeY}); + app = CubesExampleApp::Create(); + manager = new GraphicsAppManager(app.get(), &window); + manager->StartUp(); + + _displayLink = [CADisplayLink displayLinkWithTarget: self selector: @selector(renderLoop)]; + [_displayLink setPreferredFramesPerSecond: 60]; + [_displayLink addToRunLoop: NSRunLoop.currentRunLoop forMode: NSDefaultRunLoopMode]; +} + +-(void) renderLoop { + manager->LoopTick(); +} + +// Allow device rotation to resize the swapchain +-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { + [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; + manager->OnWindowResize(&window, size.width, size.height); +} + +- (BOOL)prefersHomeIndicatorAutoHidden { + return true; +} +@end + + +#pragma mark - +#pragma mark DemoView + +@implementation DemoView + +/** Returns a Metal-compatible layer. */ ++(Class) layerClass { return [CAMetalLayer class]; } + +@end +