├── .gitignore ├── LICENSE ├── README.md └── objc ├── 02-ClearScreen ├── ClearScreen.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── ClearScreen.xcscheme └── ClearScreen │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── 03-DrawingIn2D ├── DrawingIn2D.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── DrawingIn2D.xcscheme └── DrawingIn2D │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── Shaders.metal │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── 04-DrawingIn3D ├── DrawingIn3D.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── DrawingIn3D │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── MBEMathUtilities.h │ ├── MBEMathUtilities.m │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── MBERenderer.h │ ├── MBERenderer.m │ ├── Shaders.metal │ ├── ViewController.h │ ├── ViewController.m │ └── main.m ├── 05-Lighting ├── Lighting.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Lighting │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── MBEMathUtilities.h │ ├── MBEMathUtilities.m │ ├── MBEMesh.h │ ├── MBEMesh.m │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── MBEOBJGroup.h │ ├── MBEOBJGroup.mm │ ├── MBEOBJMesh.h │ ├── MBEOBJMesh.m │ ├── MBEOBJModel.h │ ├── MBEOBJModel.mm │ ├── MBERenderer.h │ ├── MBERenderer.m │ ├── MBETypes.h │ ├── Shaders.metal │ ├── ViewController.h │ ├── ViewController.m │ ├── main.m │ └── teapot.obj ├── 06-Texturing ├── Texturing.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Texturing │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard │ ├── Info.plist │ ├── MBEMaterial.h │ ├── MBEMaterial.m │ ├── MBEMathUtilities.h │ ├── MBEMathUtilities.m │ ├── MBEMesh.h │ ├── MBEMesh.m │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── MBEOBJGroup.h │ ├── MBEOBJGroup.mm │ ├── MBEOBJMesh.h │ ├── MBEOBJMesh.m │ ├── MBEOBJModel.h │ ├── MBEOBJModel.mm │ ├── MBERenderer.h │ ├── MBERenderer.m │ ├── MBETextureLoader.h │ ├── MBETextureLoader.m │ ├── MBETypes.h │ ├── Shaders.metal │ ├── ViewController.h │ ├── ViewController.m │ ├── main.m │ └── spot │ ├── README.txt │ ├── moo.aiff │ ├── spot.obj │ ├── spot_control_mesh.obj │ ├── spot_quadrangulated.obj │ ├── spot_texture.png │ ├── spot_texture.svg │ └── spot_triangulated.obj ├── 07-Mipmapping ├── Mipmapping.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── Mipmapping │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Info.plist │ ├── MBECubeMesh.h │ ├── MBECubeMesh.m │ ├── MBEMatrixUtilities.h │ ├── MBEMatrixUtilities.m │ ├── MBEMesh.h │ ├── MBEMesh.m │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── MBERenderer.h │ ├── MBERenderer.m │ ├── MBETextureGenerator.h │ ├── MBETextureGenerator.m │ ├── MBETypes.h │ ├── MBEViewController.h │ ├── MBEViewController.m │ ├── Shaders.metal │ └── main.m ├── 08-CubeMapping ├── CubeMapping.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── CubeMapping │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Info.plist │ ├── MBEMatrixUtilities.h │ ├── MBEMatrixUtilities.m │ ├── MBEMesh.h │ ├── MBEMesh.m │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── MBERenderer.h │ ├── MBERenderer.m │ ├── MBESkyboxMesh.h │ ├── MBESkyboxMesh.m │ ├── MBETextureLoader.h │ ├── MBETextureLoader.m │ ├── MBETorusKnotMesh.h │ ├── MBETorusKnotMesh.m │ ├── MBETypes.h │ ├── MBEViewController.h │ ├── MBEViewController.m │ ├── Shaders.metal │ ├── Textures │ ├── nx.png │ ├── ny.png │ ├── nz.png │ ├── px.png │ ├── py.png │ ├── pz.png │ └── texture-readme.txt │ └── main.m ├── 09-CompressedTextures ├── CompressedTextures.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── CompressedTextures │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Info.plist │ ├── MBEMathUtilities.h │ ├── MBEMathUtilities.m │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── MBERenderer.h │ ├── MBERenderer.m │ ├── MBETextureDataSource.h │ ├── MBETextureDataSource.m │ ├── MBETypes.h │ ├── MBEViewController.h │ ├── MBEViewController.m │ ├── Shaders.metal │ ├── Textures │ ├── hotair.2bpp.pvr │ ├── hotair.4bpp.pvr │ ├── hotair.astc4x4.ktx │ ├── hotair.astc8x8.ktx │ ├── hotair.etc2.pvr │ ├── hotair.png │ └── textures.json │ └── main.m ├── 10-AlphaBlending ├── AlphaBlending.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── AlphaBlending │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Info.plist │ ├── MBEAppDelegate.h │ ├── MBEAppDelegate.m │ ├── MBEMaterial.h │ ├── MBEMaterial.m │ ├── MBEMathUtilities.h │ ├── MBEMathUtilities.m │ ├── MBEMesh.h │ ├── MBEMesh.m │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── MBEOBJGroup.h │ ├── MBEOBJGroup.mm │ ├── MBEOBJMesh.h │ ├── MBEOBJMesh.m │ ├── MBEOBJModel.h │ ├── MBEOBJModel.mm │ ├── MBEPlaneMesh.h │ ├── MBEPlaneMesh.m │ ├── MBERenderer.h │ ├── MBERenderer.m │ ├── MBETerrainMesh.h │ ├── MBETerrainMesh.m │ ├── MBETextureLoader.h │ ├── MBETextureLoader.m │ ├── MBETypes.h │ ├── MBEViewController.h │ ├── MBEViewController.m │ ├── Shaders.metal │ ├── main.m │ ├── palm │ ├── LICENSE │ ├── palm.obj │ ├── palm_diffuse.png │ └── palm_spec.png │ ├── sand.png │ └── water.png ├── 11-InstancedDrawing ├── InstancedDrawing.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── InstancedDrawing.xcscheme └── InstancedDrawing │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Info.plist │ ├── MBECow.h │ ├── MBECow.m │ ├── MBEMatrixUtilities.h │ ├── MBEMatrixUtilities.m │ ├── MBEMesh.h │ ├── MBEMesh.m │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── MBEOBJGroup.h │ ├── MBEOBJGroup.mm │ ├── MBEOBJMesh.h │ ├── MBEOBJMesh.m │ ├── MBEOBJModel.h │ ├── MBEOBJModel.mm │ ├── MBERenderer.h │ ├── MBERenderer.m │ ├── MBETerrainMesh.h │ ├── MBETerrainMesh.m │ ├── MBETextureLoader.h │ ├── MBETextureLoader.m │ ├── MBETypes.h │ ├── MBEViewController.h │ ├── MBEViewController.m │ ├── Shaders.metal │ ├── main.m │ ├── spot │ ├── CREDITS │ ├── spot.obj │ ├── spot.png │ ├── spot_control_mesh.obj │ ├── spot_quadrangulated.obj │ ├── spot_texture.svg │ └── spot_triangulated.obj │ └── textures │ ├── CREDITS │ └── grass.png ├── 12-TextRendering ├── TextRendering.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── xcshareddata │ │ └── xcschemes │ │ └── TextRendering.xcscheme └── TextRendering │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon@2x.png │ │ ├── Icon@3x.png │ │ ├── Icon~ipad.png │ │ └── Icon~ipad@2x.png │ ├── Info.plist │ ├── MBEFontAtlas.h │ ├── MBEFontAtlas.m │ ├── MBEMathUtilities.h │ ├── MBEMathUtilities.m │ ├── MBEMesh.h │ ├── MBEMesh.m │ ├── MBEMetalView.h │ ├── MBEMetalView.m │ ├── MBERenderer.h │ ├── MBERenderer.m │ ├── MBETextMesh.h │ ├── MBETextMesh.m │ ├── MBETextureLoader.h │ ├── MBETextureLoader.m │ ├── MBETypes.h │ ├── MBEViewController.h │ ├── MBEViewController.m │ ├── Shaders.metal │ └── main.m └── 14-ImageProcessing ├── ImageProcessing.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist └── ImageProcessing ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj ├── LaunchScreen.xib └── Main.storyboard ├── Images.xcassets ├── AppIcon.appiconset │ ├── Contents.json │ ├── Icon@2x.png │ ├── Icon@3x.png │ ├── Icon~ipad.png │ └── Icon~ipad@2x.png └── mandrill.imageset │ ├── Contents.json │ └── mandrill.png ├── Info.plist ├── MBEContext.h ├── MBEContext.m ├── MBEGaussianBlur2DFilter.h ├── MBEGaussianBlur2DFilter.m ├── MBEImageFilter.h ├── MBEImageFilter.m ├── MBEMainBundleTextureProvider.h ├── MBEMainBundleTextureProvider.m ├── MBESaturationAdjustmentFilter.h ├── MBESaturationAdjustmentFilter.m ├── MBETextureConsumer.h ├── MBETextureProvider.h ├── MBEViewController.h ├── MBEViewController.m ├── Shaders.metal ├── UIImage+MBETextureUtilities.h ├── UIImage+MBETextureUtilities.m └── main.m /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | .DS_Store 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Warren Moore 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Metal by Example 2 | 3 | This repository holds the sample code for the book _Metal by Example_ by Warren Moore. 4 | 5 | 6 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/02-ClearScreen/ClearScreen/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/Assets.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/02-ClearScreen/ClearScreen/Assets.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/02-ClearScreen/ClearScreen/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/02-ClearScreen/ClearScreen/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface MBEMetalView : UIView 4 | 5 | @property (readonly) CAMetalLayer *metalLayer; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/MBEMetalView.m: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | @import Metal; 3 | 4 | @interface MBEMetalView () 5 | @property (readonly) id device; 6 | @end 7 | 8 | @implementation MBEMetalView 9 | 10 | + (id)layerClass 11 | { 12 | return [CAMetalLayer class]; 13 | } 14 | 15 | - (instancetype)initWithCoder:(NSCoder *)aDecoder 16 | { 17 | if ((self = [super initWithCoder:aDecoder])) 18 | { 19 | _device = MTLCreateSystemDefaultDevice(); 20 | self.metalLayer.device = _device; 21 | self.metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; 22 | } 23 | 24 | return self; 25 | } 26 | 27 | - (CAMetalLayer *)metalLayer { 28 | return (CAMetalLayer *)self.layer; 29 | } 30 | 31 | - (void)didMoveToWindow 32 | { 33 | [self redraw]; 34 | } 35 | 36 | - (void)redraw 37 | { 38 | id drawable = [self.metalLayer nextDrawable]; 39 | id texture = drawable.texture; 40 | 41 | MTLRenderPassDescriptor *passDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; 42 | passDescriptor.colorAttachments[0].texture = texture; 43 | passDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; 44 | passDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; 45 | passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1, 0, 0, 1); 46 | 47 | id commandQueue = [self.device newCommandQueue]; 48 | 49 | id commandBuffer = [commandQueue commandBuffer]; 50 | 51 | id commandEncoder = [commandBuffer renderCommandEncoderWithDescriptor:passDescriptor]; 52 | [commandEncoder endEncoding]; 53 | 54 | [commandBuffer presentDrawable:drawable]; 55 | [commandBuffer commit]; 56 | 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/ViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface ViewController : UIViewController 4 | 5 | @end 6 | 7 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/ViewController.m: -------------------------------------------------------------------------------- 1 | 2 | #import "ViewController.h" 3 | 4 | @implementation ViewController 5 | 6 | - (void)viewDidLoad { 7 | [super viewDidLoad]; 8 | } 9 | 10 | - (BOOL)prefersStatusBarHidden { 11 | return YES; 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /objc/02-ClearScreen/ClearScreen/main.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "AppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 | return YES; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/03-DrawingIn2D/DrawingIn2D/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/Assets.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/03-DrawingIn2D/DrawingIn2D/Assets.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/03-DrawingIn2D/DrawingIn2D/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/03-DrawingIn2D/DrawingIn2D/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | 2D Drawing 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | metal 32 | armv7 33 | 34 | UISupportedInterfaceOrientations 35 | 36 | UIInterfaceOrientationPortrait 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | UISupportedInterfaceOrientations~ipad 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationPortraitUpsideDown 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface MBEMetalView : UIView 4 | 5 | @property (readonly) CAMetalLayer *metalLayer; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/Shaders.metal: -------------------------------------------------------------------------------- 1 | using namespace metal; 2 | 3 | struct Vertex 4 | { 5 | float4 position [[position]]; 6 | float4 color; 7 | }; 8 | 9 | vertex Vertex vertex_main(const device Vertex *vertices [[buffer(0)]], 10 | uint vid [[vertex_id]]) 11 | { 12 | return vertices[vid]; 13 | } 14 | 15 | fragment float4 fragment_main(Vertex inVertex [[stage_in]]) 16 | { 17 | return inVertex.color; 18 | } 19 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/ViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface ViewController : UIViewController 4 | 5 | @end 6 | 7 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/ViewController.m: -------------------------------------------------------------------------------- 1 | #import "ViewController.h" 2 | 3 | @implementation ViewController 4 | 5 | - (void)viewDidLoad { 6 | [super viewDidLoad]; 7 | } 8 | 9 | - (BOOL)prefersStatusBarHidden { 10 | return YES; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /objc/03-DrawingIn2D/DrawingIn2D/main.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "AppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 | return YES; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/04-DrawingIn3D/DrawingIn3D/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/Assets.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/04-DrawingIn3D/DrawingIn3D/Assets.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/04-DrawingIn3D/DrawingIn3D/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/04-DrawingIn3D/DrawingIn3D/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | 3D Drawing 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/MBEMathUtilities.h: -------------------------------------------------------------------------------- 1 | @import simd; 2 | 3 | /// Builds a translation matrix that translates by the supplied vector 4 | matrix_float4x4 matrix_float4x4_translation(vector_float3 t); 5 | 6 | /// Builds a scale matrix that uniformly scales all axes by the supplied factor 7 | matrix_float4x4 matrix_float4x4_uniform_scale(float scale); 8 | 9 | /// Builds a rotation matrix that rotates about the supplied axis by an 10 | /// angle (given in radians). The axis should be normalized. 11 | matrix_float4x4 matrix_float4x4_rotation(vector_float3 axis, float angle); 12 | 13 | /// Builds a symmetric perspective projection matrix with the supplied aspect ratio, 14 | /// vertical field of view (in radians), and near and far distances 15 | matrix_float4x4 matrix_float4x4_perspective(float aspect, float fovy, float near, float far); 16 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | @import QuartzCore.CAMetalLayer; 4 | 5 | @protocol MBEMetalViewDelegate; 6 | 7 | @interface MBEMetalView : UIView 8 | 9 | /// The delegate of this view, responsible for drawing 10 | @property (nonatomic, weak) id delegate; 11 | 12 | /// The Metal layer that backs this view 13 | @property (nonatomic, readonly) CAMetalLayer *metalLayer; 14 | 15 | /// The target frame rate (in Hz). For best results, this should 16 | /// be a number that evenly divides 60 (e.g., 60, 30, 15). 17 | @property (nonatomic) NSInteger preferredFramesPerSecond; 18 | 19 | /// The desired pixel format of the color attachment 20 | @property (nonatomic) MTLPixelFormat colorPixelFormat; 21 | 22 | /// The color to which the color attachment should be cleared at the start of 23 | /// a rendering pass 24 | @property (nonatomic, assign) MTLClearColor clearColor; 25 | 26 | /// The duration (in seconds) of the previous frame. This is valid only in the context 27 | /// of a callback to the delegate's -drawInView: method. 28 | @property (nonatomic, readonly) NSTimeInterval frameDuration; 29 | 30 | /// The view's layer's current drawable. This is valid only in the context 31 | /// of a callback to the delegate's -drawInView: method. 32 | @property (nonatomic, readonly) id currentDrawable; 33 | 34 | /// A render pass descriptor configured to use the current drawable's texture 35 | /// as its primary color attachment and an internal depth texture of the same 36 | /// size as its depth attachment's texture 37 | @property (nonatomic, readonly) MTLRenderPassDescriptor *currentRenderPassDescriptor; 38 | 39 | @end 40 | 41 | @protocol MBEMetalViewDelegate 42 | /// This method is called once per frame. Within the method, you may access 43 | /// any of the properties of the view, and request the current render pass 44 | /// descriptor to get a descriptor configured with renderable color and depth 45 | /// textures. 46 | - (void)drawInView:(MBEMetalView *)view; 47 | @end 48 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/MBERenderer.h: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | 3 | @interface MBERenderer : NSObject 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/Shaders.metal: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace metal; 4 | 5 | struct Vertex 6 | { 7 | float4 position [[position]]; 8 | float4 color; 9 | }; 10 | 11 | struct Uniforms 12 | { 13 | float4x4 modelViewProjectionMatrix; 14 | }; 15 | 16 | 17 | vertex Vertex vertex_project(const device Vertex *vertices [[buffer(0)]], 18 | constant Uniforms *uniforms [[buffer(1)]], 19 | uint vid [[vertex_id]]) 20 | { 21 | Vertex vertexOut; 22 | vertexOut.position = uniforms->modelViewProjectionMatrix * vertices[vid].position; 23 | vertexOut.color = vertices[vid].color; 24 | 25 | return vertexOut; 26 | } 27 | 28 | fragment half4 fragment_flatcolor(Vertex vertexIn [[stage_in]]) 29 | { 30 | return half4(vertexIn.color); 31 | } 32 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/ViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "MBERenderer.h" 3 | 4 | @interface ViewController : UIViewController 5 | 6 | @end 7 | 8 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/ViewController.m: -------------------------------------------------------------------------------- 1 | #import "ViewController.h" 2 | #import "MBEMetalView.h" 3 | 4 | @interface ViewController () 5 | @property (nonatomic, strong) MBERenderer *renderer; 6 | @end 7 | 8 | @implementation ViewController 9 | 10 | - (MBEMetalView *)metalView { 11 | return (MBEMetalView *)self.view; 12 | } 13 | 14 | - (void)viewDidLoad { 15 | [super viewDidLoad]; 16 | 17 | self.renderer = [MBERenderer new]; 18 | self.metalView.delegate = self.renderer; 19 | } 20 | 21 | - (BOOL)prefersStatusBarHidden { 22 | return YES; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /objc/04-DrawingIn3D/DrawingIn3D/main.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "AppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 | return YES; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/05-Lighting/Lighting/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/Assets.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/05-Lighting/Lighting/Assets.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/05-Lighting/Lighting/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/05-Lighting/Lighting/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBEMathUtilities.h: -------------------------------------------------------------------------------- 1 | @import simd; 2 | 3 | /// Builds a translation matrix that translates by the supplied vector 4 | matrix_float4x4 matrix_float4x4_translation(vector_float3 t); 5 | 6 | /// Builds a scale matrix that uniformly scales all axes by the supplied factor 7 | matrix_float4x4 matrix_float4x4_uniform_scale(float scale); 8 | 9 | /// Builds a rotation matrix that rotates about the supplied axis by an 10 | /// angle (given in radians). The axis should be normalized. 11 | matrix_float4x4 matrix_float4x4_rotation(vector_float3 axis, float angle); 12 | 13 | /// Builds a symmetric perspective projection matrix with the supplied aspect ratio, 14 | /// vertical field of view (in radians), and near and far distances 15 | matrix_float4x4 matrix_float4x4_perspective(float aspect, float fovy, float near, float far); 16 | 17 | matrix_float3x3 matrix_float4x4_extract_linear(matrix_float4x4); -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBEMesh.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBEMesh : NSObject 5 | @property (nonatomic, readonly) id vertexBuffer; 6 | @property (nonatomic, readonly) id indexBuffer; 7 | @end 8 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBEMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | 3 | @implementation MBEMesh 4 | @end 5 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | @import QuartzCore.CAMetalLayer; 4 | 5 | @protocol MBEMetalViewDelegate; 6 | 7 | @interface MBEMetalView : UIView 8 | 9 | /// The delegate of this view, responsible for drawing 10 | @property (nonatomic, weak) id delegate; 11 | 12 | /// The Metal layer that backs this view 13 | @property (nonatomic, readonly) CAMetalLayer *metalLayer; 14 | 15 | /// The target frame rate (in Hz). For best results, this should 16 | /// be a number that evenly divides 60 (e.g., 60, 30, 15). 17 | @property (nonatomic) NSInteger preferredFramesPerSecond; 18 | 19 | /// The desired pixel format of the color attachment 20 | @property (nonatomic) MTLPixelFormat colorPixelFormat; 21 | 22 | /// The color to which the color attachment should be cleared at the start of 23 | /// a rendering pass 24 | @property (nonatomic, assign) MTLClearColor clearColor; 25 | 26 | /// The duration (in seconds) of the previous frame. This is valid only in the context 27 | /// of a callback to the delegate's -drawInView: method. 28 | @property (nonatomic, readonly) NSTimeInterval frameDuration; 29 | 30 | /// The view's layer's current drawable. This is valid only in the context 31 | /// of a callback to the delegate's -drawInView: method. 32 | @property (nonatomic, readonly) id currentDrawable; 33 | 34 | /// A render pass descriptor configured to use the current drawable's texture 35 | /// as its primary color attachment and an internal depth texture of the same 36 | /// size as its depth attachment's texture 37 | @property (nonatomic, readonly) MTLRenderPassDescriptor *currentRenderPassDescriptor; 38 | 39 | @end 40 | 41 | @protocol MBEMetalViewDelegate 42 | /// This method is called once per frame. Within the method, you may access 43 | /// any of the properties of the view, and request the current render pass 44 | /// descriptor to get a descriptor configured with renderable color and depth 45 | /// textures. 46 | - (void)drawInView:(MBEMetalView *)view; 47 | @end 48 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBEOBJGroup.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface MBEOBJGroup : NSObject 4 | 5 | - (instancetype)initWithName:(NSString *)name; 6 | 7 | @property (copy) NSString *name; 8 | @property (copy) NSData *vertexData; 9 | @property (copy) NSData *indexData; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBEOBJGroup.mm: -------------------------------------------------------------------------------- 1 | #import "MBEOBJGroup.h" 2 | #import "MBETypes.h" 3 | 4 | @implementation MBEOBJGroup 5 | 6 | - (instancetype)initWithName:(NSString *)name 7 | { 8 | if ((self = [super init])) 9 | { 10 | _name = [name copy]; 11 | } 12 | return self; 13 | } 14 | 15 | - (NSString *)description 16 | { 17 | size_t vertCount = self.vertexData.length / sizeof(MBEVertex); 18 | size_t indexCount = self.indexData.length / sizeof(MBEIndex); 19 | return [NSString stringWithFormat:@" (\"%@\", %d vertices, %d indices)", 20 | self, self.name, (int)vertCount, (int)indexCount]; 21 | } 22 | 23 | @end 24 | 25 | 26 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBEOBJMesh.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import Metal; 3 | #import "MBEMesh.h" 4 | 5 | @class MBEOBJGroup; 6 | 7 | @interface MBEOBJMesh : MBEMesh 8 | 9 | - (instancetype)initWithGroup:(MBEOBJGroup *)group device:(id)device; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBEOBJMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEOBJMesh.h" 2 | #import "MBEOBJGroup.h" 3 | 4 | @implementation MBEOBJMesh 5 | 6 | @synthesize indexBuffer=_indexBuffer; 7 | @synthesize vertexBuffer=_vertexBuffer; 8 | 9 | - (instancetype)initWithGroup:(MBEOBJGroup *)group device:(id)device 10 | { 11 | if ((self = [super init])) 12 | { 13 | _vertexBuffer = [device newBufferWithBytes:[group.vertexData bytes] 14 | length:[group.vertexData length] 15 | options:MTLResourceOptionCPUCacheModeDefault]; 16 | [_vertexBuffer setLabel:[NSString stringWithFormat:@"Vertices (%@)", group.name]]; 17 | 18 | _indexBuffer = [device newBufferWithBytes:[group.indexData bytes] 19 | length:[group.indexData length] 20 | options:MTLResourceOptionCPUCacheModeDefault]; 21 | [_indexBuffer setLabel:[NSString stringWithFormat:@"Indices (%@)", group.name]]; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBEOBJModel.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class MBEOBJGroup; 4 | 5 | @interface MBEOBJModel : NSObject 6 | 7 | - (instancetype)initWithContentsOfURL:(NSURL *)fileURL generateNormals:(BOOL)generateNormals; 8 | 9 | /// Index 0 corresponds to an unnamed group that collects all the geometry 10 | /// declared outside of explicit "g" statements. Therefore, if your file 11 | /// contains explicit groups, you'll probably want to start from index 1, 12 | /// which will be the group beginning at the first group statement. 13 | @property (nonatomic, readonly) NSArray *groups; 14 | 15 | /// Retrieve a group from the OBJ file by name 16 | - (MBEOBJGroup *)groupForName:(NSString *)groupName; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBERenderer.h: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | 3 | @interface MBERenderer : NSObject 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/MBETypes.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | typedef uint16_t MBEIndex; 5 | const MTLIndexType MBEIndexType = MTLIndexTypeUInt16; 6 | 7 | typedef struct __attribute((packed)) 8 | { 9 | vector_float4 position; 10 | vector_float4 normal; 11 | } MBEVertex; 12 | 13 | typedef struct __attribute((packed)) 14 | { 15 | matrix_float4x4 modelViewProjectionMatrix; 16 | matrix_float4x4 modelViewMatrix; 17 | matrix_float3x3 normalMatrix; 18 | } MBEUniforms; 19 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/ViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface ViewController : UIViewController 4 | 5 | @end 6 | 7 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/ViewController.m: -------------------------------------------------------------------------------- 1 | #import "ViewController.h" 2 | #import "MBERenderer.h" 3 | #import "MBEMetalView.h" 4 | 5 | @interface ViewController () 6 | @property (nonatomic, strong) MBERenderer *renderer; 7 | @end 8 | 9 | @implementation ViewController 10 | 11 | - (MBEMetalView *)metalView { 12 | return (MBEMetalView *)self.view; 13 | } 14 | 15 | - (void)viewDidLoad { 16 | [super viewDidLoad]; 17 | 18 | self.renderer = [MBERenderer new]; 19 | self.metalView.delegate = self.renderer; 20 | } 21 | 22 | - (BOOL)prefersStatusBarHidden { 23 | return YES; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /objc/05-Lighting/Lighting/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Lighting 4 | // 5 | // Created by Warren Moore on 10/29/15. 6 | // Copyright © 2015 Metal by Example. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Texturing 4 | // 5 | // Created by Warren Moore on 10/29/15. 6 | // Copyright © 2015 Metal by Example. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | }, 67 | { 68 | "idiom" : "car", 69 | "size" : "60x60", 70 | "scale" : "2x" 71 | }, 72 | { 73 | "idiom" : "car", 74 | "size" : "60x60", 75 | "scale" : "3x" 76 | } 77 | ], 78 | "info" : { 79 | "version" : 1, 80 | "author" : "xcode" 81 | } 82 | } -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/Assets.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/06-Texturing/Texturing/Assets.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/Assets.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/06-Texturing/Texturing/Assets.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/06-Texturing/Texturing/Assets.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/06-Texturing/Texturing/Assets.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEMaterial.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import Metal; 3 | 4 | @interface MBEMaterial : NSObject 5 | 6 | @property (strong) id vertexFunction; 7 | @property (strong) id fragmentFunction; 8 | @property (strong) id diffuseTexture; 9 | 10 | - (instancetype)initWithVertexFunction:(id)vertexFunction 11 | fragmentFunction:(id)fragmentFunction 12 | diffuseTexture:(id)diffuseTexture; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEMaterial.m: -------------------------------------------------------------------------------- 1 | #import "MBEMaterial.h" 2 | 3 | @implementation MBEMaterial 4 | 5 | - (instancetype)initWithVertexFunction:(id)vertexFunction 6 | fragmentFunction:(id)fragmentFunction 7 | diffuseTexture:(id)diffuseTexture 8 | { 9 | if ((self = [super init])) 10 | { 11 | _vertexFunction = vertexFunction; 12 | _fragmentFunction = fragmentFunction; 13 | _diffuseTexture = diffuseTexture; 14 | } 15 | return self; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEMathUtilities.h: -------------------------------------------------------------------------------- 1 | @import simd; 2 | 3 | /// Builds a translation matrix that translates by the supplied vector 4 | matrix_float4x4 matrix_float4x4_translation(vector_float3 t); 5 | 6 | /// Builds a scale matrix that uniformly scales all axes by the supplied factor 7 | matrix_float4x4 matrix_float4x4_uniform_scale(float scale); 8 | 9 | /// Builds a rotation matrix that rotates about the supplied axis by an 10 | /// angle (given in radians). The axis should be normalized. 11 | matrix_float4x4 matrix_float4x4_rotation(vector_float3 axis, float angle); 12 | 13 | /// Builds a symmetric perspective projection matrix with the supplied aspect ratio, 14 | /// vertical field of view (in radians), and near and far distances 15 | matrix_float4x4 matrix_float4x4_perspective(float aspect, float fovy, float near, float far); 16 | 17 | matrix_float3x3 matrix_float4x4_extract_linear(matrix_float4x4); -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEMesh.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBEMesh : NSObject 5 | @property (nonatomic, readonly) id vertexBuffer; 6 | @property (nonatomic, readonly) id indexBuffer; 7 | @end 8 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | 3 | @implementation MBEMesh 4 | @end 5 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | @import QuartzCore.CAMetalLayer; 4 | 5 | @protocol MBEMetalViewDelegate; 6 | 7 | @interface MBEMetalView : UIView 8 | 9 | /// The delegate of this view, responsible for drawing 10 | @property (nonatomic, weak) id delegate; 11 | 12 | /// The Metal layer that backs this view 13 | @property (nonatomic, readonly) CAMetalLayer *metalLayer; 14 | 15 | /// The target frame rate (in Hz). For best results, this should 16 | /// be a number that evenly divides 60 (e.g., 60, 30, 15). 17 | @property (nonatomic) NSInteger preferredFramesPerSecond; 18 | 19 | /// The desired pixel format of the color attachment 20 | @property (nonatomic) MTLPixelFormat colorPixelFormat; 21 | 22 | /// The color to which the color attachment should be cleared at the start of 23 | /// a rendering pass 24 | @property (nonatomic, assign) MTLClearColor clearColor; 25 | 26 | /// The duration (in seconds) of the previous frame. This is valid only in the context 27 | /// of a callback to the delegate's -drawInView: method. 28 | @property (nonatomic, readonly) NSTimeInterval frameDuration; 29 | 30 | /// The view's layer's current drawable. This is valid only in the context 31 | /// of a callback to the delegate's -drawInView: method. 32 | @property (nonatomic, readonly) id currentDrawable; 33 | 34 | /// A render pass descriptor configured to use the current drawable's texture 35 | /// as its primary color attachment and an internal depth texture of the same 36 | /// size as its depth attachment's texture 37 | @property (nonatomic, readonly) MTLRenderPassDescriptor *currentRenderPassDescriptor; 38 | 39 | @end 40 | 41 | @protocol MBEMetalViewDelegate 42 | /// This method is called once per frame. Within the method, you may access 43 | /// any of the properties of the view, and request the current render pass 44 | /// descriptor to get a descriptor configured with renderable color and depth 45 | /// textures. 46 | - (void)drawInView:(MBEMetalView *)view; 47 | @end 48 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEOBJGroup.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface MBEOBJGroup : NSObject 4 | 5 | - (instancetype)initWithName:(NSString *)name; 6 | 7 | @property (copy) NSString *name; 8 | @property (copy) NSData *vertexData; 9 | @property (copy) NSData *indexData; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEOBJGroup.mm: -------------------------------------------------------------------------------- 1 | #import "MBEOBJGroup.h" 2 | #import "MBETypes.h" 3 | 4 | @implementation MBEOBJGroup 5 | 6 | - (instancetype)initWithName:(NSString *)name 7 | { 8 | if ((self = [super init])) 9 | { 10 | _name = [name copy]; 11 | } 12 | return self; 13 | } 14 | 15 | - (NSString *)description 16 | { 17 | size_t vertCount = self.vertexData.length / sizeof(MBEVertex); 18 | size_t indexCount = self.indexData.length / sizeof(MBEIndex); 19 | return [NSString stringWithFormat:@" (\"%@\", %d vertices, %d indices)", 20 | self, self.name, (int)vertCount, (int)indexCount]; 21 | } 22 | 23 | @end 24 | 25 | 26 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEOBJMesh.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import Metal; 3 | #import "MBEMesh.h" 4 | 5 | @class MBEOBJGroup; 6 | 7 | @interface MBEOBJMesh : MBEMesh 8 | 9 | - (instancetype)initWithGroup:(MBEOBJGroup *)group device:(id)device; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEOBJMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEOBJMesh.h" 2 | #import "MBEOBJGroup.h" 3 | 4 | @implementation MBEOBJMesh 5 | 6 | @synthesize indexBuffer=_indexBuffer; 7 | @synthesize vertexBuffer=_vertexBuffer; 8 | 9 | - (instancetype)initWithGroup:(MBEOBJGroup *)group device:(id)device 10 | { 11 | if ((self = [super init])) 12 | { 13 | _vertexBuffer = [device newBufferWithBytes:[group.vertexData bytes] 14 | length:[group.vertexData length] 15 | options:MTLResourceOptionCPUCacheModeDefault]; 16 | [_vertexBuffer setLabel:[NSString stringWithFormat:@"Vertices (%@)", group.name]]; 17 | 18 | _indexBuffer = [device newBufferWithBytes:[group.indexData bytes] 19 | length:[group.indexData length] 20 | options:MTLResourceOptionCPUCacheModeDefault]; 21 | [_indexBuffer setLabel:[NSString stringWithFormat:@"Indices (%@)", group.name]]; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBEOBJModel.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class MBEOBJGroup; 4 | 5 | @interface MBEOBJModel : NSObject 6 | 7 | - (instancetype)initWithContentsOfURL:(NSURL *)fileURL generateNormals:(BOOL)generateNormals; 8 | 9 | /// Index 0 corresponds to an unnamed group that collects all the geometry 10 | /// declared outside of explicit "g" statements. Therefore, if your file 11 | /// contains explicit groups, you'll probably want to start from index 1, 12 | /// which will be the group beginning at the first group statement. 13 | @property (nonatomic, readonly) NSArray *groups; 14 | 15 | /// Retrieve a group from the OBJ file by name 16 | - (MBEOBJGroup *)groupForName:(NSString *)groupName; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBERenderer.h: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | 3 | @interface MBERenderer : NSObject 4 | 5 | @property (nonatomic, assign) CGFloat rotationX; 6 | @property (nonatomic, assign) CGFloat rotationY; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBETextureLoader.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBETextureLoader : NSObject 5 | 6 | + (instancetype)sharedTextureLoader; 7 | 8 | - (id)texture2DWithImageNamed:(NSString *)imageName 9 | mipmapped:(BOOL)mipmapped 10 | commandQueue:(id)queue; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/MBETypes.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | typedef uint16_t MBEIndex; 5 | const MTLIndexType MBEIndexType = MTLIndexTypeUInt16; 6 | 7 | typedef struct __attribute((packed)) 8 | { 9 | vector_float4 position; 10 | vector_float4 normal; 11 | vector_float2 texCoords; 12 | } MBEVertex; 13 | 14 | typedef struct __attribute((packed)) 15 | { 16 | matrix_float4x4 modelViewProjectionMatrix; 17 | matrix_float4x4 modelViewMatrix; 18 | matrix_float3x3 normalMatrix; 19 | } MBEUniforms; 20 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/ViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface ViewController : UIViewController 4 | 5 | @end 6 | 7 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Texturing 4 | // 5 | // Created by Warren Moore on 10/29/15. 6 | // Copyright © 2015 Metal by Example. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/spot/README.txt: -------------------------------------------------------------------------------- 1 | Spot 2 | ==== 3 | contact: Keenan Crane (keenan@cs.caltech.edu) 4 | 5 | Files 6 | -------------------------------------------- 7 | This archive contains a description of the surface "Spot," including: 8 | 9 | 1. the original Catmull-Clark control mesh [spot_control_mesh.obj] 10 | 2. the original texture map as a vector image [spot_texture.svg] 11 | 3. triangular and quadrilateral tessellations [spot_triangulated.obj, spot_quadrangulated.obj] 12 | 4. the texture map as a raster image [spot_texture.png] 13 | 14 | Note that (3) and (4) can be generated from (1) and (2), and are provided only 15 | for convenience. Meshes are stored in the Wavefront OBJ format. All meshes 16 | are manifold, genus-0 embeddings. The texture map should be interpreted as a 17 | unit square in the positive quadrant [0,1]x[0,1]. 18 | 19 | License 20 | -------------------------------------------- 21 | 22 | As the sole author of this data, I hereby release it into the public domain. 23 | 24 | -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/spot/moo.aiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/06-Texturing/Texturing/spot/moo.aiff -------------------------------------------------------------------------------- /objc/06-Texturing/Texturing/spot/spot_texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/06-Texturing/Texturing/spot/spot_texture.png -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 | return YES; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIFileSharingEnabled 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UIStatusBarHidden 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBECubeMesh.h: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | @import Metal; 3 | 4 | @interface MBECubeMesh : MBEMesh 5 | 6 | - (instancetype)initWithDevice:(id) device; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBEMatrixUtilities.h: -------------------------------------------------------------------------------- 1 | @import simd; 2 | 3 | matrix_float4x4 matrix_identity(void); 4 | 5 | matrix_float4x4 matrix_rotation(vector_float3 axis, float angle); 6 | 7 | matrix_float4x4 matrix_translation(vector_float3 t) __attribute((overloadable)); 8 | 9 | matrix_float4x4 matrix_scale(vector_float3 s) __attribute((overloadable)); 10 | 11 | matrix_float4x4 matrix_uniform_scale(float s); 12 | 13 | matrix_float4x4 matrix_perspective_projection(float aspect, float fovy, float near, float far); 14 | 15 | matrix_float3x3 matrix_upper_left3x3(const matrix_float4x4 mat4x4); 16 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBEMesh.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | #import "MBETypes.h" 5 | 6 | @interface MBEMesh : NSObject 7 | 8 | @property (nonatomic, readonly) id vertexBuffer; 9 | @property (nonatomic, readonly) id indexBuffer; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBEMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | 3 | @implementation MBEMesh 4 | @end -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import QuartzCore.CAMetalLayer; 3 | 4 | @interface MBEMetalView : UIView 5 | 6 | @property (nonatomic, readonly) CAMetalLayer *metalLayer; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBEMetalView.m: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | 3 | @implementation MBEMetalView 4 | 5 | + (Class)layerClass 6 | { 7 | return [CAMetalLayer class]; 8 | } 9 | 10 | - (CAMetalLayer *)metalLayer 11 | { 12 | return (CAMetalLayer *)self.layer; 13 | } 14 | 15 | - (void)setFrame:(CGRect)frame 16 | { 17 | [super setFrame:frame]; 18 | 19 | // During the first layout pass, we will not be in a view hierarchy, so we guess our scale 20 | CGFloat scale = [UIScreen mainScreen].scale; 21 | 22 | // If we've moved to a window by the time our frame is being set, we can take its scale as our own 23 | if (self.window) 24 | { 25 | scale = self.window.screen.scale; 26 | } 27 | 28 | CGSize drawableSize = self.bounds.size; 29 | 30 | // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels 31 | drawableSize.width *= scale; 32 | drawableSize.height *= scale; 33 | 34 | self.metalLayer.drawableSize = drawableSize; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBERenderer.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import QuartzCore.CAMetalLayer; 3 | @import Metal; 4 | 5 | typedef NS_ENUM(NSInteger, MBEMipmappingMode) 6 | { 7 | MBEMipmappingModeNone, 8 | MBEMipmappingModeBlitGeneratedLinear, 9 | MBEMipmappingModeVibrantLinear, 10 | MBEMipmappingModeVibrantNearest 11 | }; 12 | 13 | @interface MBERenderer : NSObject 14 | 15 | @property (nonatomic, strong) id device; 16 | @property (nonatomic, strong) CAMetalLayer *layer; 17 | 18 | @property (nonatomic, assign) float cameraDistance; 19 | @property (nonatomic, assign) MBEMipmappingMode mipmappingMode; 20 | 21 | - (instancetype)initWithLayer:(CAMetalLayer *)layer; 22 | - (void)draw; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBETextureGenerator.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBETextureGenerator : NSObject 5 | 6 | /// Generates a square checkerboard texture with the specified number of tiles. 7 | /// If `colorfulMipmaps` is YES, mipmap levels will be generated on the CPU and tinted 8 | /// to be visually distinct when drawn. Otherwise, the blit command encoder is used to 9 | /// generate all mipmap levels on the GPU. 10 | + (void)checkerboardTextureWithSize:(CGSize)size 11 | tileCount:(size_t)tileCount 12 | colorfulMipmaps:(BOOL)colorfulMipmaps 13 | device:(id)device 14 | completion:(void (^)(id))completionBlock; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBETypes.h: -------------------------------------------------------------------------------- 1 | @import simd; 2 | 3 | typedef uint16_t MBEIndex; 4 | 5 | typedef struct 6 | { 7 | matrix_float4x4 modelMatrix; 8 | matrix_float3x3 normalMatrix; 9 | matrix_float4x4 modelViewProjectionMatrix; 10 | } MBEUniforms; 11 | 12 | typedef struct 13 | { 14 | packed_float4 position; 15 | packed_float4 normal; 16 | packed_float2 texCoords; 17 | } MBEVertex; 18 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/MBEViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "MBEMetalView.h" 3 | 4 | @interface MBEViewController : UIViewController 5 | 6 | @property (nonatomic, readonly) MBEMetalView *metalView; 7 | 8 | @end 9 | 10 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/Shaders.metal: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace metal; 3 | 4 | constant float3 kLightDirection(0, 0, -1); 5 | 6 | struct InVertex 7 | { 8 | float4 position [[attribute(0)]]; 9 | float4 normal [[attribute(1)]]; 10 | float2 texCoords [[attribute(2)]]; 11 | }; 12 | 13 | struct ProjectedVertex 14 | { 15 | float4 position [[position]]; 16 | float3 normal [[user(normal)]]; 17 | float2 texCoords [[user(tex_coords)]]; 18 | }; 19 | 20 | struct Uniforms 21 | { 22 | float4x4 modelMatrix; 23 | float3x3 normalMatrix; 24 | float4x4 modelViewProjectionMatrix; 25 | }; 26 | 27 | vertex ProjectedVertex vertex_project(InVertex inVertex [[stage_in]], 28 | constant Uniforms &uniforms [[buffer(1)]]) 29 | { 30 | ProjectedVertex outVert; 31 | outVert.position = uniforms.modelViewProjectionMatrix * float4(inVertex.position); 32 | outVert.normal = uniforms.normalMatrix * float4(inVertex.normal).xyz; 33 | outVert.texCoords = inVertex.texCoords; 34 | return outVert; 35 | } 36 | 37 | fragment half4 fragment_texture(ProjectedVertex vert [[stage_in]], 38 | texture2d texture [[texture(0)]], 39 | sampler texSampler [[sampler(0)]]) 40 | { 41 | float diffuseIntensity = max(0.33, dot(normalize(vert.normal), -kLightDirection)); 42 | float4 diffuseColor = texture.sample(texSampler, vert.texCoords); 43 | float4 color = diffuseColor * diffuseIntensity; 44 | return half4(color.r, color.g, color.b, 1); 45 | } 46 | -------------------------------------------------------------------------------- /objc/07-Mipmapping/Mipmapping/main.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "AppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 | return YES; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Images.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Images.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Images.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Images.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Images.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Images.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Cube Mapping 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | UISupportedInterfaceOrientations~ipad 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationPortraitUpsideDown 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBEMatrixUtilities.h: -------------------------------------------------------------------------------- 1 | @import simd; 2 | 3 | simd_float4x4 identity(void); 4 | 5 | simd_float4x4 rotation_about_axis(simd_float3 axis, float angle); 6 | 7 | simd_float4x4 translation(simd_float4 t); 8 | 9 | simd_float4x4 perspective_projection(float aspect, float fovy, float near, float far); 10 | 11 | simd_float3x3 upper_left3x3(const simd_float4x4 mat4x4); 12 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBEMesh.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBEMesh : NSObject 5 | 6 | @property (nonatomic, readonly) id vertexBuffer; 7 | @property (nonatomic, readonly) id indexBuffer; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBEMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | 3 | @implementation MBEMesh 4 | @end -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import QuartzCore.CAMetalLayer; 3 | 4 | @interface MBEMetalView : UIView 5 | 6 | @property (nonatomic, readonly) CAMetalLayer *metalLayer; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBEMetalView.m: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | 3 | @implementation MBEMetalView 4 | 5 | + (Class)layerClass 6 | { 7 | return [CAMetalLayer class]; 8 | } 9 | 10 | - (CAMetalLayer *)metalLayer 11 | { 12 | return (CAMetalLayer *)self.layer; 13 | } 14 | 15 | - (void)setFrame:(CGRect)frame 16 | { 17 | [super setFrame:frame]; 18 | 19 | // During the first layout pass, we will not be in a view hierarchy, so we guess our scale 20 | CGFloat scale = [UIScreen mainScreen].scale; 21 | 22 | // If we've moved to a window by the time our frame is being set, we can take its scale as our own 23 | if (self.window) 24 | { 25 | scale = self.window.screen.scale; 26 | } 27 | 28 | CGSize drawableSize = self.bounds.size; 29 | 30 | // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels 31 | drawableSize.width *= scale; 32 | drawableSize.height *= scale; 33 | 34 | self.metalLayer.drawableSize = drawableSize; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBERenderer.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import QuartzCore.CAMetalLayer; 3 | @import Metal; 4 | @import simd; 5 | 6 | @interface MBERenderer : NSObject 7 | 8 | @property (nonatomic, strong) id device; 9 | @property (nonatomic, strong) CAMetalLayer *layer; 10 | 11 | @property (nonatomic, assign) BOOL useRefractionMaterial; 12 | @property (nonatomic, assign) simd_float4x4 sceneOrientation; 13 | 14 | - (instancetype)initWithLayer:(CAMetalLayer *)layer; 15 | - (void)draw; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBESkyboxMesh.h: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | @import Metal; 3 | 4 | @interface MBESkyboxMesh : MBEMesh 5 | 6 | - (instancetype)initWithDevice:(id) device; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBETextureLoader.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBETextureLoader : NSObject 5 | 6 | + (id)texture2DWithImageNamed:(NSString *)imageName device:(id)device; 7 | 8 | + (id)textureCubeWithImagesNamed:(NSArray *)imageNameArray 9 | device:(id)device 10 | commandQueue:(id)commandQueue; 11 | @end 12 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBETorusKnotMesh.h: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | @import Metal; 3 | 4 | @interface MBETorusKnotMesh : MBEMesh 5 | 6 | /// `parameters` must be an NSArray containing two co-prime integers p, q, wrapped as NSNumbers. 7 | - (instancetype)initWithParameters:(NSArray *)parameters 8 | tubeRadius:(CGFloat)tubeRadius 9 | tubeSegments:(NSInteger)segments 10 | tubeSlices:(NSInteger)slices 11 | device:(id)device; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBETypes.h: -------------------------------------------------------------------------------- 1 | @import simd; 2 | 3 | typedef struct 4 | { 5 | simd_float4x4 modelMatrix; 6 | simd_float4x4 projectionMatrix; 7 | simd_float4x4 normalMatrix; 8 | simd_float4x4 modelViewProjectionMatrix; 9 | simd_float4 worldCameraPosition; 10 | } MBEUniforms; 11 | 12 | typedef struct 13 | { 14 | simd_float4 position; 15 | simd_float4 normal; 16 | } MBEVertex; 17 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/MBEViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface MBEViewController : UIViewController 4 | 5 | @end 6 | 7 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Textures/nx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Textures/nx.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Textures/ny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Textures/ny.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Textures/nz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Textures/nz.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Textures/px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Textures/px.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Textures/py.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Textures/py.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Textures/pz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/08-CubeMapping/CubeMapping/Textures/pz.png -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/Textures/texture-readme.txt: -------------------------------------------------------------------------------- 1 | Author 2 | ====== 3 | 4 | This is the work of Emil Persson, aka Humus. 5 | http://www.humus.name 6 | 7 | 8 | 9 | License 10 | ======= 11 | 12 | This work is licensed under a Creative Commons Attribution 3.0 Unported License. 13 | http://creativecommons.org/licenses/by/3.0/ 14 | -------------------------------------------------------------------------------- /objc/08-CubeMapping/CubeMapping/main.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "AppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 | return YES; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Images.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Images.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Images.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Images.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Images.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Images.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Compressed 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/MBEMathUtilities.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import simd; 3 | 4 | /// Returns random float between min and max, inclusive 5 | float random_float(float min, float max); 6 | 7 | /// Returns a vector that is orthogonal to the input vector 8 | vector_float3 vector_orthogonal(vector_float3 v); 9 | 10 | /// Returns the identity matrix 11 | matrix_float4x4 matrix_identity(void); 12 | 13 | /// Returns the matrix that rotates by `angle` radians about `axis` 14 | matrix_float4x4 matrix_rotation(vector_float3 axis, float angle); 15 | 16 | /// Returns the matrix that translates by translation vector `t` in 3D space 17 | matrix_float4x4 matrix_translation(vector_float3 t) __attribute((overloadable)); 18 | 19 | /// Returns the matrix that scales by scale vector `s` about the origin 20 | matrix_float4x4 matrix_scale(vector_float3 s) __attribute((overloadable)); 21 | 22 | /// Returns the matrix that uniformly scales about the origin along each axis by scale factor `s` 23 | matrix_float4x4 matrix_uniform_scale(float s); 24 | 25 | /// Returns the matrix that performs a symmetric perspective projection with the specified 26 | /// aspect ratio, vertical field of view (in radians), and near and far clipping planes 27 | matrix_float4x4 matrix_perspective_projection(float aspect, float fovy, float near, float far); 28 | 29 | /// Returns the matrix that performs an off-centered orthographic projection with the specified 30 | /// left, right, top and bottom clipping planes 31 | matrix_float4x4 matrix_orthographic_projection(float left, float right, float top, float bottom); 32 | 33 | /// Extracts the linear (upper left 3x3) portion of a matrix. The returned matrix has its 34 | /// right-most column and row = [ 0 0 0 1 ]. 35 | matrix_float4x4 matrix_extract_linear(const matrix_float4x4 mat4x4); 36 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import QuartzCore.CAMetalLayer; 3 | 4 | @interface MBEMetalView : UIView 5 | 6 | @property (nonatomic, readonly) CAMetalLayer *metalLayer; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/MBEMetalView.m: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | 3 | @implementation MBEMetalView 4 | 5 | + (Class)layerClass 6 | { 7 | return [CAMetalLayer class]; 8 | } 9 | 10 | - (CAMetalLayer *)metalLayer 11 | { 12 | return (CAMetalLayer *)self.layer; 13 | } 14 | 15 | - (void)setFrame:(CGRect)frame 16 | { 17 | [super setFrame:frame]; 18 | 19 | // During the first layout pass, we will not be in a view hierarchy, so we guess our scale 20 | CGFloat scale = [UIScreen mainScreen].scale; 21 | 22 | // If we've moved to a window by the time our frame is being set, we can take its scale as our own 23 | if (self.window) 24 | { 25 | scale = self.window.screen.scale; 26 | } 27 | 28 | CGSize drawableSize = self.bounds.size; 29 | 30 | // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels 31 | drawableSize.width *= scale; 32 | drawableSize.height *= scale; 33 | 34 | self.metalLayer.drawableSize = drawableSize; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/MBERenderer.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import Metal; 3 | @import QuartzCore.CAMetalLayer; 4 | 5 | @interface MBERenderer : NSObject 6 | 7 | @property (nonatomic, readonly) NSArray *textures; 8 | @property (nonatomic, assign) NSInteger currentTextureIndex; 9 | @property (nonatomic, assign) CGVector rotationAngles; 10 | 11 | - (instancetype)initWithLayer:(CAMetalLayer *)layer; 12 | - (void)draw; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/MBETextureDataSource.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import Metal; 3 | 4 | /// This class provides pixel data for textures from the following formats: 5 | /// - Any format that can be loaded by UIImage, such as PNG, JPEG, TIFF, etc. 6 | /// (These textures will be converted to have a pixel format of RGBA8Unorm) 7 | /// - Legacy PVR (v.2) encapsulating PVRTC data 8 | /// - PVR v.3 encapsulating PVRTC or ETC2/EAC data 9 | /// - ASTC encapsulating ASTC (LDR) data 10 | /// 11 | /// The `levels` property is an array of NSData objects containing the mipmap 12 | /// levels encoded in the file, suitable for loading into an MTLTexture. 13 | /// If the file contains only a single layer, this array will have one entry. 14 | /// 15 | /// The `width` and `height` properties give the dimensions of the base level. 16 | /// 17 | /// Currently, only 2D, single-slice, single-face textures are supported. 18 | @interface MBETextureDataSource : NSObject 19 | 20 | @property (nonatomic, readonly) MTLPixelFormat pixelFormat; 21 | @property (nonatomic, readonly) NSUInteger width; 22 | @property (nonatomic, readonly) NSUInteger height; 23 | @property (nonatomic, readonly) NSUInteger bytesPerRow; 24 | @property (nonatomic, readonly) NSUInteger mipmapCount; 25 | @property (nonatomic, readonly) NSArray *levels; 26 | 27 | + (instancetype)textureDataSourceWithContentsOfURL:(NSURL *)url; 28 | 29 | + (instancetype)textureDataSourceWithData:(NSData *)data; 30 | 31 | /// This method creates a new texture, generating mipmaps if requested. 32 | /// If the pixel format of the data data does not permit runtime mipmap 33 | /// generation, the `generateMipmaps` parameter is ignored. 34 | - (id)newTextureWithCommandQueue:(id)commandQueue 35 | generateMipmaps:(BOOL)generateMipmaps; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/MBETypes.h: -------------------------------------------------------------------------------- 1 | @import simd; 2 | 3 | typedef uint16_t MBEIndexType; 4 | 5 | typedef struct __attribute((packed)) 6 | { 7 | vector_float4 position; 8 | vector_float2 texCoords; 9 | } MBEVertex; 10 | 11 | typedef struct __attribute((packed)) 12 | { 13 | matrix_float4x4 modelViewProjectionMatrix; 14 | } MBEUniforms; 15 | 16 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/MBEViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface MBEViewController : UIViewController 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Shaders.metal: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace metal; 3 | 4 | struct Uniforms 5 | { 6 | float4x4 modelViewProjectionMatrix; 7 | }; 8 | 9 | struct Vertex 10 | { 11 | packed_float4 position; 12 | packed_float2 texCoords; 13 | }; 14 | 15 | struct ProjectedVertex 16 | { 17 | float4 position [[position]]; 18 | float2 texCoords [[user(texcoords)]]; 19 | }; 20 | 21 | vertex ProjectedVertex vertex_main(const device Vertex *vertices [[buffer(0)]], 22 | constant Uniforms *uniforms [[buffer(1)]], 23 | uint vertexID [[vertex_id]]) 24 | { 25 | float4 position = vertices[vertexID].position; 26 | float2 texCoords = vertices[vertexID].texCoords; 27 | 28 | ProjectedVertex outVert; 29 | outVert.position = uniforms->modelViewProjectionMatrix * position; 30 | outVert.texCoords = texCoords; 31 | return outVert; 32 | } 33 | 34 | fragment half4 fragment_main(ProjectedVertex inVert [[stage_in]], 35 | texture2d diffuseTexture [[texture(0)]], 36 | sampler textureSampler [[sampler(0)]]) 37 | { 38 | float4 color = diffuseTexture.sample(textureSampler, inVert.texCoords); 39 | 40 | if (color.a < 0.5) 41 | discard_fragment(); 42 | 43 | return half4(color); 44 | } 45 | -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Textures/hotair.2bpp.pvr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Textures/hotair.2bpp.pvr -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Textures/hotair.4bpp.pvr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Textures/hotair.4bpp.pvr -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Textures/hotair.astc4x4.ktx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Textures/hotair.astc4x4.ktx -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Textures/hotair.astc8x8.ktx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Textures/hotair.astc8x8.ktx -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Textures/hotair.etc2.pvr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Textures/hotair.etc2.pvr -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Textures/hotair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/09-CompressedTextures/CompressedTextures/Textures/hotair.png -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/Textures/textures.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "label":"PNG", 4 | "filename":"hotair.png", 5 | }, 6 | { 7 | "label":"PVRTC (2-bpp)", 8 | "filename":"hotair.2bpp.pvr", 9 | }, 10 | { 11 | "label":"PVRTC (4-bpp)", 12 | "filename":"hotair.4bpp.pvr", 13 | }, 14 | { 15 | "label":"ASTC (4x4 block size)", 16 | "filename":"hotair.astc4x4.ktx", 17 | }, 18 | { 19 | "label":"ASTC (8x8 block size)", 20 | "filename":"hotair.astc8x8.ktx", 21 | }, 22 | { 23 | "label":"ETC2", 24 | "filename":"hotair.etc2.pvr", 25 | }, 26 | ] -------------------------------------------------------------------------------- /objc/09-CompressedTextures/CompressedTextures/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CompressedTextures 4 | // 5 | // Created by Warren Moore on 4/17/15. 6 | // Copyright (c) 2015 Metal By Example. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/Images.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/10-AlphaBlending/AlphaBlending/Images.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/Images.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/10-AlphaBlending/AlphaBlending/Images.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/Images.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/10-AlphaBlending/AlphaBlending/Images.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/10-AlphaBlending/AlphaBlending/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Blending 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEAppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface MBEAppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEAppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "MBEAppDelegate.h" 2 | 3 | @implementation MBEAppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 | return YES; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEMaterial.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import Metal; 3 | @import simd; 4 | 5 | @interface MBEMaterial : NSObject 6 | 7 | @property (nonatomic, strong) id pipelineState; 8 | @property (nonatomic, strong) id depthState; 9 | @property (nonatomic, strong) id diffuseTexture; 10 | 11 | - (instancetype)initWithDiffuseTexture:(id)diffuseTexture 12 | alphaTestEnabled:(BOOL)alphaTestEnabled 13 | blendingEnabled:(BOOL)blendingEnabled 14 | depthWriteEnabled:(BOOL)depthWriteEnabled 15 | device:(id)device; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEMathUtilities.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import simd; 3 | 4 | /// Returns random float between min and max, inclusive 5 | float random_float(float min, float max); 6 | 7 | /// Returns a vector that is orthogonal to the input vector 8 | vector_float3 vector_orthogonal(vector_float3 v); 9 | 10 | matrix_float4x4 matrix_identity(void); 11 | 12 | matrix_float4x4 matrix_rotation(vector_float3 axis, float angle); 13 | 14 | matrix_float4x4 matrix_translation(vector_float3 t) __attribute((overloadable)); 15 | 16 | matrix_float4x4 matrix_scale(vector_float3 s) __attribute((overloadable)); 17 | 18 | matrix_float4x4 matrix_uniform_scale(float s); 19 | 20 | matrix_float4x4 matrix_perspective_projection(float aspect, float fovy, float near, float far); 21 | 22 | matrix_float4x4 matrix_extract_linear(const matrix_float4x4 mat4x4); 23 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEMesh.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBEMesh : NSObject 5 | 6 | @property (nonatomic, readonly) id vertexBuffer; 7 | @property (nonatomic, readonly) id indexBuffer; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | 3 | @implementation MBEMesh 4 | @end 5 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import QuartzCore.CAMetalLayer; 3 | 4 | @interface MBEMetalView : UIView 5 | 6 | @property (nonatomic, readonly) CAMetalLayer *metalLayer; 7 | @property (nonatomic, readonly) UITouch *currentTouch; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEMetalView.m: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | 3 | @implementation MBEMetalView 4 | 5 | + (Class)layerClass 6 | { 7 | return [CAMetalLayer class]; 8 | } 9 | 10 | - (CAMetalLayer *)metalLayer 11 | { 12 | return (CAMetalLayer *)self.layer; 13 | } 14 | 15 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 16 | { 17 | _currentTouch = [touches anyObject]; 18 | } 19 | 20 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 21 | { 22 | _currentTouch = nil; 23 | } 24 | 25 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 26 | { 27 | _currentTouch = nil; 28 | } 29 | 30 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 31 | { 32 | _currentTouch = [touches anyObject]; 33 | } 34 | 35 | - (void)setFrame:(CGRect)frame 36 | { 37 | [super setFrame:frame]; 38 | 39 | // During the first layout pass, we will not be in a view hierarchy, so we guess our scale 40 | CGFloat scale = [UIScreen mainScreen].scale; 41 | 42 | // If we've moved to a window by the time our frame is being set, we can take its scale as our own 43 | if (self.window) 44 | { 45 | scale = self.window.screen.scale; 46 | } 47 | 48 | CGSize drawableSize = self.bounds.size; 49 | 50 | // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels 51 | drawableSize.width *= scale; 52 | drawableSize.height *= scale; 53 | 54 | self.metalLayer.drawableSize = drawableSize; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEOBJGroup.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface MBEOBJGroup : NSObject 4 | 5 | - (instancetype)initWithName:(NSString *)name; 6 | 7 | @property (copy) NSString *name; 8 | @property (copy) NSData *vertexData; 9 | @property (copy) NSData *indexData; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEOBJGroup.mm: -------------------------------------------------------------------------------- 1 | #import "MBEOBJGroup.h" 2 | #import "MBETypes.h" 3 | 4 | @implementation MBEOBJGroup 5 | 6 | - (instancetype)initWithName:(NSString *)name 7 | { 8 | if ((self = [super init])) 9 | { 10 | _name = [name copy]; 11 | } 12 | return self; 13 | } 14 | 15 | - (NSString *)description 16 | { 17 | size_t vertCount = self.vertexData.length / sizeof(MBEVertex); 18 | size_t indexCount = self.indexData.length / sizeof(MBEIndex); 19 | return [NSString stringWithFormat:@" (\"%@\", %d vertices, %d indices)", 20 | self, self.name, (int)vertCount, (int)indexCount]; 21 | } 22 | 23 | @end 24 | 25 | 26 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEOBJMesh.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import Metal; 3 | #import "MBEMesh.h" 4 | 5 | @class MBEOBJGroup; 6 | 7 | @interface MBEOBJMesh : MBEMesh 8 | 9 | - (instancetype)initWithGroup:(MBEOBJGroup *)group device:(id)device; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEOBJMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEOBJMesh.h" 2 | #import "MBEOBJGroup.h" 3 | 4 | @implementation MBEOBJMesh 5 | 6 | @synthesize indexBuffer=_indexBuffer; 7 | @synthesize vertexBuffer=_vertexBuffer; 8 | 9 | - (instancetype)initWithGroup:(MBEOBJGroup *)group device:(id)device 10 | { 11 | if ((self = [super init])) 12 | { 13 | _vertexBuffer = [device newBufferWithBytes:[group.vertexData bytes] 14 | length:[group.vertexData length] 15 | options:MTLResourceOptionCPUCacheModeDefault]; 16 | [_vertexBuffer setLabel:[NSString stringWithFormat:@"Vertices (%@)", group.name]]; 17 | 18 | _indexBuffer = [device newBufferWithBytes:[group.indexData bytes] 19 | length:[group.indexData length] 20 | options:MTLResourceOptionCPUCacheModeDefault]; 21 | [_indexBuffer setLabel:[NSString stringWithFormat:@"Indices (%@)", group.name]]; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEOBJModel.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class MBEOBJGroup; 4 | 5 | @interface MBEOBJModel : NSObject 6 | 7 | - (instancetype)initWithContentsOfURL:(NSURL *)fileURL generateNormals:(BOOL)generateNormals; 8 | 9 | /// Index 0 corresponds to an unnamed group that collects all the geometry 10 | /// declared outside of explicit "g" statements. Therefore, if your file 11 | /// contains explicit groups, you'll probably want to start from index 1, 12 | /// which will be the group beginning at the first group statement. 13 | @property (nonatomic, readonly) NSArray *groups; 14 | 15 | /// Retrieve a group from the OBJ file by name 16 | - (MBEOBJGroup *)groupForName:(NSString *)groupName; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEPlaneMesh.h: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | @import simd; 3 | 4 | @interface MBEPlaneMesh : MBEMesh 5 | 6 | /// Generates a planar mesh with the specified dimensions and subdivision counts. 7 | /// Texture coordinates are multiplied by textureScale to allow tiling, and 8 | /// opacity is set as the alpha value of the diffuse color of each vertex. 9 | - (instancetype)initWithWidth:(float)width 10 | depth:(float)depth 11 | divisionsX:(unsigned int)divisionsX 12 | divisionsZ:(unsigned int)divisionsZ 13 | textureScale:(float)textureScale 14 | opacity:(float)opacity 15 | device:(id)device; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBERenderer.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import QuartzCore.CAMetalLayer; 3 | 4 | @interface MBERenderer : NSObject 5 | 6 | @property (nonatomic, assign) float angularVelocity; 7 | @property (nonatomic, assign) float velocity; 8 | @property (nonatomic, assign) float frameDuration; 9 | 10 | - (instancetype)initWithLayer:(CAMetalLayer *)layer; 11 | - (void)draw; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBETerrainMesh.h: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | 3 | @interface MBETerrainMesh : MBEMesh 4 | 5 | @property (nonatomic, readonly) float width; 6 | @property (nonatomic, readonly) float depth; 7 | @property (nonatomic, readonly) float height; 8 | 9 | /// Generates a square patch of terrain, using the diamond-square midpoint displacement algorithm. 10 | /// Smoothness varies from 0 to 1, with 1 being the smoothest. `iterations` determines how many 11 | /// times the recursive subdivision algorithm is applied; the total number of triangles is 12 | /// 2 * (2 ^ (2 * iterations)). `width` determines both the width and depth of the patch. `height` 13 | /// is the maximum possible distance from the lowest point to the highest point on the patch. 14 | - (instancetype)initWithWidth:(float)width 15 | height:(float)height 16 | iterations:(uint16_t)iterations 17 | smoothness:(float)smoothness 18 | device:(id)device; 19 | 20 | - (float)heightAtPositionX:(float)x z:(float)z; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBETextureLoader.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBETextureLoader : NSObject 5 | 6 | + (instancetype)sharedTextureLoader; 7 | 8 | - (id)texture2DWithImageNamed:(NSString *)imageName 9 | mipmapped:(BOOL)mipmapped 10 | device:(id)device; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBETypes.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | typedef uint16_t MBEIndex; 4 | 5 | typedef struct 6 | { 7 | matrix_float4x4 viewProjectionMatrix; 8 | } Uniforms; 9 | 10 | typedef struct 11 | { 12 | matrix_float4x4 modelMatrix; 13 | matrix_float4x4 normalMatrix; 14 | } InstanceUniforms; 15 | 16 | typedef struct 17 | { 18 | packed_float4 position; 19 | packed_float4 normal; 20 | packed_float4 diffuseColor; 21 | packed_float2 texCoords; 22 | } MBEVertex; 23 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @class MBEMetalView; 4 | 5 | @interface MBEViewController : UIViewController 6 | 7 | @property (nonatomic, readonly) MBEMetalView *metalView; 8 | 9 | @end 10 | 11 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/MBEViewController.m: -------------------------------------------------------------------------------- 1 | #import "MBEViewController.h" 2 | #import "MBEMetalView.h" 3 | #import "MBERenderer.h" 4 | 5 | static const float MBERotationSpeed = 3; 6 | 7 | @interface MBEViewController () 8 | @property (nonatomic, strong) CADisplayLink *displayLink; 9 | @property (nonatomic, strong) MBERenderer *renderer; 10 | @end 11 | 12 | @implementation MBEViewController 13 | 14 | - (void)viewDidLoad 15 | { 16 | [super viewDidLoad]; 17 | 18 | self.renderer = [[MBERenderer alloc] initWithLayer:self.metalView.metalLayer]; 19 | 20 | self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)]; 21 | [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 22 | } 23 | 24 | - (BOOL)prefersStatusBarHidden 25 | { 26 | return YES; 27 | } 28 | 29 | - (MBEMetalView *)metalView 30 | { 31 | return (MBEMetalView *)self.view; 32 | } 33 | 34 | - (void)updateMotion 35 | { 36 | self.renderer.frameDuration = self.displayLink.duration; 37 | 38 | UITouch *touch = self.metalView.currentTouch; 39 | 40 | if (touch) 41 | { 42 | CGRect bounds = self.view.bounds; 43 | float rotationScale = (CGRectGetMidX(bounds) - [touch locationInView:self.view].x) / bounds.size.width; 44 | 45 | self.renderer.velocity = 2; 46 | self.renderer.angularVelocity = rotationScale * MBERotationSpeed; 47 | } 48 | else 49 | { 50 | self.renderer.velocity = 0; 51 | self.renderer.angularVelocity = 0; 52 | } 53 | } 54 | 55 | - (void)displayLinkDidFire:(id)sender 56 | { 57 | [self updateMotion]; 58 | 59 | [self.renderer draw]; 60 | } 61 | 62 | @end 63 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/main.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "MBEAppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([MBEAppDelegate class])); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/palm/LICENSE: -------------------------------------------------------------------------------- 1 | Provided by Nobiax. 2 | 3 | Absolutely free to use or to modify in any kind of work (personal, commercial or else). 4 | 5 | Give me a link of the result at nobiax.deviantart.com or my other account on OpenGameArt.com or ShareCG.com 6 | ( watch my journal on deviantart ) ;) 7 | -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/palm/palm_diffuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/10-AlphaBlending/AlphaBlending/palm/palm_diffuse.png -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/palm/palm_spec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/10-AlphaBlending/AlphaBlending/palm/palm_spec.png -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/sand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/10-AlphaBlending/AlphaBlending/sand.png -------------------------------------------------------------------------------- /objc/10-AlphaBlending/AlphaBlending/water.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/10-AlphaBlending/AlphaBlending/water.png -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 | return YES; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/Images.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/11-InstancedDrawing/InstancedDrawing/Images.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/Images.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/11-InstancedDrawing/InstancedDrawing/Images.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/Images.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/11-InstancedDrawing/InstancedDrawing/Images.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/11-InstancedDrawing/InstancedDrawing/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Instanced 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIStatusBarHidden 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | UIInterfaceOrientationPortraitUpsideDown 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBECow.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import simd; 3 | 4 | @interface MBECow : NSObject 5 | @property (nonatomic, assign) vector_float3 position; 6 | @property (nonatomic, assign) float targetHeading; 7 | @property (nonatomic, assign) float heading; 8 | @end 9 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBECow.m: -------------------------------------------------------------------------------- 1 | #import "MBECow.h" 2 | 3 | @implementation MBECow 4 | @end 5 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEMatrixUtilities.h: -------------------------------------------------------------------------------- 1 | @import simd; 2 | 3 | matrix_float4x4 matrix_identity(void); 4 | 5 | matrix_float4x4 matrix_rotation(vector_float3 axis, float angle); 6 | 7 | matrix_float4x4 matrix_translation(vector_float3 t) __attribute((overloadable)); 8 | 9 | matrix_float4x4 matrix_scale(vector_float3 s) __attribute((overloadable)); 10 | 11 | matrix_float4x4 matrix_uniform_scale(float s); 12 | 13 | matrix_float4x4 matrix_perspective_projection(float aspect, float fovy, float near, float far); 14 | 15 | matrix_float3x3 matrix_upper_left3x3(const matrix_float4x4 mat4x4); 16 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEMesh.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBEMesh : NSObject 5 | 6 | @property (nonatomic, readonly) id vertexBuffer; 7 | @property (nonatomic, readonly) id indexBuffer; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | 3 | @implementation MBEMesh 4 | @end -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import QuartzCore.CAMetalLayer; 3 | 4 | @interface MBEMetalView : UIView 5 | 6 | @property (nonatomic, readonly) CAMetalLayer *metalLayer; 7 | @property (nonatomic, readonly) UITouch *currentTouch; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEMetalView.m: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | 3 | @implementation MBEMetalView 4 | 5 | + (Class)layerClass 6 | { 7 | return [CAMetalLayer class]; 8 | } 9 | 10 | - (CAMetalLayer *)metalLayer 11 | { 12 | return (CAMetalLayer *)self.layer; 13 | } 14 | 15 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 16 | { 17 | _currentTouch = [touches anyObject]; 18 | } 19 | 20 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 21 | { 22 | _currentTouch = nil; 23 | } 24 | 25 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 26 | { 27 | _currentTouch = nil; 28 | } 29 | 30 | - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 31 | { 32 | _currentTouch = [touches anyObject]; 33 | } 34 | 35 | - (void)setFrame:(CGRect)frame 36 | { 37 | [super setFrame:frame]; 38 | 39 | // During the first layout pass, we will not be in a view hierarchy, so we guess our scale 40 | CGFloat scale = [UIScreen mainScreen].scale; 41 | 42 | // If we've moved to a window by the time our frame is being set, we can take its scale as our own 43 | if (self.window) 44 | { 45 | scale = self.window.screen.scale; 46 | } 47 | 48 | CGSize drawableSize = self.bounds.size; 49 | 50 | // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels 51 | drawableSize.width *= scale; 52 | drawableSize.height *= scale; 53 | 54 | self.metalLayer.drawableSize = drawableSize; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEOBJGroup.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface MBEOBJGroup : NSObject 4 | 5 | - (instancetype)initWithName:(NSString *)name; 6 | 7 | @property (copy) NSString *name; 8 | @property (copy) NSData *vertexData; 9 | @property (copy) NSData *indexData; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEOBJGroup.mm: -------------------------------------------------------------------------------- 1 | #import "MBEOBJGroup.h" 2 | 3 | @implementation MBEOBJGroup 4 | 5 | - (instancetype)initWithName:(NSString *)name 6 | { 7 | if ((self = [super init])) 8 | { 9 | _name = [name copy]; 10 | } 11 | return self; 12 | } 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEOBJMesh.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import Metal; 3 | #import "MBEMesh.h" 4 | 5 | @class MBEOBJGroup; 6 | 7 | @interface MBEOBJMesh : MBEMesh 8 | 9 | - (instancetype)initWithGroup:(MBEOBJGroup *)group device:(id)device; 10 | 11 | @end 12 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEOBJMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEOBJMesh.h" 2 | #import "MBEOBJGroup.h" 3 | 4 | @implementation MBEOBJMesh 5 | 6 | @synthesize indexBuffer=_indexBuffer; 7 | @synthesize vertexBuffer=_vertexBuffer; 8 | 9 | - (instancetype)initWithGroup:(MBEOBJGroup *)group device:(id)device 10 | { 11 | if ((self = [super init])) 12 | { 13 | _vertexBuffer = [device newBufferWithBytes:[group.vertexData bytes] 14 | length:[group.vertexData length] 15 | options:MTLResourceOptionCPUCacheModeDefault]; 16 | [_vertexBuffer setLabel:[NSString stringWithFormat:@"Vertices (%@)", group.name]]; 17 | 18 | _indexBuffer = [device newBufferWithBytes:[group.indexData bytes] 19 | length:[group.indexData length] 20 | options:MTLResourceOptionCPUCacheModeDefault]; 21 | [_indexBuffer setLabel:[NSString stringWithFormat:@"Indices (%@)", group.name]]; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEOBJModel.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @class MBEOBJGroup; 4 | 5 | @interface MBEOBJModel : NSObject 6 | 7 | - (instancetype)initWithContentsOfURL:(NSURL *)fileURL generateNormals:(BOOL)generateNormals; 8 | 9 | // Index 0 corresponds to an unnamed group that collects all the geometry 10 | // declared outside of explicit "g" statements. Therefore, if your file 11 | // contains explicit groups, you'll probably want to start from index 1, 12 | // which will be the group beginning at the first group statement. 13 | @property (nonatomic, readonly) NSArray *groups; 14 | 15 | /// Retrieve a group from the OBJ file by name 16 | - (MBEOBJGroup *)groupForName:(NSString *)groupName; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBERenderer.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import QuartzCore.CAMetalLayer; 3 | 4 | @interface MBERenderer : NSObject 5 | 6 | @property (nonatomic, assign) float angularVelocity; 7 | @property (nonatomic, assign) float velocity; 8 | @property (nonatomic, assign) float frameDuration; 9 | 10 | - (instancetype)initWithLayer:(CAMetalLayer *)layer; 11 | - (void)draw; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBETerrainMesh.h: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | 3 | @interface MBETerrainMesh : MBEMesh 4 | 5 | @property (nonatomic, readonly) float width; 6 | @property (nonatomic, readonly) float depth; 7 | @property (nonatomic, readonly) float height; 8 | 9 | /// Generates a square patch of terrain, using the diamond-square midpoint displacement algorithm. 10 | /// Smoothness varies from 0 to 1, with 1 being the smoothest. `iterations` determines how many 11 | /// times the recursive subdivision algorithm is applied; the total number of triangles is 12 | /// 2 * (2 ^ (2 * iterations)). `width` determines both the width and depth of the patch. `height` 13 | /// is the maximum possible distance from the lowest point to the highest point on the patch. 14 | - (instancetype)initWithWidth:(float)width 15 | height:(float)height 16 | iterations:(uint16_t)iterations 17 | smoothness:(float)smoothness 18 | device:(id)device; 19 | 20 | - (float)heightAtPositionX:(float)x z:(float)z; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBETextureLoader.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBETextureLoader : NSObject 5 | 6 | + (id)texture2DWithImageNamed:(NSString *)imageName device:(id)device commandQueue:(id)commandQueue; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBETypes.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | typedef uint16_t MBEIndex; 4 | 5 | typedef struct 6 | { 7 | matrix_float4x4 viewProjectionMatrix; 8 | } Uniforms; 9 | 10 | typedef struct 11 | { 12 | matrix_float4x4 modelMatrix; 13 | matrix_float3x3 normalMatrix; 14 | } PerInstanceUniforms; 15 | 16 | typedef struct 17 | { 18 | packed_float4 position; 19 | packed_float4 normal; 20 | packed_float2 texCoords; 21 | } MBEVertex; 22 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface MBEViewController : UIViewController 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/MBEViewController.m: -------------------------------------------------------------------------------- 1 | #import "MBEViewController.h" 2 | #import "MBEMetalView.h" 3 | #import "MBERenderer.h" 4 | @import QuartzCore.CAMetalLayer; 5 | 6 | static const float MBERotationSpeed = 3; // radians per second 7 | 8 | @interface MBEViewController () 9 | @property (nonatomic, readonly) MBEMetalView *metalView; 10 | @property (nonatomic, strong) MBERenderer *renderer; 11 | @property (nonatomic, strong) CADisplayLink *displayLink; 12 | @property (nonatomic, assign) float angularVelocity; 13 | @end 14 | 15 | @implementation MBEViewController 16 | 17 | - (void)viewDidLoad 18 | { 19 | [super viewDidLoad]; 20 | 21 | self.renderer = [[MBERenderer alloc] initWithLayer:self.metalView.metalLayer]; 22 | 23 | self.displayLink = [CADisplayLink displayLinkWithTarget:self 24 | selector:@selector(displayLinkDidFire:)]; 25 | [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; 26 | } 27 | 28 | - (MBEMetalView *)metalView 29 | { 30 | return (MBEMetalView *)self.view; 31 | } 32 | 33 | - (BOOL)prefersStatusBarHidden 34 | { 35 | return YES; 36 | } 37 | 38 | - (void)updateMotion 39 | { 40 | self.renderer.frameDuration = self.displayLink.duration; 41 | 42 | UITouch *touch = self.metalView.currentTouch; 43 | 44 | if (touch) 45 | { 46 | CGRect bounds = self.view.bounds; 47 | float rotationScale = (CGRectGetMidX(bounds) - [touch locationInView:self.view].x) / bounds.size.width; 48 | 49 | self.renderer.velocity = 2; 50 | self.renderer.angularVelocity = rotationScale * MBERotationSpeed; 51 | } 52 | else 53 | { 54 | self.renderer.velocity = 0; 55 | self.renderer.angularVelocity = 0; 56 | } 57 | } 58 | 59 | - (void)displayLinkDidFire:(id)sender 60 | { 61 | [self updateMotion]; 62 | 63 | [self.renderer draw]; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/Shaders.metal: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace metal; 3 | 4 | constant float3 kLightDirection(-0.43, -0.8, -0.43); 5 | 6 | struct InVertex 7 | { 8 | float4 position [[attribute(0)]]; 9 | float4 normal [[attribute(1)]]; 10 | float2 texCoords [[attribute(2)]]; 11 | }; 12 | 13 | struct ProjectedVertex 14 | { 15 | float4 position [[position]]; 16 | float3 normal [[user(normal)]]; 17 | float2 texCoords [[user(tex_coords)]]; 18 | }; 19 | 20 | struct Uniforms 21 | { 22 | float4x4 viewProjectionMatrix; 23 | }; 24 | 25 | struct PerInstanceUniforms 26 | { 27 | float4x4 modelMatrix; 28 | float3x3 normalMatrix; 29 | }; 30 | 31 | vertex ProjectedVertex vertex_project(InVertex vertexIn [[stage_in]], 32 | constant Uniforms &uniforms [[buffer(1)]], 33 | constant PerInstanceUniforms *perInstanceUniforms [[buffer(2)]], 34 | ushort vid [[vertex_id]], 35 | ushort iid [[instance_id]]) 36 | { 37 | float4x4 instanceModelMatrix = perInstanceUniforms[iid].modelMatrix; 38 | float3x3 instanceNormalMatrix = perInstanceUniforms[iid].normalMatrix; 39 | 40 | ProjectedVertex outVert; 41 | outVert.position = uniforms.viewProjectionMatrix * instanceModelMatrix * float4(vertexIn.position); 42 | outVert.normal = instanceNormalMatrix * float4(vertexIn.normal).xyz; 43 | outVert.texCoords = vertexIn.texCoords; 44 | return outVert; 45 | } 46 | 47 | fragment half4 fragment_texture(ProjectedVertex vert [[stage_in]], 48 | texture2d texture [[texture(0)]], 49 | sampler texSampler [[sampler(0)]]) 50 | { 51 | float diffuseIntensity = max(0.33, dot(normalize(vert.normal), -kLightDirection)); 52 | float4 diffuseColor = texture.sample(texSampler, vert.texCoords); 53 | float4 color = diffuseColor * diffuseIntensity; 54 | return half4(color.r, color.g, color.b, 1); 55 | } 56 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/main.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "AppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/spot/CREDITS: -------------------------------------------------------------------------------- 1 | Spot 2 | ==== 3 | contact: Keenan Crane (keenan@cs.caltech.edu) 4 | 5 | Files 6 | -------------------------------------------- 7 | This archive contains a description of the surface "Spot," including: 8 | 9 | 1. the original Catmull-Clark control mesh [spot_control_mesh.obj] 10 | 2. the original texture map as a vector image [spot_texture.svg] 11 | 3. triangular and quadrilateral tessellations [spot_triangulated.obj, spot_quadrangulated.obj] 12 | 4. the texture map as a raster image [spot.png] 13 | 14 | Note that (3) and (4) can be generated from (1) and (2), and are provided only 15 | for convenience. Meshes are stored in the Wavefront OBJ format. All meshes 16 | are manifold, genus-0 embeddings. The texture map should be interpreted as a 17 | unit square in the positive quadrant [0,1]x[0,1]. 18 | 19 | License 20 | -------------------------------------------- 21 | 22 | As the sole author of this data, I hereby release it into the public domain. 23 | 24 | -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/spot/spot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/11-InstancedDrawing/InstancedDrawing/spot/spot.png -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/textures/CREDITS: -------------------------------------------------------------------------------- 1 | Textures provided by Simon Murray of goodtextures.com 2 | 3 | Texture License 4 | --------------- 5 | This work is licensed under a Creative Commons Attribution 3.0 Unported License. 6 | You may redistribute, remix, tweak, and build upon this work even for commercial 7 | reasons, as long as you credit this artist by linking back. 8 | 9 | http://creativecommons.org/licenses/by/3.0/ -------------------------------------------------------------------------------- /objc/11-InstancedDrawing/InstancedDrawing/textures/grass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/11-InstancedDrawing/InstancedDrawing/textures/grass.png -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 6 | return YES; 7 | } 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/Images.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/12-TextRendering/TextRendering/Images.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/Images.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/12-TextRendering/TextRendering/Images.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/Images.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/12-TextRendering/TextRendering/Images.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/12-TextRendering/TextRendering/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Text 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIFileSharingEnabled 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBEFontAtlas.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface MBEGlyphDescriptor : NSObject 4 | @property (nonatomic, assign) CGGlyph glyphIndex; 5 | @property (nonatomic, assign) CGPoint topLeftTexCoord; 6 | @property (nonatomic, assign) CGPoint bottomRightTexCoord; 7 | @end 8 | 9 | @interface MBEFontAtlas : NSObject 10 | 11 | @property (nonatomic, readonly) UIFont *parentFont; 12 | @property (nonatomic, readonly) CGFloat fontPointSize; 13 | @property (nonatomic, readonly) CGFloat spread; 14 | @property (nonatomic, readonly) NSInteger textureSize; 15 | @property (nonatomic, readonly) NSArray *glyphDescriptors; 16 | @property (nonatomic, readonly) NSData *textureData; 17 | 18 | /// Create a signed-distance field based font atlas with the specified dimensions. 19 | /// The supplied font will be resized to fit all available glyphs in the texture. 20 | - (instancetype)initWithFont:(UIFont *)font textureSize:(NSInteger)textureSize; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBEMathUtilities.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import simd; 3 | 4 | /// Returns random float between min and max, inclusive 5 | float random_float(float min, float max); 6 | 7 | /// Returns a vector that is orthogonal to the input vector 8 | vector_float3 vector_orthogonal(vector_float3 v); 9 | 10 | /// Returns the identity matrix 11 | matrix_float4x4 matrix_identity(void); 12 | 13 | /// Returns the matrix that rotates by `angle` radians about `axis` 14 | matrix_float4x4 matrix_rotation(vector_float3 axis, float angle); 15 | 16 | /// Returns the matrix that translates by translation vector `t` in 3D space 17 | matrix_float4x4 matrix_translation(vector_float3 t) __attribute((overloadable)); 18 | 19 | /// Returns the matrix that scales by scale vector `s` about the origin 20 | matrix_float4x4 matrix_scale(vector_float3 s) __attribute((overloadable)); 21 | 22 | /// Returns the matrix that uniformly scales about the origin along each axis by scale factor `s` 23 | matrix_float4x4 matrix_uniform_scale(float s); 24 | 25 | /// Returns the matrix that performs a symmetric perspective projection with the specified 26 | /// aspect ratio, vertical field of view (in radians), and near and far clipping planes 27 | matrix_float4x4 matrix_perspective_projection(float aspect, float fovy, float near, float far); 28 | 29 | /// Returns the matrix that performs an off-centered orthographic projection with the specified 30 | /// left, right, top and bottom clipping planes 31 | matrix_float4x4 matrix_orthographic_projection(float left, float right, float top, float bottom); 32 | 33 | /// Extracts the linear (upper left 3x3) portion of a matrix. The returned matrix has its 34 | /// right-most column and row = [ 0 0 0 1 ]. 35 | matrix_float4x4 matrix_extract_linear(const matrix_float4x4 mat4x4); 36 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBEMesh.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import Metal; 3 | 4 | @interface MBEMesh : NSObject 5 | 6 | @property (nonatomic, readonly) id vertexBuffer; 7 | @property (nonatomic, readonly) id indexBuffer; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBEMesh.m: -------------------------------------------------------------------------------- 1 | #import "MBEMesh.h" 2 | 3 | @implementation MBEMesh 4 | @end 5 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBEMetalView.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | @import QuartzCore.CAMetalLayer; 3 | 4 | @interface MBEMetalView : UIView 5 | 6 | @property (nonatomic, readonly) CAMetalLayer *metalLayer; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBEMetalView.m: -------------------------------------------------------------------------------- 1 | #import "MBEMetalView.h" 2 | 3 | @implementation MBEMetalView 4 | 5 | + (Class)layerClass 6 | { 7 | return [CAMetalLayer class]; 8 | } 9 | 10 | - (CAMetalLayer *)metalLayer 11 | { 12 | return (CAMetalLayer *)self.layer; 13 | } 14 | 15 | - (void)setFrame:(CGRect)frame 16 | { 17 | [super setFrame:frame]; 18 | 19 | // During the first layout pass, we will not be in a view hierarchy, so we guess our scale 20 | CGFloat scale = [UIScreen mainScreen].scale; 21 | 22 | // If we've moved to a window by the time our frame is being set, we can take its scale as our own 23 | if (self.window) 24 | { 25 | scale = self.window.screen.scale; 26 | } 27 | 28 | CGSize drawableSize = self.bounds.size; 29 | 30 | // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels 31 | drawableSize.width *= scale; 32 | drawableSize.height *= scale; 33 | 34 | self.metalLayer.drawableSize = drawableSize; 35 | } 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBERenderer.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | @import QuartzCore.CAMetalLayer; 3 | 4 | @interface MBERenderer : NSObject 5 | 6 | @property (nonatomic, assign) CGPoint textTranslation; 7 | @property (nonatomic, assign) CGFloat textScale; 8 | 9 | - (instancetype)initWithLayer:(CAMetalLayer *)layer; 10 | - (void)draw; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBETextMesh.h: -------------------------------------------------------------------------------- 1 | @import Metal; 2 | #import "MBEMesh.h" 3 | #import "MBEFontAtlas.h" 4 | 5 | @interface MBETextMesh : MBEMesh 6 | 7 | - (instancetype)initWithString:(NSString *)string 8 | inRect:(CGRect)rect 9 | withFontAtlas:(MBEFontAtlas *)fontAtlas 10 | atSize:(CGFloat)fontSize 11 | device:(id)device; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBETextureLoader.h: -------------------------------------------------------------------------------- 1 | // 2 | // MBETextureLoader.h 3 | // TextRendering 4 | // 5 | // Created by Warren Moore on 11/7/14. 6 | // Copyright (c) 2014 Metal By Example. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | @import Metal; 11 | 12 | @interface MBETextureLoader : NSObject 13 | 14 | + (instancetype)sharedTextureLoader; 15 | 16 | - (id)texture2DWithImage:(UIImage *)image 17 | mipmapped:(BOOL)mipmapped 18 | device:(id)device; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBETypes.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | typedef uint16_t MBEIndexType; 4 | 5 | typedef struct 6 | { 7 | matrix_float4x4 modelMatrix; 8 | matrix_float4x4 viewProjectionMatrix; 9 | vector_float4 foregroundColor; 10 | } MBEUniforms; 11 | 12 | typedef struct 13 | { 14 | packed_float4 position; 15 | packed_float2 texCoords; 16 | } MBEVertex; 17 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/MBEViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface MBEViewController : UIViewController 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/Shaders.metal: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace metal; 3 | 4 | struct Vertex 5 | { 6 | packed_float4 position; 7 | packed_float2 texCoords; 8 | }; 9 | 10 | struct TransformedVertex 11 | { 12 | float4 position [[position]]; 13 | float2 texCoords; 14 | }; 15 | 16 | struct Uniforms 17 | { 18 | float4x4 modelMatrix; 19 | float4x4 viewProjectionMatrix; 20 | float4 foregroundColor; 21 | }; 22 | 23 | vertex TransformedVertex vertex_shade(constant Vertex *vertices [[buffer(0)]], 24 | constant Uniforms &uniforms [[buffer(1)]], 25 | uint vid [[vertex_id]]) 26 | { 27 | TransformedVertex outVert; 28 | outVert.position = uniforms.viewProjectionMatrix * uniforms.modelMatrix * float4(vertices[vid].position); 29 | outVert.texCoords = vertices[vid].texCoords; 30 | return outVert; 31 | } 32 | 33 | fragment half4 fragment_shade(TransformedVertex vert [[stage_in]], 34 | constant Uniforms &uniforms [[buffer(0)]], 35 | sampler samplr [[sampler(0)]], 36 | texture2d texture [[texture(0)]]) 37 | { 38 | float4 color = uniforms.foregroundColor; 39 | // Outline of glyph is the isocontour with value 50% 40 | float edgeDistance = 0.5; 41 | // Sample the signed-distance field to find distance from this fragment to the glyph outline 42 | float sampleDistance = texture.sample(samplr, vert.texCoords).r; 43 | // Use local automatic gradients to find anti-aliased anisotropic edge width, cf. Gustavson 2012 44 | float edgeWidth = 0.75 * length(float2(dfdx(sampleDistance), dfdy(sampleDistance))); 45 | // Smooth the glyph edge by interpolating across the boundary in a band with the width determined above 46 | float insideness = smoothstep(edgeDistance - edgeWidth, edgeDistance + edgeWidth, sampleDistance); 47 | return half4(color.r, color.g, color.b, insideness); 48 | } 49 | -------------------------------------------------------------------------------- /objc/12-TextRendering/TextRendering/main.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "AppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/AppDelegate.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface AppDelegate : UIResponder 4 | 5 | @property (strong, nonatomic) UIWindow *window; 6 | 7 | @end 8 | 9 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | @implementation AppDelegate 4 | 5 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 6 | { 7 | return YES; 8 | } 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "size" : "60x60", 25 | "idiom" : "iphone", 26 | "filename" : "Icon@2x.png", 27 | "scale" : "2x" 28 | }, 29 | { 30 | "size" : "60x60", 31 | "idiom" : "iphone", 32 | "filename" : "Icon@3x.png", 33 | "scale" : "3x" 34 | }, 35 | { 36 | "idiom" : "ipad", 37 | "size" : "29x29", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "idiom" : "ipad", 42 | "size" : "29x29", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "idiom" : "ipad", 47 | "size" : "40x40", 48 | "scale" : "1x" 49 | }, 50 | { 51 | "idiom" : "ipad", 52 | "size" : "40x40", 53 | "scale" : "2x" 54 | }, 55 | { 56 | "size" : "76x76", 57 | "idiom" : "ipad", 58 | "filename" : "Icon~ipad.png", 59 | "scale" : "1x" 60 | }, 61 | { 62 | "size" : "76x76", 63 | "idiom" : "ipad", 64 | "filename" : "Icon~ipad@2x.png", 65 | "scale" : "2x" 66 | } 67 | ], 68 | "info" : { 69 | "version" : 1, 70 | "author" : "xcode" 71 | } 72 | } -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Images.xcassets/AppIcon.appiconset/Icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/14-ImageProcessing/ImageProcessing/Images.xcassets/AppIcon.appiconset/Icon@2x.png -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Images.xcassets/AppIcon.appiconset/Icon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/14-ImageProcessing/ImageProcessing/Images.xcassets/AppIcon.appiconset/Icon@3x.png -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Images.xcassets/AppIcon.appiconset/Icon~ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/14-ImageProcessing/ImageProcessing/Images.xcassets/AppIcon.appiconset/Icon~ipad.png -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/14-ImageProcessing/ImageProcessing/Images.xcassets/AppIcon.appiconset/Icon~ipad@2x.png -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Images.xcassets/mandrill.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x", 6 | "filename" : "mandrill.png" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Images.xcassets/mandrill.imageset/mandrill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/metal-by-example/sample-code/a73cc91cf8e4dcae452e732d4c7800eb4ac2d44d/objc/14-ImageProcessing/ImageProcessing/Images.xcassets/mandrill.imageset/mandrill.png -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Image Proc 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | metal 32 | armv7 33 | 34 | UISupportedInterfaceOrientations 35 | 36 | UIInterfaceOrientationPortrait 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | UISupportedInterfaceOrientations~ipad 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationPortraitUpsideDown 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBEContext.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @protocol MTLDevice, MTLLibrary, MTLCommandQueue; 4 | 5 | @interface MBEContext : NSObject 6 | 7 | @property (strong) id device; 8 | @property (strong) id library; 9 | @property (strong) id commandQueue; 10 | 11 | + (instancetype)newContext; 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBEContext.m: -------------------------------------------------------------------------------- 1 | #import "MBEContext.h" 2 | @import Metal; 3 | 4 | @implementation MBEContext 5 | 6 | + (instancetype)newContext 7 | { 8 | return [[self alloc] initWithDevice:nil]; 9 | } 10 | 11 | - (instancetype)initWithDevice:(id)device 12 | { 13 | if ((self = [super init])) 14 | { 15 | _device = device ?: MTLCreateSystemDefaultDevice(); 16 | _library = [_device newDefaultLibrary]; 17 | _commandQueue = [_device newCommandQueue]; 18 | } 19 | return self; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBEGaussianBlur2DFilter.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import "MBEImageFilter.h" 3 | 4 | @interface MBEGaussianBlur2DFilter : MBEImageFilter 5 | 6 | @property (nonatomic, assign) float radius; 7 | @property (nonatomic, assign) float sigma; 8 | 9 | + (instancetype)filterWithRadius:(float)radius context:(MBEContext *)context; 10 | 11 | @end 12 | 13 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBEImageFilter.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import "MBETextureProvider.h" 3 | #import "MBETextureConsumer.h" 4 | #import "MBEContext.h" 5 | 6 | @protocol MTLTexture, MTLBuffer, MTLComputeCommandEncoder, MTLComputePipelineState; 7 | 8 | @interface MBEImageFilter : NSObject 9 | 10 | @property (nonatomic, strong) MBEContext *context; 11 | @property (nonatomic, strong) id uniformBuffer; 12 | @property (nonatomic, strong) id pipeline; 13 | @property (nonatomic, strong) id internalTexture; 14 | @property (nonatomic, assign, getter=isDirty) BOOL dirty; 15 | 16 | - (instancetype)initWithFunctionName:(NSString *)functionName context:(MBEContext *)context; 17 | 18 | - (void)configureArgumentTableWithCommandEncoder:(id)commandEncoder; 19 | 20 | @end 21 | 22 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBEMainBundleTextureProvider.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "MBETextureProvider.h" 3 | 4 | @class MBEContext; 5 | 6 | @interface MBEMainBundleTextureProvider : NSObject 7 | 8 | + (instancetype)textureProviderWithImageNamed:(NSString *)imageName context:(MBEContext *)context; 9 | 10 | @end 11 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBESaturationAdjustmentFilter.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | #import "MBEContext.h" 3 | #import "MBEImageFilter.h" 4 | 5 | @interface MBESaturationAdjustmentFilter : MBEImageFilter 6 | 7 | @property (nonatomic, assign) float saturationFactor; 8 | 9 | + (instancetype)filterWithSaturationFactor:(float)saturation context:(MBEContext *)context; 10 | 11 | @end 12 | 13 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBESaturationAdjustmentFilter.m: -------------------------------------------------------------------------------- 1 | #import "MBESaturationAdjustmentFilter.h" 2 | @import Metal; 3 | 4 | struct AdjustSaturationUniforms 5 | { 6 | float saturationFactor; 7 | }; 8 | 9 | @implementation MBESaturationAdjustmentFilter 10 | 11 | @synthesize saturationFactor=_saturationFactor; 12 | 13 | + (instancetype)filterWithSaturationFactor:(float)saturation context:(MBEContext *)context 14 | { 15 | return [[self alloc] initWithSaturationFactor:saturation context:context]; 16 | } 17 | 18 | - (instancetype)initWithSaturationFactor:(float)saturation context:(MBEContext *)context 19 | { 20 | if ((self = [super initWithFunctionName:@"adjust_saturation" context:context])) 21 | { 22 | _saturationFactor = saturation; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)setSaturationFactor:(float)saturationFactor 28 | { 29 | self.dirty = YES; 30 | _saturationFactor = saturationFactor; 31 | } 32 | 33 | - (void)configureArgumentTableWithCommandEncoder:(id)commandEncoder 34 | { 35 | struct AdjustSaturationUniforms uniforms; 36 | uniforms.saturationFactor = self.saturationFactor; 37 | 38 | if (!self.uniformBuffer) 39 | { 40 | self.uniformBuffer = [self.context.device newBufferWithLength:sizeof(uniforms) 41 | options:MTLResourceOptionCPUCacheModeDefault]; 42 | } 43 | 44 | memcpy([self.uniformBuffer contents], &uniforms, sizeof(uniforms)); 45 | 46 | [commandEncoder setBuffer:self.uniformBuffer offset:0 atIndex:0]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBETextureConsumer.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @protocol MBETextureProvider; 4 | 5 | @protocol MBETextureConsumer 6 | 7 | @property (nonatomic, strong) id provider; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBETextureProvider.h: -------------------------------------------------------------------------------- 1 | @import Foundation; 2 | 3 | @protocol MTLTexture; 4 | 5 | @protocol MBETextureProvider 6 | 7 | @property (nonatomic, readonly) id texture; 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/MBEViewController.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @interface MBEViewController : UIViewController 4 | 5 | @property (weak, nonatomic) IBOutlet UIImageView *imageView; 6 | @property (weak, nonatomic) IBOutlet UISlider *blurRadiusSlider; 7 | @property (weak, nonatomic) IBOutlet UISlider *saturationSlider; 8 | 9 | - (IBAction)blurRadiusDidChange:(id)sender; 10 | - (IBAction)saturationDidChange:(id)sender; 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/Shaders.metal: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace metal; 4 | 5 | struct AdjustSaturationUniforms 6 | { 7 | float saturationFactor; 8 | }; 9 | 10 | kernel void adjust_saturation(texture2d inTexture [[texture(0)]], 11 | texture2d outTexture [[texture(1)]], 12 | constant AdjustSaturationUniforms &uniforms [[buffer(0)]], 13 | uint2 gid [[thread_position_in_grid]]) 14 | { 15 | float4 inColor = inTexture.read(gid); 16 | float value = dot(inColor.rgb, float3(0.299, 0.587, 0.114)); 17 | float4 grayColor(value, value, value, 1.0); 18 | float4 outColor = mix(grayColor, inColor, uniforms.saturationFactor); 19 | outTexture.write(outColor, gid); 20 | } 21 | 22 | kernel void gaussian_blur_2d(texture2d inTexture [[texture(0)]], 23 | texture2d outTexture [[texture(1)]], 24 | texture2d weights [[texture(2)]], 25 | uint2 gid [[thread_position_in_grid]]) 26 | { 27 | int size = weights.get_width(); 28 | int radius = size / 2; 29 | 30 | float4 accumColor(0, 0, 0, 0); 31 | for (int j = 0; j < size; ++j) 32 | { 33 | for (int i = 0; i < size; ++i) 34 | { 35 | uint2 kernelIndex(i, j); 36 | uint2 textureIndex(gid.x + (i - radius), gid.y + (j - radius)); 37 | float4 color = inTexture.read(textureIndex).rgba; 38 | float4 weight = weights.read(kernelIndex).rrrr; 39 | accumColor += weight * color; 40 | } 41 | } 42 | 43 | outTexture.write(float4(accumColor.rgb, 1), gid); 44 | } 45 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/UIImage+MBETextureUtilities.h: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | 3 | @protocol MTLTexture; 4 | 5 | @interface UIImage (MBETextureUtilities) 6 | 7 | + (UIImage *)imageWithMTLTexture:(id)texture; 8 | 9 | @end 10 | 11 | -------------------------------------------------------------------------------- /objc/14-ImageProcessing/ImageProcessing/main.m: -------------------------------------------------------------------------------- 1 | @import UIKit; 2 | #import "AppDelegate.h" 3 | 4 | int main(int argc, char * argv[]) { 5 | @autoreleasepool { 6 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 7 | } 8 | } 9 | --------------------------------------------------------------------------------