184 lines
5.0 KiB
Plaintext
184 lines
5.0 KiB
Plaintext
/*
|
|
* 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; }
|
|
|
|
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;
|
|
}
|
|
|
|
- (id)initWithGAM:(GraphicsAppManager*)gam
|
|
{
|
|
manager = gam;
|
|
return self;
|
|
}
|
|
|
|
- (void) mtkView:(MTKView *) view drawableSizeWillChange:(CGSize) size
|
|
{}
|
|
|
|
- (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 CubesExampleApp::Create();
|
|
}
|
|
|
|
-(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});
|
|
//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->StartUp();
|
|
|
|
OpenVulkanoView* mtkView = (OpenVulkanoView*)(self.view);
|
|
mtdelegate = [[MetalViewDelegate alloc] initWithGAM:manager];
|
|
[mtkView setDelegate:mtdelegate];
|
|
mtkView.preferredFramesPerSecond = 60;
|
|
}
|
|
|
|
-(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 OpenVulkanoView
|
|
|
|
@implementation OpenVulkanoView
|
|
|
|
/** Returns a Metal-compatible layer. */
|
|
+(Class) layerClass { return [CAMetalLayer class]; }
|
|
|
|
@end
|
|
|