diff --git a/base/vulkanexamplebase.cpp b/base/vulkanexamplebase.cpp index 2e00aa14..28016be2 100644 --- a/base/vulkanexamplebase.cpp +++ b/base/vulkanexamplebase.cpp @@ -2793,7 +2793,7 @@ void VulkanExampleBase::handleMouseMove(int32_t x, int32_t y) viewUpdated = true; } if (mouseButtons.middle) { - camera.translate(glm::vec3(-dx * 0.01f, -dy * 0.01f, 0.0f)); + camera.translate(glm::vec3(-dx * 0.005f, -dy * 0.005f, 0.0f)); viewUpdated = true; } mousePos = glm::vec2((float)x, (float)y); diff --git a/xcode/MVKExample.cpp b/xcode/MVKExample.cpp index 9ed6e36b..ca561249 100644 --- a/xcode/MVKExample.cpp +++ b/xcode/MVKExample.cpp @@ -5,11 +5,14 @@ * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ -#include #include "MVKExample.h" #include "examples.h" +void MVKExample::renderFrame() { + _vulkanExample->renderFrame(); +} + void MVKExample::displayLinkOutputCb() { // SRS - expose VulkanExampleBase::displayLinkOutputCb() to DemoViewController _vulkanExample->displayLinkOutputCb(); } @@ -18,26 +21,44 @@ void MVKExample::setRefreshPeriod(double refreshPeriod) { // SRS - set Vul _vulkanExample->refreshPeriod = refreshPeriod; } -void MVKExample::keyPressed(uint32_t keyCode) { - _vulkanExample->keyPressed(keyCode); +void MVKExample::keyPressed(uint32_t keyChar) { // SRS - handle iOS virtual screen keyboard presses + switch (keyChar) + { + case 'p': + case 'P': + _vulkanExample->paused = !_vulkanExample->paused; + break; + default: + _vulkanExample->keyPressed(keyChar); + break; + } } -void MVKExample::keyDown(uint32_t keyCode) { - switch (keyCode) +void MVKExample::keyDown(uint32_t keyChar) { // SRS - handle physical keyboard key down/up actions + switch (keyChar) { - case kVK_ANSI_P: + case 'p': + case 'P': _vulkanExample->paused = !_vulkanExample->paused; break; - case kVK_ANSI_W: + case 'w': + case 'W': + case 'z': // for French AZERTY keyboards + case 'Z': _vulkanExample->camera.keys.up = true; break; - case kVK_ANSI_S: + case 's': + case 'S': _vulkanExample->camera.keys.down = true; break; - case kVK_ANSI_A: + case 'a': + case 'A': + case 'q': // for French AZERTY keyboards + case 'Q': _vulkanExample->camera.keys.left = true; break; - case kVK_ANSI_D: + case 'd': + case 'D': _vulkanExample->camera.keys.right = true; break; default: @@ -45,19 +66,27 @@ void MVKExample::keyDown(uint32_t keyCode) { } } -void MVKExample::keyUp(uint32_t keyCode) { - switch (keyCode) +void MVKExample::keyUp(uint32_t keyChar) { + switch (keyChar) { - case kVK_ANSI_W: + case 'w': + case 'W': + case 'z': // for French AZERTY keyboards + case 'Z': _vulkanExample->camera.keys.up = false; break; - case kVK_ANSI_S: + case 's': + case 'S': _vulkanExample->camera.keys.down = false; break; - case kVK_ANSI_A: + case 'a': + case 'A': + case 'q': // for French AZERTY keyboards + case 'Q': _vulkanExample->camera.keys.left = false; break; - case kVK_ANSI_D: + case 'd': + case 'D': _vulkanExample->camera.keys.right = false; break; default: @@ -70,12 +99,12 @@ void MVKExample::mouseDown(double x, double y) { _vulkanExample->mouseButtons.left = true; } -void MVKExample::mouseUp(double x, double y) { - _vulkanExample->mousePos = glm::vec2(x, y); +void MVKExample::mouseUp() { _vulkanExample->mouseButtons.left = false; } -void MVKExample::rightMouseDown() { +void MVKExample::rightMouseDown(double x, double y) { + _vulkanExample->mousePos = glm::vec2(x, y); _vulkanExample->mouseButtons.right = true; } @@ -83,7 +112,8 @@ void MVKExample::rightMouseUp() { _vulkanExample->mouseButtons.right = false; } -void MVKExample::otherMouseDown() { +void MVKExample::otherMouseDown(double x, double y) { + _vulkanExample->mousePos = glm::vec2(x, y); _vulkanExample->mouseButtons.middle = true; } @@ -95,22 +125,16 @@ void MVKExample::mouseDragged(double x, double y) { _vulkanExample->mouseDragged(x, y); } -void MVKExample::mouseMoved(double x, double y) { - _vulkanExample->mouseDragged(x, y); -} - void MVKExample::scrollWheel(short wheelDelta) { _vulkanExample->camera.translate(glm::vec3(0.0f, 0.0f, wheelDelta * 0.05f * _vulkanExample->camera.movementSpeed)); } MVKExample::MVKExample(void* view) { _vulkanExample = new VulkanExample(); - width = _vulkanExample->width; // SRS - Get desired window size from VulkanExampleBase instance - height = _vulkanExample->height; _vulkanExample->initVulkan(); _vulkanExample->setupWindow(view); _vulkanExample->prepare(); - _vulkanExample->renderLoop(); // SRS - Init destWidth & destHeight, then fall through and return + _vulkanExample->renderLoop(); // SRS - init VulkanExampleBase::destWidth & destHeight, then fall through and return } MVKExample::~MVKExample() { diff --git a/xcode/MVKExample.h b/xcode/MVKExample.h index 8e5acf47..5b647c63 100644 --- a/xcode/MVKExample.h +++ b/xcode/MVKExample.h @@ -13,24 +13,21 @@ class MVKExample { public: - uint32_t width; // SRS - expose VulkanExampleBase initial window size to DemoViewController - uint32_t height; - + void renderFrame(); void displayLinkOutputCb(); // SRS - expose VulkanExampleBase::displayLinkOutputCb() to DemoViewController void setRefreshPeriod(double refreshPeriod); // SRS - set VulkanExampleBase::refreshPeriod from DemoViewController displayLink - void keyPressed(uint32_t keyCode); // SRS - expose keyboard events to DemoViewController - void keyDown(uint32_t keyCode); - void keyUp(uint32_t keyCode); + void keyPressed(uint32_t keyChar); // SRS - expose keyboard events to DemoViewController + void keyDown(uint32_t keyChar); + void keyUp(uint32_t keyChar); void mouseDown(double x, double y); // SRS - expose mouse events to DemoViewController - void mouseUp(double x, double y); - void rightMouseDown(); + void mouseUp(); + void rightMouseDown(double x, double y); void rightMouseUp(); - void otherMouseDown(); + void otherMouseDown(double x, double y); void otherMouseUp(); void mouseDragged(double x, double y); - void mouseMoved(double x, double y); void scrollWheel(short wheelDelta); MVKExample(void* view); diff --git a/xcode/examples.h b/xcode/examples.h index 68182c49..4268deca 100644 --- a/xcode/examples.h +++ b/xcode/examples.h @@ -17,7 +17,7 @@ * * For example, to run the pipelines example, you would add the MVK_pipelines define macro * to the Preprocessor Macros (aka GCC_PREPROCESSOR_DEFINITIONS) entry of the Xcode project, - * overwriting any otheor value there. + * overwriting any other value there. * * If you choose to add a #define statement to this file, be sure to clear the existing macro * from the Preprocessor Macros (aka GCC_PREPROCESSOR_DEFINITIONS) compiler setting in Xcode. @@ -27,11 +27,12 @@ // In the list below, the comments indicate entries that, // under certain conditions, that may not run as expected. -#define MVK_vulkanscene +// Uncomment the next line and select example here if not using a Preprocessor Macro to define example +//#define MVK_vulkanscene // COMMON - Include VulkanglTFModel.cpp in all examples other than ones that already include/customize tiny_gltf.h directly #if !defined(MVK_gltfloading) && !defined(MVK_gltfskinning) && !defined(MVK_gltfscenerendering) && !defined(MVK_vertexattributes) -#include "../base/VulkanglTFModel.cpp" +# include "../base/VulkanglTFModel.cpp" #endif diff --git a/xcode/examples.xcodeproj/project.pbxproj b/xcode/examples.xcodeproj/project.pbxproj index 173ea0da..4b9237ca 100644 --- a/xcode/examples.xcodeproj/project.pbxproj +++ b/xcode/examples.xcodeproj/project.pbxproj @@ -638,12 +638,13 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = NO; INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "@executable_path"; LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/MoltenVK/dylib/iOS\""; SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; TARGETED_DEVICE_FAMILY = "1,2"; - VALID_ARCHS = arm64; + VALID_ARCHS = "$(ARCHS_STANDARD)"; }; name = Debug; }; @@ -659,12 +660,13 @@ ); GCC_WARN_64_TO_32_BIT_CONVERSION = NO; INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "@executable_path"; LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/MoltenVK/dylib/iOS\""; SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; TARGETED_DEVICE_FAMILY = "1,2"; - VALID_ARCHS = arm64; + VALID_ARCHS = "$(ARCHS_STANDARD)"; }; name = Release; }; @@ -676,11 +678,7 @@ COMBINE_HIDPI_IMAGES = YES; GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - _DEBUG, - VK_USE_PLATFORM_MACOS_MVK, - ); - "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = ( + "$(inherited)", "DEBUG=1", _DEBUG, VK_USE_PLATFORM_MACOS_MVK, @@ -700,13 +698,15 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; GCC_PREFIX_HEADER = ""; - GCC_PREPROCESSOR_DEFINITIONS = VK_USE_PLATFORM_MACOS_MVK; - "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = VK_USE_PLATFORM_MACOS_MVK; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + VK_USE_PLATFORM_MACOS_MVK, + ); INFOPLIST_FILE = "$(SRCROOT)/macOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "@executable_path"; LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/MoltenVK/dylib/macOS\""; MACOSX_DEPLOYMENT_TARGET = 10.11; - ONLY_ACTIVE_ARCH = YES; + ONLY_ACTIVE_ARCH = NO; SDKROOT = macosx; }; name = Release; diff --git a/xcode/ios/DemoViewController.mm b/xcode/ios/DemoViewController.mm index a8d4ca3c..616ba39f 100644 --- a/xcode/ios/DemoViewController.mm +++ b/xcode/ios/DemoViewController.mm @@ -37,13 +37,22 @@ const std::string getAssetPath() { [_displayLink setFrameInterval: 60 / fps]; [_displayLink addToRunLoop: NSRunLoop.currentRunLoop forMode: NSDefaultRunLoopMode]; - // Setup tap gesture to toggle virtual keyboard + // SRS - set VulkanExampleBase::refreshPeriod to calibrate the frame animation rate + _mvkExample->setRefreshPeriod( 1.0 / fps ); + + // Setup double tap gesture to toggle virtual keyboard UITapGestureRecognizer* tapSelector = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(handleTapGesture:)]; - tapSelector.numberOfTapsRequired = 1; + tapSelector.numberOfTapsRequired = 2; tapSelector.cancelsTouchesInView = YES; [self.view addGestureRecognizer: tapSelector]; + // SRS - Setup pinch gesture to detect and activate zoom + UIPinchGestureRecognizer* pinchSelector = [[UIPinchGestureRecognizer alloc] + initWithTarget: self action: @selector(handlePinchGesture:)]; + pinchSelector.cancelsTouchesInView = YES; + [self.view addGestureRecognizer: pinchSelector]; + _viewHasAppeared = NO; } @@ -55,8 +64,8 @@ const std::string getAssetPath() { -(BOOL) canBecomeFirstResponder { return _viewHasAppeared; } -(void) renderFrame { - //_mvkExample->renderFrame(); - _mvkExample->nextFrame(); // SRS - Call MVKExample::nextFrame() to animate frames vs. MVKExample::renderFrame() for static image + //_mvkExample->renderFrame(); + _mvkExample->displayLinkOutputCb(); // SRS - Call displayLinkOutputCb() to animate frames vs. renderFrame() for static image } -(void) dealloc { @@ -73,18 +82,13 @@ const std::string getAssetPath() { } } -// Display and hide the keyboard by tapping on the view +// Display and hide the keyboard by double tapping on the view -(void) handleTapGesture: (UITapGestureRecognizer*) gestureRecognizer { if (gestureRecognizer.state == UIGestureRecognizerStateEnded) { [self toggleKeyboard]; } } -// Handle keyboard input --(void) handleKeyboardInput: (unichar) keycode { - _mvkExample->keyPressed(keycode); -} - #pragma mark UIKeyInput methods @@ -93,16 +97,73 @@ const std::string getAssetPath() { // A key on the keyboard has been pressed. -(void) insertText: (NSString*) text { - unichar keycode = (text.length > 0) ? [text characterAtIndex: 0] : 0; - [self handleKeyboardInput: keycode]; + unichar keychar = (text.length > 0) ? [text characterAtIndex: 0] : 0; + _mvkExample->keyPressed(keychar); } // The delete backward key has been pressed. -(void) deleteBackward { - [self handleKeyboardInput: 0x33]; + _mvkExample->keyPressed(0x7F); } +#pragma mark UITouch methods + +// SRS - Handle touch events +-(CGPoint) getTouchLocalPoint:(UIEvent*) theEvent { + UITouch *touch = [[theEvent allTouches] anyObject]; + CGPoint point = [touch locationInView:self.view]; + point.x = point.x * self.view.contentScaleFactor; + point.y = point.y * self.view.contentScaleFactor; + return point; +} + +-(void) touchesBegan:(NSSet*) touches withEvent:(UIEvent*) theEvent { + auto point = [self getTouchLocalPoint:theEvent]; + if (touches.count == 1) { + // Single touch for imgui select and camera rotation + _mvkExample->mouseDown(point.x, point.y); + } + else { + // Multi-touch for swipe translation (note: pinch gesture will cancel/override) + _mvkExample->otherMouseDown(point.x, point.y); + } +} + +-(void) touchesMoved:(NSSet*) touches withEvent:(UIEvent*) theEvent { + auto point = [self getTouchLocalPoint:theEvent]; + _mvkExample->mouseDragged(point.x, point.y); +} + +-(void) touchesEnded:(NSSet*) touches withEvent:(UIEvent*) theEvent { + _mvkExample->mouseUp(); + _mvkExample->otherMouseUp(); +} + +-(void) touchesCancelled:(NSSet*) touches withEvent:(UIEvent*) theEvent { + _mvkExample->mouseUp(); + _mvkExample->otherMouseUp(); +} + +// SRS - Respond to pinch gestures for zoom +-(void) handlePinchGesture: (UIPinchGestureRecognizer*) gestureRecognizer { + if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { + auto point = [gestureRecognizer locationInView:self.view]; + point.x = point.x * self.view.contentScaleFactor; + point.y = point.y * self.view.contentScaleFactor; + _mvkExample->rightMouseDown(point.x, point.y); + } + else if (gestureRecognizer.state == UIGestureRecognizerStateChanged) { + auto point = [gestureRecognizer locationInView:self.view]; + point.x = point.x * self.view.contentScaleFactor; + point.y = point.y * self.view.contentScaleFactor; + _mvkExample->mouseDragged(point.x, point.y - gestureRecognizer.view.frame.size.height / 2.0 * log(gestureRecognizer.scale)); + } + else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) { + _mvkExample->rightMouseUp(); + } +} + @end diff --git a/xcode/ios/Info.plist b/xcode/ios/Info.plist index eb0fa65a..e61fdb6f 100644 --- a/xcode/ios/Info.plist +++ b/xcode/ios/Info.plist @@ -20,6 +20,8 @@ APPL CFBundleVersion 1.0 + CFBundleShortVersionString + 1.0 LSApplicationCategoryType UIMainStoryboardFile diff --git a/xcode/macos/DemoViewController.mm b/xcode/macos/DemoViewController.mm index c1e3cf1d..ea33c1bd 100644 --- a/xcode/macos/DemoViewController.mm +++ b/xcode/macos/DemoViewController.mm @@ -48,15 +48,11 @@ MVKExample* _mvkExample; CVDisplayLinkStart(_displayLink); } -// SRS - Set window's initial content size and set VulkanExampleBase::refreshPeriod from the displayLink +// SRS - Center the window and set VulkanExampleBase::refreshPeriod from the active displayLink -(void) viewWillAppear { [super viewWillAppear]; NSWindow* window = self.view.window; - NSSize viewSize; - viewSize.width = _mvkExample->width; - viewSize.height = _mvkExample->height; - [window setContentSize:viewSize]; [window center]; _mvkExample->setRefreshPeriod(CVDisplayLinkGetActualOutputVideoRefreshPeriod(_displayLink)); @@ -94,12 +90,15 @@ MVKExample* _mvkExample; // SRS - Handle keyboard events -(void) keyDown:(NSEvent*) theEvent { - _mvkExample->keyPressed(theEvent.keyCode); - _mvkExample->keyDown(theEvent.keyCode); + NSString *text = [theEvent charactersIgnoringModifiers]; + unichar keychar = (text.length > 0) ? [text characterAtIndex: 0] : 0; + _mvkExample->keyDown(keychar); } -(void) keyUp:(NSEvent*) theEvent { - _mvkExample->keyUp(theEvent.keyCode); + NSString *text = [theEvent charactersIgnoringModifiers]; + unichar keychar = (text.length > 0) ? [text characterAtIndex: 0] : 0; + _mvkExample->keyUp(keychar); } // SRS - Handle mouse events @@ -116,12 +115,12 @@ MVKExample* _mvkExample; } -(void) mouseUp:(NSEvent*) theEvent { - auto point = [self getMouseLocalPoint:theEvent]; - _mvkExample->mouseUp(point.x, point.y); + _mvkExample->mouseUp(); } -(void) rightMouseDown:(NSEvent*) theEvent { - _mvkExample->rightMouseDown(); + auto point = [self getMouseLocalPoint:theEvent]; + _mvkExample->rightMouseDown(point.x, point.y); } -(void) rightMouseUp:(NSEvent*) theEvent { @@ -129,7 +128,8 @@ MVKExample* _mvkExample; } -(void) otherMouseDown:(NSEvent*) theEvent { - _mvkExample->otherMouseDown(); + auto point = [self getMouseLocalPoint:theEvent]; + _mvkExample->otherMouseDown(point.x, point.y); } -(void) otherMouseUp:(NSEvent*) theEvent { @@ -151,11 +151,6 @@ MVKExample* _mvkExample; _mvkExample->mouseDragged(point.x, point.y); } --(void) mouseMoved:(NSEvent*) theEvent { - auto point = [self getMouseLocalPoint:theEvent]; - _mvkExample->mouseDragged(point.x, point.y); -} - -(void) scrollWheel:(NSEvent*) theEvent { short wheelDelta = [theEvent deltaY]; _mvkExample->scrollWheel(wheelDelta); diff --git a/xcode/macos/Resources/Main.storyboard b/xcode/macos/Resources/Main.storyboard index e682969c..6ba73adf 100644 --- a/xcode/macos/Resources/Main.storyboard +++ b/xcode/macos/Resources/Main.storyboard @@ -103,7 +103,7 @@ - + @@ -122,7 +122,7 @@ - +