Add iOS window host
This commit is contained in:
24
openVulkanoCpp/Host/iOS/OpenVulkanoViewController.h
Normal file
24
openVulkanoCpp/Host/iOS/OpenVulkanoViewController.h
Normal file
@@ -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 <UIKit/UIKit.h>
|
||||
|
||||
|
||||
#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
|
||||
|
||||
141
openVulkanoCpp/Host/iOS/OpenVulkanoViewController.mm
Normal file
141
openVulkanoCpp/Host/iOS/OpenVulkanoViewController.mm
Normal file
@@ -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 <MoltenVK/mvk_vulkan.h>
|
||||
#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<VkInstance>(instance), &surfaceCreateInfo, NULL, &surface);
|
||||
return { surface };
|
||||
}
|
||||
|
||||
std::vector<std::string> GetRequiredInstanceExtensions() override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
Math::Vector2ui GetSize() override { return windowConf.size;}
|
||||
|
||||
void Close() override {}
|
||||
};
|
||||
|
||||
@implementation OpenVulkanoViewController {
|
||||
CADisplayLink* _displayLink;
|
||||
GraphicsAppManager* manager;
|
||||
ViewWindow window;
|
||||
std::unique_ptr<IGraphicsApp> 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
|
||||
|
||||
Reference in New Issue
Block a user