├── .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 |
--------------------------------------------------------------------------------