Start refactoring of OpenVulkanoView implementation (#1)
This commit is contained in:
88
openVulkanoCpp/Host/iOS/MetalViewWindow.h
Normal file
88
openVulkanoCpp/Host/iOS/MetalViewWindow.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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 "Base/UI/IVulkanWindow.hpp"
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
class MetalViewWindow final : public IVulkanWindow
|
||||
{
|
||||
WindowConfiguration windowConf;
|
||||
IWindowHandler* handler = nullptr;
|
||||
void* caMetalLayer = nullptr;
|
||||
bool tickHandler = true;
|
||||
|
||||
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 { windowConf.size = { width, height }; }
|
||||
|
||||
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; }
|
||||
|
||||
bool WindowHasBeenDestroyed() const override { return false; }
|
||||
|
||||
void SetWindowHasBeenDestroyed() override
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
void* GetNativeWindowHandle() override { return caMetalLayer; }
|
||||
|
||||
vk::SurfaceKHR CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator = nullptr) override;
|
||||
|
||||
std::vector<std::string> GetRequiredInstanceExtensions() override;
|
||||
|
||||
Math::Vector2ui GetSize() override { return windowConf.size; }
|
||||
|
||||
void Close() override {}
|
||||
|
||||
void OnResize(uint32_t width, uint32_t height);
|
||||
|
||||
void TickHandler();
|
||||
};
|
||||
}
|
||||
53
openVulkanoCpp/Host/iOS/MetalViewWindow.mm
Normal file
53
openVulkanoCpp/Host/iOS/MetalViewWindow.mm
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
// Makre usre the Molten include is first!
|
||||
#include <MoltenVK/mvk_vulkan.h>
|
||||
|
||||
#include "MetalViewWindow.h"
|
||||
#include "Base/Logger.hpp"
|
||||
#include "Host/GraphicsAppManager.hpp"
|
||||
|
||||
#import <MetalKit/MTKView.h>
|
||||
|
||||
namespace OpenVulkano
|
||||
{
|
||||
vk::SurfaceKHR MetalViewWindow::CreateSurface(const vk::Instance& instance, const vk::AllocationCallbacks* pAllocator)
|
||||
{
|
||||
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> MetalViewWindow::GetRequiredInstanceExtensions()
|
||||
{
|
||||
return {}; //TODO
|
||||
}
|
||||
|
||||
void MetalViewWindow::OnResize(uint32_t newWidth, uint32_t newHeight)
|
||||
{
|
||||
Logger::WINDOW->debug("Window (id: {0}) resized (width: {1}, height: {2})", GetWindowId(), newWidth, newHeight);
|
||||
if (handler)
|
||||
handler->OnWindowResize(this, newWidth, newHeight);
|
||||
}
|
||||
|
||||
void MetalViewWindow::TickHandler()
|
||||
{
|
||||
if (tickHandler)
|
||||
{
|
||||
if (auto graphApp = dynamic_cast<GraphicsAppManager*>(handler))
|
||||
{
|
||||
graphApp->LoopTick();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,11 @@
|
||||
|
||||
//@interface OpenVulkanoView : UIView
|
||||
@interface OpenVulkanoView : MTKView
|
||||
-(void*)GetWindow;
|
||||
|
||||
-(void)WillAppear;
|
||||
-(void)DidAppear;
|
||||
-(void)WillDisappear;
|
||||
-(void)DidDisappear;
|
||||
-(void)DidUnload;
|
||||
@end
|
||||
|
||||
@@ -8,21 +8,57 @@
|
||||
|
||||
#include "Input/Touch/InputDeviceTouch.hpp"
|
||||
#include "Input/InputManager.hpp"
|
||||
#include "MetalViewWindow.h"
|
||||
#include <map>
|
||||
|
||||
#import <MetalKit/MTKView.h>
|
||||
|
||||
using namespace OpenVulkano;
|
||||
|
||||
#pragma mark MetalViewDelegate
|
||||
@interface MetalViewDelegate : NSObject<MTKViewDelegate>
|
||||
- (void) mtkView:(MTKView *) view drawableSizeWillChange:(CGSize) size;
|
||||
- (void) drawInMTKView:(MTKView *) view;
|
||||
@end
|
||||
|
||||
@implementation MetalViewDelegate
|
||||
{
|
||||
MetalViewWindow* window;
|
||||
}
|
||||
|
||||
- (id)initWithWindow:(MetalViewWindow*)win
|
||||
{
|
||||
window = win;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) mtkView:(MTKView *) view drawableSizeWillChange:(CGSize) size
|
||||
{
|
||||
window->OnResize(size.width, size.height);
|
||||
}
|
||||
|
||||
- (void) drawInMTKView:(MTKView *) view
|
||||
{
|
||||
@autoreleasepool {
|
||||
window->TickHandler();
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark OpenVulkanoView
|
||||
|
||||
using namespace OpenVulkano;
|
||||
|
||||
@interface OpenVulkanoView()
|
||||
{
|
||||
CADisplayLink * m_displayLink;
|
||||
CADisplayLink* m_displayLink;
|
||||
MetalViewDelegate* m_mtdelegate;
|
||||
std::map<UITouch*, int32_t> m_touchToIdMap;
|
||||
Input::InputDeviceTouch m_touchDevice;
|
||||
MetalViewWindow m_window;
|
||||
}
|
||||
@end
|
||||
|
||||
#pragma mark OpenVulkanoView Implementation
|
||||
@implementation OpenVulkanoView
|
||||
/** Returns a Metal-compatible layer. */
|
||||
+(Class) layerClass { return [CAMetalLayer class]; }
|
||||
@@ -45,8 +81,28 @@ using namespace OpenVulkano;
|
||||
|
||||
- (void)commonInit {
|
||||
[self setMultipleTouchEnabled:YES];
|
||||
|
||||
self.contentScaleFactor = UIScreen.mainScreen.nativeScale / 1.5f;
|
||||
|
||||
auto size = self.bounds.size;
|
||||
auto sizeX = size.width * self.contentScaleFactor;
|
||||
auto sizeY = size.height * self.contentScaleFactor;
|
||||
m_window.Init(self.layer, {sizeX, sizeY});
|
||||
|
||||
m_touchDevice.Init(); //TODO link window
|
||||
Input::InputManager::GetInstance()->RegisterInputDevice(&m_touchDevice);
|
||||
|
||||
if ([self isKindOfClass:[MTKView class]]) {
|
||||
MTKView* mtkView = (MTKView*)(self);
|
||||
m_mtdelegate = [[MetalViewDelegate alloc] initWithWindow:&m_window];
|
||||
[mtkView setDelegate:m_mtdelegate];
|
||||
mtkView.preferredFramesPerSecond = 60;
|
||||
} else {
|
||||
m_displayLink = [CADisplayLink displayLinkWithTarget: self selector: @selector(renderLoop)];
|
||||
[m_displayLink setPreferredFramesPerSecond: 60];
|
||||
[m_displayLink addToRunLoop: NSRunLoop.currentRunLoop forMode: NSDefaultRunLoopMode];
|
||||
m_displayLink.paused = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
@@ -55,9 +111,23 @@ using namespace OpenVulkano;
|
||||
}
|
||||
Input::InputManager::GetInstance()->UnregisterInputDevice(&m_touchDevice);
|
||||
m_touchDevice.Close();
|
||||
[m_displayLink release];
|
||||
[m_mtdelegate release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
|
||||
if (m_displayLink)
|
||||
{ // Only use this update method if we use display link instead of metal delegate
|
||||
auto size = self.bounds.size;
|
||||
auto sizeX = size.width * self.contentScaleFactor;
|
||||
auto sizeY = size.height * self.contentScaleFactor;
|
||||
m_window.OnResize(sizeX, sizeY);
|
||||
}
|
||||
}
|
||||
|
||||
- (Math::Vector2f)getTouchPosition:(UITouch*)touch
|
||||
{
|
||||
CGPoint uitouchLocation = [touch locationInView:touch.view];
|
||||
@@ -121,5 +191,44 @@ using namespace OpenVulkano;
|
||||
}
|
||||
}
|
||||
|
||||
-(void*)GetWindow
|
||||
{
|
||||
return &m_window;
|
||||
}
|
||||
|
||||
-(void) renderLoop
|
||||
{
|
||||
m_window.TickHandler();
|
||||
}
|
||||
|
||||
-(void)WillAppear
|
||||
{
|
||||
if (m_displayLink) m_displayLink.paused = NO;
|
||||
}
|
||||
|
||||
-(void)DidAppear
|
||||
{
|
||||
if (m_displayLink) m_displayLink.paused = NO;
|
||||
}
|
||||
|
||||
-(void)WillDisappear
|
||||
{
|
||||
if (m_displayLink) m_displayLink.paused = YES;
|
||||
}
|
||||
|
||||
-(void)DidDisappear
|
||||
{
|
||||
if (m_displayLink) m_displayLink.paused = YES;
|
||||
}
|
||||
|
||||
-(void)DidUnload
|
||||
{
|
||||
if (m_displayLink)
|
||||
{
|
||||
[m_displayLink invalidate];
|
||||
[m_displayLink release];
|
||||
m_displayLink = nil;
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@@ -4,12 +4,19 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#import "OpenVulkanoView.h"
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark OpenVulkanoViewController
|
||||
|
||||
@interface OpenVulkanoViewController : UIViewController
|
||||
{
|
||||
@public OpenVulkanoView* openVulkanoView;
|
||||
@public BOOL fixOpenVulkanoViewOrientation;
|
||||
}
|
||||
-(void*) makeGraphicsApp;
|
||||
@end
|
||||
|
||||
|
||||
@@ -11,128 +11,32 @@
|
||||
#include "Base/UI/IVulkanWindow.hpp"
|
||||
|
||||
#import <MetalKit/MTKView.h>
|
||||
#import "OpenVulkanoView.h"
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark OpenVulkanoViewController
|
||||
|
||||
using namespace OpenVulkano;
|
||||
|
||||
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 { windowConf.size = { width, height }; }
|
||||
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; }
|
||||
|
||||
bool WindowHasBeenDestroyed() const override { return false; }
|
||||
void SetWindowHasBeenDestroyed() override {}
|
||||
|
||||
void* GetNativeWindowHandle() override { return caMetalLayer; }
|
||||
|
||||
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 {}
|
||||
};
|
||||
|
||||
@interface MetalViewDelegate : NSObject<MTKViewDelegate>
|
||||
- (id)initWithGAM:(GraphicsAppManager*)gam;
|
||||
- (void) mtkView:(MTKView *) view drawableSizeWillChange:(CGSize) size;
|
||||
- (void) drawInMTKView:(MTKView *) view;
|
||||
@end
|
||||
|
||||
@implementation MetalViewDelegate
|
||||
{
|
||||
GraphicsAppManager* manager;
|
||||
IWindow* window;
|
||||
}
|
||||
|
||||
- (id)initWithGAM:(GraphicsAppManager*)gam win:(IWindow*)win
|
||||
{
|
||||
manager = gam;
|
||||
window = win;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) mtkView:(MTKView *) view drawableSizeWillChange:(CGSize) size
|
||||
{
|
||||
manager->OnWindowResize(window, size.width, size.height);
|
||||
}
|
||||
|
||||
- (void) drawInMTKView:(MTKView *) view
|
||||
{
|
||||
@autoreleasepool {
|
||||
manager->LoopTick();
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation OpenVulkanoViewController {
|
||||
CADisplayLink* _displayLink;
|
||||
GraphicsAppManager* manager;
|
||||
ViewWindow window;
|
||||
std::unique_ptr<IGraphicsApp> app;
|
||||
MetalViewDelegate* mtdelegate;
|
||||
}
|
||||
|
||||
-(void*) makeGraphicsApp {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
-(id)init {
|
||||
[super init];
|
||||
openVulkanoView = nil;
|
||||
fixOpenVulkanoViewOrientation = false;
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void) dealloc {
|
||||
manager->ShutDown();
|
||||
[_displayLink release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@@ -140,61 +44,45 @@ public:
|
||||
-(void) viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale / 1.5f;
|
||||
|
||||
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});
|
||||
if (openVulkanoView == nil && [self.view isKindOfClass:[OpenVulkanoView class]]) {
|
||||
openVulkanoView = (OpenVulkanoView*)self.view;
|
||||
}
|
||||
|
||||
//TODO check if type is correct
|
||||
IGraphicsApp* appPtr = static_cast<IGraphicsApp*>(self.makeGraphicsApp);
|
||||
if (!appPtr) throw std::runtime_error("Failed to create graphics app");
|
||||
app = std::unique_ptr<IGraphicsApp>(appPtr);
|
||||
manager = new GraphicsAppManager(app.get(), &window);
|
||||
manager = new GraphicsAppManager(app.get(), (IVulkanWindow*)[openVulkanoView GetWindow]);
|
||||
manager->StartUp();
|
||||
|
||||
if ([self.view isKindOfClass:[MTKView class]]) {
|
||||
MTKView* mtkView = (MTKView*)(self.view);
|
||||
mtdelegate = [[MetalViewDelegate alloc] initWithGAM:manager win:&window];
|
||||
[mtkView setDelegate:mtdelegate];
|
||||
mtkView.preferredFramesPerSecond = 60;
|
||||
} else {
|
||||
_displayLink = [CADisplayLink displayLinkWithTarget: self selector: @selector(renderLoop)];
|
||||
[_displayLink setPreferredFramesPerSecond: 60];
|
||||
[_displayLink addToRunLoop: NSRunLoop.currentRunLoop forMode: NSDefaultRunLoopMode];
|
||||
}
|
||||
}
|
||||
|
||||
-(void) viewWillAppear:(BOOL)animated {
|
||||
if (openVulkanoView != nil) { [openVulkanoView willAppear]; }
|
||||
[super viewWillAppear:animated];
|
||||
self.view.contentScaleFactor = UIScreen.mainScreen.nativeScale / 1.5f;
|
||||
}
|
||||
|
||||
auto size = self.view.bounds.size;
|
||||
auto sizeX = size.width * self.view.contentScaleFactor;
|
||||
auto sizeY = size.height * self.view.contentScaleFactor;
|
||||
manager->OnWindowResize(&window, sizeX, sizeY);
|
||||
-(void) viewDidAppear:(BOOL)animated {
|
||||
if (openVulkanoView != nil) { [openVulkanoView DidAppear]; }
|
||||
[super viewDidAppear:animated];
|
||||
}
|
||||
|
||||
-(void) viewWillDisappear:(BOOL)animated {
|
||||
if (openVulkanoView != nil) { [openVulkanoView WillDisappear]; }
|
||||
[super viewWillDisappear:animated];
|
||||
}
|
||||
|
||||
-(void) viewDidDisappear:(BOOL)animated {
|
||||
[_displayLink release];
|
||||
_displayLink = nil;
|
||||
if (openVulkanoView != nil) { [openVulkanoView DidDisappear]; }
|
||||
[super viewDidDisappear:animated];
|
||||
}
|
||||
|
||||
-(void) viewDidUnload {
|
||||
[_displayLink release];
|
||||
_displayLink = nil;
|
||||
if (openVulkanoView != nil) { [openVulkanoView DidUnload]; }
|
||||
[super viewDidUnload];
|
||||
}
|
||||
|
||||
-(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 {
|
||||
|
||||
Reference in New Issue
Block a user