Skip to content

Commit 9660149

Browse files
committed
Updates to iOS and macOS functionality using MoltenVK.
Use getAssetPath() instead of ASSET_PATH to support broader range of platforms. Multisampling example determines sample rate from device at runtime. Move example wrapper code from DemoViewController.mm to dedicated MVKExample.cpp file. Remove AssImp libraries for iOS and macOS from repo, and add instructions for generating them from AssImp source files. Update general README.md file to mention support for iOS and macOS platforms. Add Apple logo for README.md. Update Vulkan logo to current registered TM logo. Update copyright notice of MoltenVK example files to MIT license. Examples use +/- on main keyboard, instead of numpad.
1 parent 8b30d7b commit 9660149

27 files changed

+317
-159
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ Note that you need [assimp](https://github.com/assimp/assimp) in order to compil
3333

3434
Building on Android is done using the [Android NDK](http://developer.android.com/tools/sdk/ndk/index.html) and requires a device that supports Vulkan. Please see the [Android readme](./android/README.md) on how to build and deploy the examples.
3535

36+
## <img src="./images/applelogo.png" alt="" height="32px"> [iOS and macOS](xcode/)
37+
38+
Building for *iOS* and *macOS* is done using the [examples](xcode/examples.xcodeproj) *Xcode* project found in the [xcode](xcode) directory. These examples use the [**MoltenVK**](https://moltengl.com/moltenvk) Vulkan driver to provide Vulkan support on *iOS* and *macOS*, and require an *iOS* or *macOS* device that supports *Metal*. Please see the [MoltenVK Examples readme](xcode/README_MoltenVK_Examples.md) for more info on acquiring **MoltenVK** and building and deploying the examples on *iOS* and *macOS*.
39+
3640
## Additional asset pack
3741

3842
**Note:** Binary assets (textures, models) will no longer be added directly to the repository to keep it's size down, so newer examples will require the download of an [additional asset pack](data/README.md).

base/keycodes.hpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555

5656
#elif defined(VK_USE_PLATFORM_IOS_MVK)
5757
// Use numeric keys instead of function keys.
58+
// Use main keyboard plus/minus instead of keypad plus/minus
5859
// Use Delete key instead of Escape key.
5960
#define KEY_ESCAPE 0x33
6061
#define KEY_F1 '1'
@@ -77,8 +78,9 @@
7778
#define KEY_T 't'
7879

7980
#elif defined(VK_USE_PLATFORM_MACOS_MVK)
80-
// For iOS UX compatibility:
81+
// For compatibility with iOS UX and absent keypad on MacBook:
8182
// - Use numeric keys instead of function keys
83+
// - Use main keyboard plus/minus instead of keypad plus/minus
8284
// - Use Delete key instead of Escape key
8385
#define KEY_ESCAPE 0x33
8486
#define KEY_F1 0x12
@@ -91,8 +93,8 @@
9193
#define KEY_D 0x02
9294
#define KEY_P 0x23
9395
#define KEY_SPACE 0x31
94-
#define KEY_KPADD 0x45
95-
#define KEY_KPSUB 0x4E
96+
#define KEY_KPADD 0x18
97+
#define KEY_KPSUB 0x1B
9698
#define KEY_B 0x0B
9799
#define KEY_F 0x03
98100
#define KEY_L 0x25

hdr/hdr.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ class VulkanExample : public VulkanExampleBase
606606
std::vector<std::string> filenames = { "geosphere.obj", "teapot.dae", "torusknot.obj", "venus.fbx" };
607607
for (auto file : filenames) {
608608
vks::Model model;
609-
model.loadFromFile(ASSET_PATH "models/" + file, vertexLayout, 0.05f * (file == "venus.fbx" ? 3.0f : 1.0f), vulkanDevice, queue);
609+
model.loadFromFile(getAssetPath() + "models/" + file, vertexLayout, 0.05f * (file == "venus.fbx" ? 3.0f : 1.0f), vulkanDevice, queue);
610610
models.objects.push_back(model);
611611
}
612612
// Load HDR cube map

images/applelogo.png

15.7 KB
Loading

images/vulkanlogo.png

10 KB
Loading

libs/assimp/ios/libassimp.a

-25.8 MB
Binary file not shown.

libs/assimp/ios/libzlibstatic.a

-130 KB
Binary file not shown.

libs/assimp/macos/libassimp.dylib

-14.9 MB
Binary file not shown.

multisampling/multisampling.cpp

+20-8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <string.h>
1212
#include <assert.h>
1313
#include <vector>
14+
#include <algorithm>
1415

1516
#define GLM_FORCE_RADIANS
1617
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
@@ -25,7 +26,6 @@
2526

2627
#define VERTEX_BUFFER_BIND_ID 0
2728
#define ENABLE_VALIDATION false
28-
#define SAMPLE_COUNT VK_SAMPLE_COUNT_8_BIT
2929

3030
struct {
3131
struct {
@@ -44,6 +44,7 @@ class VulkanExample : public VulkanExampleBase
4444
{
4545
public:
4646
bool useSampleShading = false;
47+
VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
4748

4849
struct {
4950
vks::Texture2D colorMap;
@@ -123,7 +124,7 @@ class VulkanExample : public VulkanExampleBase
123124
void setupMultisampleTarget()
124125
{
125126
// Check if device supports requested sample count for color and depth frame buffer
126-
assert((deviceProperties.limits.framebufferColorSampleCounts >= SAMPLE_COUNT) && (deviceProperties.limits.framebufferDepthSampleCounts >= SAMPLE_COUNT));
127+
assert((deviceProperties.limits.framebufferColorSampleCounts >= sampleCount) && (deviceProperties.limits.framebufferDepthSampleCounts >= sampleCount));
127128

128129
// Color target
129130
VkImageCreateInfo info = vks::initializers::imageCreateInfo();
@@ -136,7 +137,7 @@ class VulkanExample : public VulkanExampleBase
136137
info.arrayLayers = 1;
137138
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
138139
info.tiling = VK_IMAGE_TILING_OPTIMAL;
139-
info.samples = SAMPLE_COUNT;
140+
info.samples = sampleCount;
140141
// Image will only be used as a transient target
141142
info.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
142143
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -184,7 +185,7 @@ class VulkanExample : public VulkanExampleBase
184185
info.arrayLayers = 1;
185186
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
186187
info.tiling = VK_IMAGE_TILING_OPTIMAL;
187-
info.samples = SAMPLE_COUNT;
188+
info.samples = sampleCount;
188189
// Image will only be used as a transient target
189190
info.usage = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
190191
info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
@@ -230,7 +231,7 @@ class VulkanExample : public VulkanExampleBase
230231

231232
// Multisampled attachment that we render to
232233
attachments[0].format = swapChain.colorFormat;
233-
attachments[0].samples = SAMPLE_COUNT;
234+
attachments[0].samples = sampleCount;
234235
attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
235236
// No longer required after resolve, this may save some bandwidth on certain GPUs
236237
attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
@@ -252,7 +253,7 @@ class VulkanExample : public VulkanExampleBase
252253

253254
// Multisampled depth attachment we render to
254255
attachments[2].format = depthFormat;
255-
attachments[2].samples = SAMPLE_COUNT;
256+
attachments[2].samples = sampleCount;
256257
attachments[2].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
257258
attachments[2].storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
258259
attachments[2].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@@ -630,7 +631,7 @@ class VulkanExample : public VulkanExampleBase
630631
shaderStages[0] = loadShader(getAssetPath() + "shaders/mesh/mesh.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
631632
shaderStages[1] = loadShader(getAssetPath() + "shaders/mesh/mesh.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
632633
// Setup multi sampling
633-
multisampleState.rasterizationSamples = SAMPLE_COUNT; // Number of samples to use for rasterization
634+
multisampleState.rasterizationSamples = sampleCount; // Number of samples to use for rasterization
634635

635636
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.MSAA));
636637

@@ -693,6 +694,7 @@ class VulkanExample : public VulkanExampleBase
693694

694695
void prepare()
695696
{
697+
setSampleCount();
696698
VulkanExampleBase::prepare();
697699
loadAssets();
698700
setupVertexDescriptions();
@@ -733,6 +735,16 @@ class VulkanExample : public VulkanExampleBase
733735
break;
734736
}
735737
}
738+
739+
// Determine the maximum sample count usable by the platform
740+
void setSampleCount()
741+
{
742+
VkSampleCountFlags flags = std::min(deviceProperties.limits.framebufferColorSampleCounts,
743+
deviceProperties.limits.framebufferDepthSampleCounts);
744+
// Extract the value of the high-order bit of the flags
745+
sampleCount = (VkSampleCountFlagBits)(flags ? (1 << (fls(flags) - 1)) : 0);
746+
}
747+
736748
};
737749

738-
VULKAN_EXAMPLE_MAIN()
750+
VULKAN_EXAMPLE_MAIN()

texture/texture.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class VulkanExample : public VulkanExampleBase
179179
void loadTexture()
180180
{
181181
// We use the Khronos texture format (https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/)
182-
std::string filename = ASSET_PATH "textures/metalplate01_rgba.ktx";
182+
std::string filename = getAssetPath() + "textures/metalplate01_rgba.ktx";
183183
// Texture data contains 4 channels (RGBA) with unnormalized 8-bit values, this is the most commonly supported format
184184
VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
185185

xcode/MVKExample.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* MVKExample.cpp
3+
*
4+
* Copyright (c) 2016-2017 The Brenwill Workshop Ltd.
5+
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
6+
*/
7+
8+
9+
#include "MVKExample.h"
10+
#include "examples.h"
11+
12+
void MVKExample::renderFrame() {
13+
_vulkanExample->renderFrame();
14+
}
15+
16+
void MVKExample::keyPressed(uint32_t keyCode) {
17+
_vulkanExample->keyPressed(keyCode);
18+
}
19+
20+
MVKExample::MVKExample(void* view) {
21+
_vulkanExample = new VulkanExample();
22+
_vulkanExample->initVulkan();
23+
_vulkanExample->setupWindow(view);
24+
_vulkanExample->initSwapchain();
25+
_vulkanExample->prepare();
26+
}
27+
28+
MVKExample::~MVKExample() {
29+
delete _vulkanExample;
30+
}

xcode/MVKExample.h

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* MVKExample.h
3+
*
4+
* Copyright (c) 2016-2017 The Brenwill Workshop Ltd.
5+
* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
6+
*/
7+
8+
#pragma once
9+
10+
#include "vulkanexamplebase.h"
11+
12+
// Wrapper class for the SW VulkanExample instance.
13+
class MVKExample {
14+
15+
public:
16+
void renderFrame();
17+
void keyPressed(uint32_t keyCode);
18+
19+
MVKExample(void* view);
20+
~MVKExample();
21+
22+
protected:
23+
VulkanExampleBase* _vulkanExample;
24+
};
25+
26+
27+

xcode/README_MoltenVK_Examples.md

+72-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
#MoltenVK Vulkan Examples
66

7-
Copyright (c) 2014-2017 [The Brenwill Workshop Ltd.](http://www.brenwill.com) All rights reserved.
7+
Copyright (c) 2016-2017 [The Brenwill Workshop Ltd.](http://www.brenwill.com).
8+
This document is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
89

910
*This document is written in [Markdown](http://en.wikipedia.org/wiki/Markdown) format.
1011
For best results, use a Markdown reader.*
@@ -27,6 +28,9 @@ Installing MoltenVK
2728

2829
The examples in this repository can be run on *iOS* and *macOS* by using
2930
the [**MoltenVK**](http://www.moltengl.com/moltenvk/) *Vulkan* driver.
31+
32+
These examples require **MoltenVK 0.18.0** or greater.
33+
3034
Follow these instructions to install **MoltenVK**:
3135

3236
1. [Download](https://moltengl.com/free-trial/) the **Molten** free evaluation trial.
@@ -45,6 +49,72 @@ Follow these instructions to install **MoltenVK**:
4549
ln -s path-to-Molten-package/MoltenVK
4650

4751

52+
53+
<a name="installing-assimp"></a>
54+
55+
Installing AssImp
56+
-----------------
57+
58+
The examples in this repository make use of the [*AssImp*](http://assimp.sourceforge.net)
59+
library to load resource assets from files. To run the examples you must download and
60+
install *AssImp* library as follows.
61+
62+
>***Note:*** Due to the way that *AssImp* makes use of the *CMake* utility, an installation
63+
of *AssImp* can only be built for a single platform. To create *AssImp* libraries for both
64+
*iOS* and *macOS*, download a separate copy of the *AssImp* directory for each platform
65+
(or create a copy of the downloaded *AssImp* directory for each platform before building).
66+
67+
68+
####iOS
69+
70+
1. Download [AssImp 3.3.1](https://github.com/assimp/assimp/releases/tag/v3.3.1/).
71+
72+
2. Unzip and rename the directory to `assimp-3.3.1-ios`.
73+
74+
3. Open the file `assimp-3.3.1-ios/port/iOS/IPHONEOS_ARM64_TOOLCHAIN.cmake` file and comment
75+
out the following lines:
76+
77+
#SET (CC "${DEVROOT}/usr/bin/llvm-gcc")
78+
#SET (CXX "${DEVROOT}/usr/bin/llvm-g++")
79+
#CMAKE_FORCE_C_COMPILER (${CC} LLVM)
80+
#CMAKE_FORCE_CXX_COMPILER (${CXX} LLVM)
81+
82+
4. Open a *Terminal* session and navigate to the `assimp-3.3.1-ios/port/iOS` directory,
83+
and run the following build command:
84+
85+
cd path-to-assimp-3.3.1-ios/port/iOS
86+
./build.sh --stdlib=libc++ --archs="arm64" --no-fat
87+
88+
5. In the `assimp` directory within this directory, remove the existing `assimp-ios`
89+
symbolic link, and create a new symbolic link pointing to the `assimp-3.3.1-ios` directory:
90+
91+
cd path-to-this-directory/assimp
92+
rm assimp-ios
93+
ln -s path-to-assimp-3.3.1-ios assimp-ios
94+
95+
96+
####macOS
97+
98+
1. Download [AssImp 3.3.1](https://github.com/assimp/assimp/releases/tag/v3.3.1/).
99+
100+
2. Unzip and rename the directory to `assimp-3.3.1-macos`.
101+
102+
3. Open a *Terminal* session and navigate to the `assimp-3.3.1-ios/port/macOS` directory,
103+
and run the following build commands:
104+
105+
cd path-to-assimp-3.3.1-macos
106+
cmake CMakeLists.txt -G 'Unix Makefiles'
107+
make
108+
109+
4. In the `assimp` directory within this directory, remove the existing `assimp-macos`
110+
symbolic link, and create a new symbolic link pointing to the `assimp-3.3.1-macos` directory:
111+
112+
cd path-to-this-directory/assimp
113+
rm assimp-macos
114+
ln -s path-to-assimp-3.3.1-macos assimp-macos
115+
116+
117+
48118
<a name="running-examples"></a>
49119

50120
Running the Vulkan Examples
@@ -67,5 +137,6 @@ in this repository on either *iOS* or *macOS*. To do so, follow these instructio
67137

68138
- On *iOS*, tap on the scene to display the keyboard. Tap again on the scene to hide the keyboard.
69139
- On both *iOS* and *macOS*, use the numeric keys (*1, 2, 3...*) instead of function keys (*F1, F2, F3...*).
140+
- On both *iOS* and *macOS*, use the regular keyboard *+* and *-* keys instead of the numpad *+* and *-* keys.
70141
- On both *iOS* and *macOS*, use the *delete* key instead of the *escape* key.
71142

xcode/assimp/assimp-ios

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../assimp-3.3.1-ios

xcode/assimp/assimp-macos

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../assimp-3.3.1-macos

0 commit comments

Comments
 (0)