diff --git a/objc/02-ClearScreen/ClearScreen.xcodeproj/project.pbxproj b/objc/02-ClearScreen/ClearScreen.xcodeproj/project.pbxproj
index 97237cc..12a907f 100644
--- a/objc/02-ClearScreen/ClearScreen.xcodeproj/project.pbxproj
+++ b/objc/02-ClearScreen/ClearScreen.xcodeproj/project.pbxproj
@@ -110,7 +110,7 @@
833FBB9B1BBE0B0E001EFE4D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "Metal by Example";
TargetAttributes = {
833FBBA21BBE0B0E001EFE4D = {
@@ -195,12 +195,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -247,12 +249,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
diff --git a/objc/02-ClearScreen/ClearScreen.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/objc/02-ClearScreen/ClearScreen.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/objc/02-ClearScreen/ClearScreen.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/objc/02-ClearScreen/ClearScreen.xcodeproj/xcshareddata/xcschemes/ClearScreen.xcscheme b/objc/02-ClearScreen/ClearScreen.xcodeproj/xcshareddata/xcschemes/ClearScreen.xcscheme
index 03bae38..2ed7c45 100644
--- a/objc/02-ClearScreen/ClearScreen.xcodeproj/xcshareddata/xcschemes/ClearScreen.xcscheme
+++ b/objc/02-ClearScreen/ClearScreen.xcodeproj/xcshareddata/xcschemes/ClearScreen.xcscheme
@@ -1,6 +1,6 @@
@@ -46,7 +45,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/project.pbxproj b/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/project.pbxproj
index d393a58..8f06fcb 100644
--- a/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/project.pbxproj
+++ b/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/project.pbxproj
@@ -113,7 +113,7 @@
83E2D75C1BD188110006DDD8 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "Metal by Example";
TargetAttributes = {
83E2D7631BD188110006DDD8 = {
@@ -199,12 +199,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -251,12 +253,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -289,7 +293,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- INFOPLIST_FILE = "DrawingIn2D/Info.plist";
+ INFOPLIST_FILE = DrawingIn2D/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.4;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.metalbyexample.-2-DrawingIn2D";
@@ -301,7 +305,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- INFOPLIST_FILE = "DrawingIn2D/Info.plist";
+ INFOPLIST_FILE = DrawingIn2D/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 8.4;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.metalbyexample.-2-DrawingIn2D";
diff --git a/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/xcshareddata/xcschemes/DrawingIn2D.xcscheme b/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/xcshareddata/xcschemes/DrawingIn2D.xcscheme
index fc08a89..d38cb48 100644
--- a/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/xcshareddata/xcschemes/DrawingIn2D.xcscheme
+++ b/objc/03-DrawingIn2D/DrawingIn2D.xcodeproj/xcshareddata/xcschemes/DrawingIn2D.xcscheme
@@ -1,6 +1,6 @@
@@ -46,7 +45,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/AppDelegate.h b/objc/04-DrawingIn3D/DrawingIn3D-Mac/AppDelegate.h
new file mode 100644
index 0000000..c6cc122
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import
+
+@interface AppDelegate : NSObject
+
+
+@end
+
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/AppDelegate.m b/objc/04-DrawingIn3D/DrawingIn3D-Mac/AppDelegate.m
new file mode 100644
index 0000000..694bd25
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/AppDelegate.m
@@ -0,0 +1,27 @@
+//
+// AppDelegate.m
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
+}
+
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
+}
+
+
+@end
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json b/objc/04-DrawingIn3D/DrawingIn3D-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..2db2b1c
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/Assets.xcassets/Contents.json b/objc/04-DrawingIn3D/DrawingIn3D-Mac/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/Base.lproj/Main.storyboard b/objc/04-DrawingIn3D/DrawingIn3D-Mac/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..13538fe
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/Base.lproj/Main.storyboard
@@ -0,0 +1,718 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/DrawingIn3D_Mac.entitlements b/objc/04-DrawingIn3D/DrawingIn3D-Mac/DrawingIn3D_Mac.entitlements
new file mode 100644
index 0000000..f2ef3ae
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/DrawingIn3D_Mac.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+
+
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/Info.plist b/objc/04-DrawingIn3D/DrawingIn3D-Mac/Info.plist
new file mode 100644
index 0000000..7dd54bb
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ Copyright © 2018 Metal by Example. All rights reserved.
+ NSMainStoryboardFile
+ Main
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/MBEMetalViewMac.h b/objc/04-DrawingIn3D/DrawingIn3D-Mac/MBEMetalViewMac.h
new file mode 100644
index 0000000..f291345
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/MBEMetalViewMac.h
@@ -0,0 +1,15 @@
+//
+// MBEMetalViewMac.h
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+@import Cocoa;
+
+#import "MBEMetalView.h"
+
+@interface MBEMetalViewMac : MBEMetalView
+
+@end
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/MBEMetalViewMac.m b/objc/04-DrawingIn3D/DrawingIn3D-Mac/MBEMetalViewMac.m
new file mode 100644
index 0000000..66bacd8
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/MBEMetalViewMac.m
@@ -0,0 +1,72 @@
+//
+// MBEMetalViewMac.m
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalViewMac.h"
+
+@interface MBEMetalViewMac()
+@property (nonatomic) CVDisplayLinkRef displayLink;
+@property (nonatomic, strong) CAMetalLayer *metalLayer;
+@end
+
+static NSTimeInterval C3DTimeIntervalFromTimeStamp(const CVTimeStamp *timeStamp) {
+ return 1.0 / (timeStamp->rateScalar * (double)timeStamp->videoTimeScale / (double)timeStamp->videoRefreshPeriod);
+}
+
+static CVReturn C3DViewDisplayLink(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *view) {
+ @autoreleasepool {
+ [(__bridge MBEMetalView *)view renderWithDuration:C3DTimeIntervalFromTimeStamp(inOutputTime)];
+ }
+
+ return kCVReturnSuccess;
+}
+
+@implementation MBEMetalViewMac
+
+@synthesize metalLayer=_metalLayer;
+
+- (CALayer *)makeBackingLayer
+{
+ CAMetalLayer *layer = [[CAMetalLayer alloc] init];
+ _metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
+ _metalLayer = layer;
+ return layer;
+}
+
+- (CGSize)drawableSize {
+ return self.bounds.size;
+}
+
+- (void)viewDidMoveToSuperview
+{
+ [super viewDidMoveToSuperview];
+
+ if (self.metalLayer.device == nil) {
+ self.metalLayer.device = MTLCreateSystemDefaultDevice();
+ }
+ if (self.depthTexture == nil) {
+ [self makeDepthTexture];
+ }
+
+ if (self.superview) {
+ CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
+ CVDisplayLinkSetOutputCallback(_displayLink, C3DViewDisplayLink, (__bridge void *)(self));
+ CVDisplayLinkStart(_displayLink);
+ }
+ else {
+ CVDisplayLinkStop(_displayLink);
+ CVDisplayLinkRelease(_displayLink);
+ _displayLink = NULL;
+ }
+}
+
+@end
diff --git a/objc/04-DrawingIn3D/DrawingIn3D-Mac/main.m b/objc/04-DrawingIn3D/DrawingIn3D-Mac/main.m
new file mode 100644
index 0000000..0957be7
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D-Mac/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import
+
+int main(int argc, const char * argv[]) {
+ return NSApplicationMain(argc, argv);
+}
diff --git a/objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.pbxproj b/objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.pbxproj
index 6c4628b..930d5e0 100644
--- a/objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.pbxproj
+++ b/objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.pbxproj
@@ -17,6 +17,17 @@
83E2D7B51BD598810006DDD8 /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7AC1BD598810006DDD8 /* MBERenderer.m */; };
83E2D7B61BD598810006DDD8 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7AD1BD598810006DDD8 /* Shaders.metal */; };
83E2D7B81BD598810006DDD8 /* MBEMathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7B11BD598810006DDD8 /* MBEMathUtilities.m */; };
+ 845182E520D8214900BF473E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 845182E420D8214900BF473E /* AppDelegate.m */; };
+ 845182EA20D8214A00BF473E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 845182E920D8214A00BF473E /* Assets.xcassets */; };
+ 845182ED20D8214A00BF473E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 845182EB20D8214A00BF473E /* Main.storyboard */; };
+ 845182F020D8214A00BF473E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 845182EF20D8214A00BF473E /* main.m */; };
+ 845182F720D821B300BF473E /* MBEMetalViewMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 845182F620D821B300BF473E /* MBEMetalViewMac.m */; };
+ 845182F820D821DD00BF473E /* MBEMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7A71BD598810006DDD8 /* MBEMetalView.m */; };
+ 845182FB20D8222100BF473E /* MBEMetalViewIOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 845182FA20D8222100BF473E /* MBEMetalViewIOS.m */; };
+ 8451830020D8278F00BF473E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7961BD597A30006DDD8 /* ViewController.m */; };
+ 8451830120D827C800BF473E /* MBEMathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7B11BD598810006DDD8 /* MBEMathUtilities.m */; };
+ 8451830220D827C800BF473E /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7AC1BD598810006DDD8 /* MBERenderer.m */; };
+ 8451830320D827DC00BF473E /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 83E2D7AD1BD598810006DDD8 /* Shaders.metal */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -37,6 +48,18 @@
83E2D7AD1BD598810006DDD8 /* Shaders.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = ""; };
83E2D7B01BD598810006DDD8 /* MBEMathUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMathUtilities.h; sourceTree = ""; };
83E2D7B11BD598810006DDD8 /* MBEMathUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMathUtilities.m; sourceTree = ""; };
+ 845182E120D8214900BF473E /* Drawing in 3D.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Drawing in 3D.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 845182E320D8214900BF473E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
+ 845182E420D8214900BF473E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
+ 845182E920D8214A00BF473E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 845182EC20D8214A00BF473E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 845182EE20D8214A00BF473E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 845182EF20D8214A00BF473E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 845182F120D8214A00BF473E /* DrawingIn3D_Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DrawingIn3D_Mac.entitlements; sourceTree = ""; };
+ 845182F520D821B300BF473E /* MBEMetalViewMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewMac.h; sourceTree = ""; };
+ 845182F620D821B300BF473E /* MBEMetalViewMac.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewMac.m; sourceTree = ""; };
+ 845182F920D8222100BF473E /* MBEMetalViewIOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewIOS.h; sourceTree = ""; };
+ 845182FA20D8222100BF473E /* MBEMetalViewIOS.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewIOS.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -47,6 +70,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 845182DE20D8214900BF473E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -54,6 +84,7 @@
isa = PBXGroup;
children = (
83E2D78E1BD597A30006DDD8 /* DrawingIn3D */,
+ 845182E220D8214900BF473E /* DrawingIn3D-Mac */,
83E2D78D1BD597A30006DDD8 /* Products */,
);
sourceTree = "";
@@ -62,6 +93,7 @@
isa = PBXGroup;
children = (
83E2D78C1BD597A30006DDD8 /* DrawingIn3D.app */,
+ 845182E120D8214900BF473E /* Drawing in 3D.app */,
);
name = Products;
sourceTree = "";
@@ -71,20 +103,22 @@
children = (
83E2D7921BD597A30006DDD8 /* AppDelegate.h */,
83E2D7931BD597A30006DDD8 /* AppDelegate.m */,
- 83E2D7951BD597A30006DDD8 /* ViewController.h */,
- 83E2D7961BD597A30006DDD8 /* ViewController.m */,
+ 83E2D79B1BD597A30006DDD8 /* Assets.xcassets */,
+ 83E2D7A01BD597A30006DDD8 /* Info.plist */,
+ 83E2D79D1BD597A30006DDD8 /* LaunchScreen.storyboard */,
+ 83E2D7981BD597A30006DDD8 /* Main.storyboard */,
83E2D7B01BD598810006DDD8 /* MBEMathUtilities.h */,
83E2D7B11BD598810006DDD8 /* MBEMathUtilities.m */,
83E2D7A61BD598810006DDD8 /* MBEMetalView.h */,
83E2D7A71BD598810006DDD8 /* MBEMetalView.m */,
+ 845182F920D8222100BF473E /* MBEMetalViewIOS.h */,
+ 845182FA20D8222100BF473E /* MBEMetalViewIOS.m */,
83E2D7AB1BD598810006DDD8 /* MBERenderer.h */,
83E2D7AC1BD598810006DDD8 /* MBERenderer.m */,
83E2D7AD1BD598810006DDD8 /* Shaders.metal */,
- 83E2D7981BD597A30006DDD8 /* Main.storyboard */,
- 83E2D79B1BD597A30006DDD8 /* Assets.xcassets */,
- 83E2D79D1BD597A30006DDD8 /* LaunchScreen.storyboard */,
- 83E2D7A01BD597A30006DDD8 /* Info.plist */,
83E2D78F1BD597A30006DDD8 /* Supporting Files */,
+ 83E2D7951BD597A30006DDD8 /* ViewController.h */,
+ 83E2D7961BD597A30006DDD8 /* ViewController.m */,
);
path = DrawingIn3D;
sourceTree = "";
@@ -97,6 +131,22 @@
name = "Supporting Files";
sourceTree = "";
};
+ 845182E220D8214900BF473E /* DrawingIn3D-Mac */ = {
+ isa = PBXGroup;
+ children = (
+ 845182E320D8214900BF473E /* AppDelegate.h */,
+ 845182E420D8214900BF473E /* AppDelegate.m */,
+ 845182E920D8214A00BF473E /* Assets.xcassets */,
+ 845182F120D8214A00BF473E /* DrawingIn3D_Mac.entitlements */,
+ 845182EE20D8214A00BF473E /* Info.plist */,
+ 845182EF20D8214A00BF473E /* main.m */,
+ 845182EB20D8214A00BF473E /* Main.storyboard */,
+ 845182F520D821B300BF473E /* MBEMetalViewMac.h */,
+ 845182F620D821B300BF473E /* MBEMetalViewMac.m */,
+ );
+ path = "DrawingIn3D-Mac";
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -117,18 +167,39 @@
productReference = 83E2D78C1BD597A30006DDD8 /* DrawingIn3D.app */;
productType = "com.apple.product-type.application";
};
+ 845182E020D8214900BF473E /* DrawingIn3D-Mac */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 845182F220D8214A00BF473E /* Build configuration list for PBXNativeTarget "DrawingIn3D-Mac" */;
+ buildPhases = (
+ 845182DD20D8214900BF473E /* Sources */,
+ 845182DE20D8214900BF473E /* Frameworks */,
+ 845182DF20D8214900BF473E /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "DrawingIn3D-Mac";
+ productName = "DrawingIn3D-Mac";
+ productReference = 845182E120D8214900BF473E /* Drawing in 3D.app */;
+ productType = "com.apple.product-type.application";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
83E2D7841BD597A30006DDD8 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "Metal by Example";
TargetAttributes = {
83E2D78B1BD597A30006DDD8 = {
CreatedOnToolsVersion = 7.0;
};
+ 845182E020D8214900BF473E = {
+ CreatedOnToolsVersion = 9.4;
+ ProvisioningStyle = Automatic;
+ };
};
};
buildConfigurationList = 83E2D7871BD597A30006DDD8 /* Build configuration list for PBXProject "DrawingIn3D" */;
@@ -145,6 +216,7 @@
projectRoot = "";
targets = (
83E2D78B1BD597A30006DDD8 /* DrawingIn3D */,
+ 845182E020D8214900BF473E /* DrawingIn3D-Mac */,
);
};
/* End PBXProject section */
@@ -160,6 +232,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 845182DF20D8214900BF473E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 845182EA20D8214A00BF473E /* Assets.xcassets in Resources */,
+ 845182ED20D8214A00BF473E /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -168,6 +249,7 @@
buildActionMask = 2147483647;
files = (
83E2D7971BD597A30006DDD8 /* ViewController.m in Sources */,
+ 845182FB20D8222100BF473E /* MBEMetalViewIOS.m in Sources */,
83E2D7B61BD598810006DDD8 /* Shaders.metal in Sources */,
83E2D7941BD597A30006DDD8 /* AppDelegate.m in Sources */,
83E2D7B51BD598810006DDD8 /* MBERenderer.m in Sources */,
@@ -177,6 +259,21 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 845182DD20D8214900BF473E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8451830320D827DC00BF473E /* Shaders.metal in Sources */,
+ 8451830020D8278F00BF473E /* ViewController.m in Sources */,
+ 8451830120D827C800BF473E /* MBEMathUtilities.m in Sources */,
+ 845182F020D8214A00BF473E /* main.m in Sources */,
+ 845182E520D8214900BF473E /* AppDelegate.m in Sources */,
+ 8451830220D827C800BF473E /* MBERenderer.m in Sources */,
+ 845182F820D821DD00BF473E /* MBEMetalView.m in Sources */,
+ 845182F720D821B300BF473E /* MBEMetalViewMac.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
@@ -196,6 +293,14 @@
name = LaunchScreen.storyboard;
sourceTree = "";
};
+ 845182EB20D8214A00BF473E /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 845182EC20D8214A00BF473E /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@@ -211,12 +316,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -263,12 +370,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -321,6 +430,54 @@
};
name = Release;
};
+ 845182F320D8214A00BF473E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "DrawingIn3D-Mac/DrawingIn3D_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "DrawingIn3D-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.DrawingIn3D-Mac";
+ PRODUCT_NAME = "Drawing in 3D";
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 845182F420D8214A00BF473E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "DrawingIn3D-Mac/DrawingIn3D_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "DrawingIn3D-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.DrawingIn3D-Mac";
+ PRODUCT_NAME = "Drawing in 3D";
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -342,6 +499,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 845182F220D8214A00BF473E /* Build configuration list for PBXNativeTarget "DrawingIn3D-Mac" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 845182F320D8214A00BF473E /* Debug */,
+ 845182F420D8214A00BF473E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 83E2D7841BD597A30006DDD8 /* Project object */;
diff --git a/objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/objc/04-DrawingIn3D/DrawingIn3D/Base.lproj/Main.storyboard b/objc/04-DrawingIn3D/DrawingIn3D/Base.lproj/Main.storyboard
index 53b3c66..9033fb1 100644
--- a/objc/04-DrawingIn3D/DrawingIn3D/Base.lproj/Main.storyboard
+++ b/objc/04-DrawingIn3D/DrawingIn3D/Base.lproj/Main.storyboard
@@ -1,7 +1,12 @@
-
-
+
+
+
+
+
-
+
+
+
@@ -12,11 +17,10 @@
-
-
+
+
-
-
+
diff --git a/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalView.h b/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalView.h
index 3d4d533..c6c30f4 100644
--- a/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalView.h
+++ b/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalView.h
@@ -1,10 +1,18 @@
+#import
+
+#if TARGET_OS_IPHONE
@import UIKit;
+#define NSUIView UIView;
+#else
+@import AppKit;
+#define NSUIView NSView;
+#endif
@import Metal;
@import QuartzCore.CAMetalLayer;
@protocol MBEMetalViewDelegate;
-@interface MBEMetalView : UIView
+@interface MBEMetalView : NSUIView
/// The delegate of this view, responsible for drawing
@property (nonatomic, weak) id delegate;
@@ -36,6 +44,19 @@
/// size as its depth attachment's texture
@property (nonatomic, readonly) MTLRenderPassDescriptor *currentRenderPassDescriptor;
+// Subclass override points
+@property (nonatomic, readonly) CGSize drawableSize;
+
+- (void)makeDepthTexture;
+- (void)renderWithDuration:(NSTimeInterval)duration;
+
+@end
+
+// For subclasses
+@interface MBEMetalView ()
+@property (assign) NSTimeInterval frameDuration;
+@property (strong) id currentDrawable;
+@property (strong) id depthTexture;
@end
@protocol MBEMetalViewDelegate
diff --git a/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalView.m b/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalView.m
index 9726fb2..873e861 100644
--- a/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalView.m
+++ b/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalView.m
@@ -1,12 +1,5 @@
#import "MBEMetalView.h"
-@interface MBEMetalView ()
-@property (strong) id currentDrawable;
-@property (assign) NSTimeInterval frameDuration;
-@property (strong) id depthTexture;
-@property (strong) CADisplayLink *displayLink;
-@end
-
@implementation MBEMetalView
+ (Class)layerClass
@@ -52,24 +45,7 @@ - (void)commonInit
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
-
- // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
- CGFloat scale = [UIScreen mainScreen].scale;
-
- // If we've moved to a window by the time our frame is being set, we can take its scale as our own
- if (self.window)
- {
- scale = self.window.screen.scale;
- }
-
- CGSize drawableSize = self.bounds.size;
-
- // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
- drawableSize.width *= scale;
- drawableSize.height *= scale;
-
- self.metalLayer.drawableSize = drawableSize;
-
+ self.metalLayer.drawableSize = self.drawableSize;
[self makeDepthTexture];
}
@@ -83,37 +59,6 @@ - (MTLPixelFormat)colorPixelFormat
return self.metalLayer.pixelFormat;
}
-- (void)didMoveToWindow
-{
- const NSTimeInterval idealFrameDuration = (1.0 / 60);
- const NSTimeInterval targetFrameDuration = (1.0 / self.preferredFramesPerSecond);
- const NSInteger frameInterval = round(targetFrameDuration / idealFrameDuration);
-
- if (self.window)
- {
- [self.displayLink invalidate];
- self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
- self.displayLink.frameInterval = frameInterval;
- [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- }
- else
- {
- [self.displayLink invalidate];
- self.displayLink = nil;
- }
-}
-
-- (void)displayLinkDidFire:(CADisplayLink *)displayLink
-{
- self.currentDrawable = [self.metalLayer nextDrawable];
- self.frameDuration = displayLink.duration;
-
- if ([self.delegate respondsToSelector:@selector(drawInView:)])
- {
- [self.delegate drawInView:self];
- }
-}
-
- (void)makeDepthTexture
{
CGSize drawableSize = self.metalLayer.drawableSize;
@@ -126,6 +71,7 @@ - (void)makeDepthTexture
height:drawableSize.height
mipmapped:NO];
desc.usage = MTLTextureUsageRenderTarget;
+ desc.storageMode = MTLStorageModePrivate;
self.depthTexture = [self.metalLayer.device newTextureWithDescriptor:desc];
}
@@ -148,4 +94,14 @@ - (MTLRenderPassDescriptor *)currentRenderPassDescriptor
return passDescriptor;
}
+- (void)renderWithDuration:(NSTimeInterval)duration {
+ self.currentDrawable = [self.metalLayer nextDrawable];
+ self.frameDuration = duration;
+
+ if ([self.delegate respondsToSelector:@selector(drawInView:)])
+ {
+ [self.delegate drawInView:self];
+ }
+}
+
@end
diff --git a/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalViewIOS.h b/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalViewIOS.h
new file mode 100644
index 0000000..0547944
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalViewIOS.h
@@ -0,0 +1,13 @@
+//
+// MBEMetalViewIOS.h
+// DrawingIn3D
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalView.h"
+
+@interface MBEMetalViewIOS : MBEMetalView
+
+@end
diff --git a/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalViewIOS.m b/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalViewIOS.m
new file mode 100644
index 0000000..93710eb
--- /dev/null
+++ b/objc/04-DrawingIn3D/DrawingIn3D/MBEMetalViewIOS.m
@@ -0,0 +1,56 @@
+//
+// MBEMetalViewIOS.m
+// DrawingIn3D
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalViewIOS.h"
+
+@interface MBEMetalViewIOS()
+@property (strong) CADisplayLink *displayLink;
+@end
+
+@implementation MBEMetalViewIOS
+
+- (CGSize)drawableSize {
+
+ // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
+ // If we've moved to a window by the time our frame is being set, we can take its scale as our own
+ CGFloat scale = self.window ? self.window.screen.scale : [UIScreen mainScreen].scale;
+ CGSize drawableSize = self.bounds.size;
+
+ // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
+ drawableSize.width *= scale;
+ drawableSize.height *= scale;
+
+ return drawableSize;
+}
+
+- (void)didMoveToWindow
+{
+ const NSTimeInterval idealFrameDuration = (1.0 / 60);
+ const NSTimeInterval targetFrameDuration = (1.0 / self.preferredFramesPerSecond);
+ const NSInteger frameInterval = round(targetFrameDuration / idealFrameDuration);
+
+ if (self.window)
+ {
+ [self.displayLink invalidate];
+ self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
+ self.displayLink.frameInterval = frameInterval;
+ [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
+ }
+ else
+ {
+ [self.displayLink invalidate];
+ self.displayLink = nil;
+ }
+}
+
+- (void)displayLinkDidFire:(CADisplayLink *)displayLink
+{
+ [self renderWithDuration:displayLink.duration];
+}
+
+@end
diff --git a/objc/04-DrawingIn3D/DrawingIn3D/MBERenderer.m b/objc/04-DrawingIn3D/DrawingIn3D/MBERenderer.m
index da35207..e4ad951 100644
--- a/objc/04-DrawingIn3D/DrawingIn3D/MBERenderer.m
+++ b/objc/04-DrawingIn3D/DrawingIn3D/MBERenderer.m
@@ -112,7 +112,7 @@ - (void)makeBuffers
options:MTLResourceOptionCPUCacheModeDefault];
[_indexBuffer setLabel:@"Indices"];
- _uniformBuffer = [self.device newBufferWithLength:sizeof(MBEUniforms) * MBEInFlightBufferCount
+ _uniformBuffer = [self.device newBufferWithLength:self.uniformSize * MBEInFlightBufferCount
options:MTLResourceOptionCPUCacheModeDefault];
[_uniformBuffer setLabel:@"Uniforms"];
}
@@ -143,7 +143,7 @@ - (void)updateUniformsForView:(MBEMetalView *)view duration:(NSTimeInterval)dura
MBEUniforms uniforms;
uniforms.modelViewProjectionMatrix = matrix_multiply(projectionMatrix, matrix_multiply(viewMatrix, modelMatrix));
- const NSUInteger uniformBufferOffset = sizeof(MBEUniforms) * self.bufferIndex;
+ const NSUInteger uniformBufferOffset = self.uniformSize * self.bufferIndex;
memcpy([self.uniformBuffer contents] + uniformBufferOffset, &uniforms, sizeof(uniforms));
}
@@ -165,10 +165,8 @@ - (void)drawInView:(MBEMetalView *)view
[renderPass setFrontFacingWinding:MTLWindingCounterClockwise];
[renderPass setCullMode:MTLCullModeBack];
- const NSUInteger uniformBufferOffset = sizeof(MBEUniforms) * self.bufferIndex;
-
[renderPass setVertexBuffer:self.vertexBuffer offset:0 atIndex:0];
- [renderPass setVertexBuffer:self.uniformBuffer offset:uniformBufferOffset atIndex:1];
+ [renderPass setVertexBuffer:self.uniformBuffer offset:self.uniformSize * self.bufferIndex atIndex:1];
[renderPass drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:[self.indexBuffer length] / sizeof(MBEIndex)
@@ -188,4 +186,15 @@ - (void)drawInView:(MBEMetalView *)view
[commandBuffer commit];
}
+- (NSUInteger)uniformSize
+{
+ NSUInteger size = sizeof(MBEUniforms);
+#if TARGET_OS_MAC
+ if (size < 256) {
+ size = 256;
+ }
+#endif
+ return size;
+}
+
@end
diff --git a/objc/04-DrawingIn3D/DrawingIn3D/ViewController.h b/objc/04-DrawingIn3D/DrawingIn3D/ViewController.h
index 50a1e30..944d9df 100644
--- a/objc/04-DrawingIn3D/DrawingIn3D/ViewController.h
+++ b/objc/04-DrawingIn3D/DrawingIn3D/ViewController.h
@@ -1,7 +1,16 @@
+#import
+
+#if TARGET_OS_IPHONE
@import UIKit;
+#define NSUIViewController UIViewController
+#else
+@import AppKit;
+#define NSUIViewController NSViewController
+#endif
+
#import "MBERenderer.h"
-@interface ViewController : UIViewController
+@interface ViewController : NSUIViewController
@end
diff --git a/objc/05-Lighting/Lighting-Mac/AppDelegate.h b/objc/05-Lighting/Lighting-Mac/AppDelegate.h
new file mode 100644
index 0000000..42e9e32
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+// Lighting-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import
+
+@interface AppDelegate : NSObject
+
+
+@end
+
diff --git a/objc/05-Lighting/Lighting-Mac/AppDelegate.m b/objc/05-Lighting/Lighting-Mac/AppDelegate.m
new file mode 100644
index 0000000..7a979a7
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/AppDelegate.m
@@ -0,0 +1,27 @@
+//
+// AppDelegate.m
+// Lighting-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
+}
+
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
+}
+
+
+@end
diff --git a/objc/05-Lighting/Lighting-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json b/objc/05-Lighting/Lighting-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..2db2b1c
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/05-Lighting/Lighting-Mac/Assets.xcassets/Contents.json b/objc/05-Lighting/Lighting-Mac/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/05-Lighting/Lighting-Mac/Base.lproj/Main.storyboard b/objc/05-Lighting/Lighting-Mac/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..b8d5991
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/Base.lproj/Main.storyboard
@@ -0,0 +1,718 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+
+
+
+ Left to Right
+
+
+
+
+
+
+ Right to Left
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+
+
+
+ Left to Right
+
+
+
+
+
+
+ Right to Left
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/objc/05-Lighting/Lighting-Mac/Info.plist b/objc/05-Lighting/Lighting-Mac/Info.plist
new file mode 100644
index 0000000..7dd54bb
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ Copyright © 2018 Metal by Example. All rights reserved.
+ NSMainStoryboardFile
+ Main
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/objc/05-Lighting/Lighting-Mac/Lighting_Mac.entitlements b/objc/05-Lighting/Lighting-Mac/Lighting_Mac.entitlements
new file mode 100644
index 0000000..f2ef3ae
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/Lighting_Mac.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+
+
diff --git a/objc/05-Lighting/Lighting-Mac/MBEMetalViewMac.h b/objc/05-Lighting/Lighting-Mac/MBEMetalViewMac.h
new file mode 100644
index 0000000..f291345
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/MBEMetalViewMac.h
@@ -0,0 +1,15 @@
+//
+// MBEMetalViewMac.h
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+@import Cocoa;
+
+#import "MBEMetalView.h"
+
+@interface MBEMetalViewMac : MBEMetalView
+
+@end
diff --git a/objc/05-Lighting/Lighting-Mac/MBEMetalViewMac.m b/objc/05-Lighting/Lighting-Mac/MBEMetalViewMac.m
new file mode 100644
index 0000000..66bacd8
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/MBEMetalViewMac.m
@@ -0,0 +1,72 @@
+//
+// MBEMetalViewMac.m
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalViewMac.h"
+
+@interface MBEMetalViewMac()
+@property (nonatomic) CVDisplayLinkRef displayLink;
+@property (nonatomic, strong) CAMetalLayer *metalLayer;
+@end
+
+static NSTimeInterval C3DTimeIntervalFromTimeStamp(const CVTimeStamp *timeStamp) {
+ return 1.0 / (timeStamp->rateScalar * (double)timeStamp->videoTimeScale / (double)timeStamp->videoRefreshPeriod);
+}
+
+static CVReturn C3DViewDisplayLink(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *view) {
+ @autoreleasepool {
+ [(__bridge MBEMetalView *)view renderWithDuration:C3DTimeIntervalFromTimeStamp(inOutputTime)];
+ }
+
+ return kCVReturnSuccess;
+}
+
+@implementation MBEMetalViewMac
+
+@synthesize metalLayer=_metalLayer;
+
+- (CALayer *)makeBackingLayer
+{
+ CAMetalLayer *layer = [[CAMetalLayer alloc] init];
+ _metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
+ _metalLayer = layer;
+ return layer;
+}
+
+- (CGSize)drawableSize {
+ return self.bounds.size;
+}
+
+- (void)viewDidMoveToSuperview
+{
+ [super viewDidMoveToSuperview];
+
+ if (self.metalLayer.device == nil) {
+ self.metalLayer.device = MTLCreateSystemDefaultDevice();
+ }
+ if (self.depthTexture == nil) {
+ [self makeDepthTexture];
+ }
+
+ if (self.superview) {
+ CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
+ CVDisplayLinkSetOutputCallback(_displayLink, C3DViewDisplayLink, (__bridge void *)(self));
+ CVDisplayLinkStart(_displayLink);
+ }
+ else {
+ CVDisplayLinkStop(_displayLink);
+ CVDisplayLinkRelease(_displayLink);
+ _displayLink = NULL;
+ }
+}
+
+@end
diff --git a/objc/05-Lighting/Lighting-Mac/main.m b/objc/05-Lighting/Lighting-Mac/main.m
new file mode 100644
index 0000000..afcea42
--- /dev/null
+++ b/objc/05-Lighting/Lighting-Mac/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// Lighting-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import
+
+int main(int argc, const char * argv[]) {
+ return NSApplicationMain(argc, argv);
+}
diff --git a/objc/05-Lighting/Lighting.xcodeproj/project.pbxproj b/objc/05-Lighting/Lighting.xcodeproj/project.pbxproj
index 8219d7f..60d0868 100644
--- a/objc/05-Lighting/Lighting.xcodeproj/project.pbxproj
+++ b/objc/05-Lighting/Lighting.xcodeproj/project.pbxproj
@@ -22,6 +22,22 @@
839E18BA1BE31DE300944528 /* MBEOBJModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839E18B71BE31DE300944528 /* MBEOBJModel.mm */; };
839E18BD1BE31EC300944528 /* teapot.obj in Resources */ = {isa = PBXBuildFile; fileRef = 839E18BC1BE31EC300944528 /* teapot.obj */; };
839E18C01BE3224E00944528 /* MBEMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18BF1BE3224E00944528 /* MBEMesh.m */; };
+ 8451830C20D8346200BF473E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451830B20D8346200BF473E /* AppDelegate.m */; };
+ 8451831120D8346200BF473E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8451831020D8346200BF473E /* Assets.xcassets */; };
+ 8451831420D8346200BF473E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8451831220D8346200BF473E /* Main.storyboard */; };
+ 8451831720D8346200BF473E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451831620D8346200BF473E /* main.m */; };
+ 8451831E20D835D400BF473E /* MBEMetalViewIOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451831D20D835D400BF473E /* MBEMetalViewIOS.m */; };
+ 8451832120D835EB00BF473E /* MBEMetalViewMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451832020D835EB00BF473E /* MBEMetalViewMac.m */; };
+ 8451832220D84E2A00BF473E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18971BE31CDA00944528 /* ViewController.m */; };
+ 8451832320D84E5800BF473E /* MBEMathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18A81BE31D6100944528 /* MBEMathUtilities.m */; };
+ 8451832420D84E5800BF473E /* MBEOBJGroup.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839E18B31BE31DE300944528 /* MBEOBJGroup.mm */; };
+ 8451832520D84E5800BF473E /* MBEOBJModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839E18B71BE31DE300944528 /* MBEOBJModel.mm */; };
+ 8451832620D84E5C00BF473E /* MBEMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18BF1BE3224E00944528 /* MBEMesh.m */; };
+ 8451832720D84E5C00BF473E /* MBEOBJMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18B51BE31DE300944528 /* MBEOBJMesh.m */; };
+ 8451832820D84E6000BF473E /* MBEMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18AA1BE31D6100944528 /* MBEMetalView.m */; };
+ 8451832920D84E7C00BF473E /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18AC1BE31D6100944528 /* MBERenderer.m */; };
+ 8451832A20D84EA300BF473E /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 839E18B01BE31D8A00944528 /* Shaders.metal */; };
+ 8451832B20D84EA300BF473E /* teapot.obj in Resources */ = {isa = PBXBuildFile; fileRef = 839E18BC1BE31EC300944528 /* teapot.obj */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -52,6 +68,18 @@
839E18BC1BE31EC300944528 /* teapot.obj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = teapot.obj; sourceTree = ""; };
839E18BE1BE3224E00944528 /* MBEMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMesh.h; sourceTree = ""; };
839E18BF1BE3224E00944528 /* MBEMesh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMesh.m; sourceTree = ""; };
+ 8451830820D8346200BF473E /* Lighting.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Lighting.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8451830A20D8346200BF473E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
+ 8451830B20D8346200BF473E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
+ 8451831020D8346200BF473E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 8451831320D8346200BF473E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 8451831520D8346200BF473E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 8451831620D8346200BF473E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 8451831820D8346200BF473E /* Lighting_Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Lighting_Mac.entitlements; sourceTree = ""; };
+ 8451831C20D835D400BF473E /* MBEMetalViewIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewIOS.h; sourceTree = ""; };
+ 8451831D20D835D400BF473E /* MBEMetalViewIOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewIOS.m; sourceTree = ""; };
+ 8451831F20D835EB00BF473E /* MBEMetalViewMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewMac.h; sourceTree = ""; };
+ 8451832020D835EB00BF473E /* MBEMetalViewMac.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewMac.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -62,6 +90,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451830520D8346200BF473E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -69,6 +104,7 @@
isa = PBXGroup;
children = (
839E188F1BE31CDA00944528 /* Lighting */,
+ 8451830920D8346200BF473E /* Lighting-Mac */,
839E188E1BE31CDA00944528 /* Products */,
);
sourceTree = "";
@@ -77,6 +113,7 @@
isa = PBXGroup;
children = (
839E188D1BE31CDA00944528 /* Lighting.app */,
+ 8451830820D8346200BF473E /* Lighting.app */,
);
name = Products;
sourceTree = "";
@@ -120,11 +157,13 @@
839E18C21BE3252800944528 /* User Interface */ = {
isa = PBXGroup;
children = (
- 839E18C51BE3256C00944528 /* Storyboards */,
839E18931BE31CDA00944528 /* AppDelegate.h */,
839E18941BE31CDA00944528 /* AppDelegate.m */,
839E18A91BE31D6100944528 /* MBEMetalView.h */,
839E18AA1BE31D6100944528 /* MBEMetalView.m */,
+ 8451831C20D835D400BF473E /* MBEMetalViewIOS.h */,
+ 8451831D20D835D400BF473E /* MBEMetalViewIOS.m */,
+ 839E18C51BE3256C00944528 /* Storyboards */,
839E18961BE31CDA00944528 /* ViewController.h */,
839E18971BE31CDA00944528 /* ViewController.m */,
);
@@ -170,6 +209,22 @@
name = Utilities;
sourceTree = "";
};
+ 8451830920D8346200BF473E /* Lighting-Mac */ = {
+ isa = PBXGroup;
+ children = (
+ 8451830A20D8346200BF473E /* AppDelegate.h */,
+ 8451830B20D8346200BF473E /* AppDelegate.m */,
+ 8451831020D8346200BF473E /* Assets.xcassets */,
+ 8451831520D8346200BF473E /* Info.plist */,
+ 8451831820D8346200BF473E /* Lighting_Mac.entitlements */,
+ 8451831620D8346200BF473E /* main.m */,
+ 8451831220D8346200BF473E /* Main.storyboard */,
+ 8451831F20D835EB00BF473E /* MBEMetalViewMac.h */,
+ 8451832020D835EB00BF473E /* MBEMetalViewMac.m */,
+ );
+ path = "Lighting-Mac";
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -190,18 +245,39 @@
productReference = 839E188D1BE31CDA00944528 /* Lighting.app */;
productType = "com.apple.product-type.application";
};
+ 8451830720D8346200BF473E /* Lighting-Mac */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 8451831B20D8346200BF473E /* Build configuration list for PBXNativeTarget "Lighting-Mac" */;
+ buildPhases = (
+ 8451830420D8346200BF473E /* Sources */,
+ 8451830520D8346200BF473E /* Frameworks */,
+ 8451830620D8346200BF473E /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Lighting-Mac";
+ productName = "Lighting-Mac";
+ productReference = 8451830820D8346200BF473E /* Lighting.app */;
+ productType = "com.apple.product-type.application";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
839E18851BE31CDA00944528 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "Metal by Example";
TargetAttributes = {
839E188C1BE31CDA00944528 = {
CreatedOnToolsVersion = 7.1;
};
+ 8451830720D8346200BF473E = {
+ CreatedOnToolsVersion = 9.4;
+ ProvisioningStyle = Automatic;
+ };
};
};
buildConfigurationList = 839E18881BE31CDA00944528 /* Build configuration list for PBXProject "Lighting" */;
@@ -218,6 +294,7 @@
projectRoot = "";
targets = (
839E188C1BE31CDA00944528 /* Lighting */,
+ 8451830720D8346200BF473E /* Lighting-Mac */,
);
};
/* End PBXProject section */
@@ -234,6 +311,16 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451830620D8346200BF473E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8451831120D8346200BF473E /* Assets.xcassets in Resources */,
+ 8451831420D8346200BF473E /* Main.storyboard in Resources */,
+ 8451832B20D84EA300BF473E /* teapot.obj in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -246,6 +333,7 @@
839E18B81BE31DE300944528 /* MBEOBJGroup.mm in Sources */,
839E18AF1BE31D6100944528 /* MBERenderer.m in Sources */,
839E18BA1BE31DE300944528 /* MBEOBJModel.mm in Sources */,
+ 8451831E20D835D400BF473E /* MBEMetalViewIOS.m in Sources */,
839E18951BE31CDA00944528 /* AppDelegate.m in Sources */,
839E18921BE31CDA00944528 /* main.m in Sources */,
839E18AE1BE31D6100944528 /* MBEMetalView.m in Sources */,
@@ -255,6 +343,25 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451830420D8346200BF473E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8451832A20D84EA300BF473E /* Shaders.metal in Sources */,
+ 8451832920D84E7C00BF473E /* MBERenderer.m in Sources */,
+ 8451831720D8346200BF473E /* main.m in Sources */,
+ 8451830C20D8346200BF473E /* AppDelegate.m in Sources */,
+ 8451832420D84E5800BF473E /* MBEOBJGroup.mm in Sources */,
+ 8451832820D84E6000BF473E /* MBEMetalView.m in Sources */,
+ 8451832320D84E5800BF473E /* MBEMathUtilities.m in Sources */,
+ 8451832520D84E5800BF473E /* MBEOBJModel.mm in Sources */,
+ 8451832620D84E5C00BF473E /* MBEMesh.m in Sources */,
+ 8451832220D84E2A00BF473E /* ViewController.m in Sources */,
+ 8451832120D835EB00BF473E /* MBEMetalViewMac.m in Sources */,
+ 8451832720D84E5C00BF473E /* MBEOBJMesh.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
@@ -274,6 +381,14 @@
name = LaunchScreen.storyboard;
sourceTree = "";
};
+ 8451831220D8346200BF473E /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 8451831320D8346200BF473E /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@@ -289,12 +404,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -341,12 +458,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -397,6 +516,54 @@
};
name = Release;
};
+ 8451831920D8346200BF473E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "Lighting-Mac/Lighting_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "Lighting-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.Lighting-Mac";
+ PRODUCT_NAME = Lighting;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 8451831A20D8346200BF473E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "Lighting-Mac/Lighting_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "Lighting-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.Lighting-Mac";
+ PRODUCT_NAME = Lighting;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -418,6 +585,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 8451831B20D8346200BF473E /* Build configuration list for PBXNativeTarget "Lighting-Mac" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 8451831920D8346200BF473E /* Debug */,
+ 8451831A20D8346200BF473E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 839E18851BE31CDA00944528 /* Project object */;
diff --git a/objc/05-Lighting/Lighting.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/objc/05-Lighting/Lighting.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/objc/05-Lighting/Lighting.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/objc/05-Lighting/Lighting/MBEMesh.h b/objc/05-Lighting/Lighting/MBEMesh.h
index 95870b9..d46fc57 100644
--- a/objc/05-Lighting/Lighting/MBEMesh.h
+++ b/objc/05-Lighting/Lighting/MBEMesh.h
@@ -1,4 +1,4 @@
-@import UIKit;
+@import Foundation;
@import Metal;
@interface MBEMesh : NSObject
diff --git a/objc/05-Lighting/Lighting/MBEMetalView.h b/objc/05-Lighting/Lighting/MBEMetalView.h
index 3d4d533..c6c30f4 100644
--- a/objc/05-Lighting/Lighting/MBEMetalView.h
+++ b/objc/05-Lighting/Lighting/MBEMetalView.h
@@ -1,10 +1,18 @@
+#import
+
+#if TARGET_OS_IPHONE
@import UIKit;
+#define NSUIView UIView;
+#else
+@import AppKit;
+#define NSUIView NSView;
+#endif
@import Metal;
@import QuartzCore.CAMetalLayer;
@protocol MBEMetalViewDelegate;
-@interface MBEMetalView : UIView
+@interface MBEMetalView : NSUIView
/// The delegate of this view, responsible for drawing
@property (nonatomic, weak) id delegate;
@@ -36,6 +44,19 @@
/// size as its depth attachment's texture
@property (nonatomic, readonly) MTLRenderPassDescriptor *currentRenderPassDescriptor;
+// Subclass override points
+@property (nonatomic, readonly) CGSize drawableSize;
+
+- (void)makeDepthTexture;
+- (void)renderWithDuration:(NSTimeInterval)duration;
+
+@end
+
+// For subclasses
+@interface MBEMetalView ()
+@property (assign) NSTimeInterval frameDuration;
+@property (strong) id currentDrawable;
+@property (strong) id depthTexture;
@end
@protocol MBEMetalViewDelegate
diff --git a/objc/05-Lighting/Lighting/MBEMetalView.m b/objc/05-Lighting/Lighting/MBEMetalView.m
index 846f367..873e861 100644
--- a/objc/05-Lighting/Lighting/MBEMetalView.m
+++ b/objc/05-Lighting/Lighting/MBEMetalView.m
@@ -1,12 +1,5 @@
#import "MBEMetalView.h"
-@interface MBEMetalView ()
-@property (strong) id currentDrawable;
-@property (assign) NSTimeInterval frameDuration;
-@property (strong) id depthTexture;
-@property (strong) CADisplayLink *displayLink;
-@end
-
@implementation MBEMetalView
+ (Class)layerClass
@@ -52,24 +45,7 @@ - (void)commonInit
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
-
- // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
- CGFloat scale = [UIScreen mainScreen].scale;
-
- // If we've moved to a window by the time our frame is being set, we can take its scale as our own
- if (self.window)
- {
- scale = self.window.screen.scale;
- }
-
- CGSize drawableSize = self.bounds.size;
-
- // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
- drawableSize.width *= scale;
- drawableSize.height *= scale;
-
- self.metalLayer.drawableSize = drawableSize;
-
+ self.metalLayer.drawableSize = self.drawableSize;
[self makeDepthTexture];
}
@@ -83,37 +59,6 @@ - (MTLPixelFormat)colorPixelFormat
return self.metalLayer.pixelFormat;
}
-- (void)didMoveToWindow
-{
- const NSTimeInterval idealFrameDuration = (1.0 / 60);
- const NSTimeInterval targetFrameDuration = (1.0 / self.preferredFramesPerSecond);
- const NSInteger frameInterval = round(targetFrameDuration / idealFrameDuration);
-
- if (self.window)
- {
- [self.displayLink invalidate];
- self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
- self.displayLink.frameInterval = frameInterval;
- [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- }
- else
- {
- [self.displayLink invalidate];
- self.displayLink = nil;
- }
-}
-
-- (void)displayLinkDidFire:(CADisplayLink *)displayLink
-{
- self.currentDrawable = [self.metalLayer nextDrawable];
- self.frameDuration = displayLink.duration;
-
- if ([self.delegate respondsToSelector:@selector(drawInView:)])
- {
- [self.delegate drawInView:self];
- }
-}
-
- (void)makeDepthTexture
{
CGSize drawableSize = self.metalLayer.drawableSize;
@@ -126,6 +71,8 @@ - (void)makeDepthTexture
height:drawableSize.height
mipmapped:NO];
desc.usage = MTLTextureUsageRenderTarget;
+ desc.storageMode = MTLStorageModePrivate;
+
self.depthTexture = [self.metalLayer.device newTextureWithDescriptor:desc];
}
}
@@ -147,4 +94,14 @@ - (MTLRenderPassDescriptor *)currentRenderPassDescriptor
return passDescriptor;
}
+- (void)renderWithDuration:(NSTimeInterval)duration {
+ self.currentDrawable = [self.metalLayer nextDrawable];
+ self.frameDuration = duration;
+
+ if ([self.delegate respondsToSelector:@selector(drawInView:)])
+ {
+ [self.delegate drawInView:self];
+ }
+}
+
@end
diff --git a/objc/05-Lighting/Lighting/MBEMetalViewIOS.h b/objc/05-Lighting/Lighting/MBEMetalViewIOS.h
new file mode 100644
index 0000000..0547944
--- /dev/null
+++ b/objc/05-Lighting/Lighting/MBEMetalViewIOS.h
@@ -0,0 +1,13 @@
+//
+// MBEMetalViewIOS.h
+// DrawingIn3D
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalView.h"
+
+@interface MBEMetalViewIOS : MBEMetalView
+
+@end
diff --git a/objc/05-Lighting/Lighting/MBEMetalViewIOS.m b/objc/05-Lighting/Lighting/MBEMetalViewIOS.m
new file mode 100644
index 0000000..93710eb
--- /dev/null
+++ b/objc/05-Lighting/Lighting/MBEMetalViewIOS.m
@@ -0,0 +1,56 @@
+//
+// MBEMetalViewIOS.m
+// DrawingIn3D
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalViewIOS.h"
+
+@interface MBEMetalViewIOS()
+@property (strong) CADisplayLink *displayLink;
+@end
+
+@implementation MBEMetalViewIOS
+
+- (CGSize)drawableSize {
+
+ // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
+ // If we've moved to a window by the time our frame is being set, we can take its scale as our own
+ CGFloat scale = self.window ? self.window.screen.scale : [UIScreen mainScreen].scale;
+ CGSize drawableSize = self.bounds.size;
+
+ // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
+ drawableSize.width *= scale;
+ drawableSize.height *= scale;
+
+ return drawableSize;
+}
+
+- (void)didMoveToWindow
+{
+ const NSTimeInterval idealFrameDuration = (1.0 / 60);
+ const NSTimeInterval targetFrameDuration = (1.0 / self.preferredFramesPerSecond);
+ const NSInteger frameInterval = round(targetFrameDuration / idealFrameDuration);
+
+ if (self.window)
+ {
+ [self.displayLink invalidate];
+ self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
+ self.displayLink.frameInterval = frameInterval;
+ [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
+ }
+ else
+ {
+ [self.displayLink invalidate];
+ self.displayLink = nil;
+ }
+}
+
+- (void)displayLinkDidFire:(CADisplayLink *)displayLink
+{
+ [self renderWithDuration:displayLink.duration];
+}
+
+@end
diff --git a/objc/05-Lighting/Lighting/MBERenderer.m b/objc/05-Lighting/Lighting/MBERenderer.m
index 48e2efe..4a52c4c 100644
--- a/objc/05-Lighting/Lighting/MBERenderer.m
+++ b/objc/05-Lighting/Lighting/MBERenderer.m
@@ -73,7 +73,7 @@ - (void)makeResources
MBEOBJGroup *group = [model groupForName:@"teapot"];
_mesh = [[MBEOBJMesh alloc] initWithGroup:group device:_device];
- _uniformBuffer = [self.device newBufferWithLength:sizeof(MBEUniforms) * MBEInFlightBufferCount
+ _uniformBuffer = [self.device newBufferWithLength:self.uniformSize * MBEInFlightBufferCount
options:MTLResourceOptionCPUCacheModeDefault];
[_uniformBuffer setLabel:@"Uniforms"];
}
@@ -106,7 +106,7 @@ - (void)updateUniformsForView:(MBEMetalView *)view duration:(NSTimeInterval)dura
uniforms.modelViewProjectionMatrix = matrix_multiply(projectionMatrix, uniforms.modelViewMatrix);
uniforms.normalMatrix = matrix_float4x4_extract_linear(uniforms.modelViewMatrix);
- const NSUInteger uniformBufferOffset = sizeof(MBEUniforms) * self.bufferIndex;
+ const NSUInteger uniformBufferOffset = self.uniformSize * self.bufferIndex;
memcpy([self.uniformBuffer contents] + uniformBufferOffset, &uniforms, sizeof(uniforms));
}
@@ -128,7 +128,7 @@ - (void)drawInView:(MBEMetalView *)view
[renderPass setFrontFacingWinding:MTLWindingCounterClockwise];
[renderPass setCullMode:MTLCullModeBack];
- const NSUInteger uniformBufferOffset = sizeof(MBEUniforms) * self.bufferIndex;
+ const NSUInteger uniformBufferOffset = self.uniformSize * self.bufferIndex;
[renderPass setVertexBuffer:self.mesh.vertexBuffer offset:0 atIndex:0];
[renderPass setVertexBuffer:self.uniformBuffer offset:uniformBufferOffset atIndex:1];
@@ -151,4 +151,13 @@ - (void)drawInView:(MBEMetalView *)view
[commandBuffer commit];
}
+- (NSUInteger)uniformSize
+{
+ NSUInteger size = sizeof(MBEUniforms);
+#if TARGET_OS_MAC
+ size = (((NSUInteger)((CGFloat)(size - 1) / 256.0f) + 1) * 256);
+#endif
+ return size;
+}
+
@end
diff --git a/objc/05-Lighting/Lighting/ViewController.h b/objc/05-Lighting/Lighting/ViewController.h
index c8dda6c..2865375 100644
--- a/objc/05-Lighting/Lighting/ViewController.h
+++ b/objc/05-Lighting/Lighting/ViewController.h
@@ -1,6 +1,14 @@
+#import
+
+#if TARGET_OS_IPHONE
@import UIKit;
+#define NSUIViewController UIViewController
+#else
+@import AppKit;
+#define NSUIViewController NSViewController
+#endif
-@interface ViewController : UIViewController
+@interface ViewController : NSUIViewController
@end
diff --git a/objc/06-Texturing/Texturing-Mac/AppDelegate.h b/objc/06-Texturing/Texturing-Mac/AppDelegate.h
new file mode 100644
index 0000000..6c5d6ae
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+// Texturing-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import
+
+@interface AppDelegate : NSObject
+
+
+@end
+
diff --git a/objc/06-Texturing/Texturing-Mac/AppDelegate.m b/objc/06-Texturing/Texturing-Mac/AppDelegate.m
new file mode 100644
index 0000000..add7941
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/AppDelegate.m
@@ -0,0 +1,27 @@
+//
+// AppDelegate.m
+// Texturing-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
+}
+
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
+}
+
+
+@end
diff --git a/objc/06-Texturing/Texturing-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json b/objc/06-Texturing/Texturing-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..2db2b1c
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/06-Texturing/Texturing-Mac/Assets.xcassets/Contents.json b/objc/06-Texturing/Texturing-Mac/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/06-Texturing/Texturing-Mac/Base.lproj/Main.storyboard b/objc/06-Texturing/Texturing-Mac/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..4ae9657
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/Base.lproj/Main.storyboard
@@ -0,0 +1,718 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+
+
+
+ Left to Right
+
+
+
+
+
+
+ Right to Left
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+
+
+
+ Left to Right
+
+
+
+
+
+
+ Right to Left
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/objc/06-Texturing/Texturing-Mac/Info.plist b/objc/06-Texturing/Texturing-Mac/Info.plist
new file mode 100644
index 0000000..7dd54bb
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ Copyright © 2018 Metal by Example. All rights reserved.
+ NSMainStoryboardFile
+ Main
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/objc/06-Texturing/Texturing-Mac/MBEMetalViewMac.h b/objc/06-Texturing/Texturing-Mac/MBEMetalViewMac.h
new file mode 100644
index 0000000..f291345
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/MBEMetalViewMac.h
@@ -0,0 +1,15 @@
+//
+// MBEMetalViewMac.h
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+@import Cocoa;
+
+#import "MBEMetalView.h"
+
+@interface MBEMetalViewMac : MBEMetalView
+
+@end
diff --git a/objc/06-Texturing/Texturing-Mac/MBEMetalViewMac.m b/objc/06-Texturing/Texturing-Mac/MBEMetalViewMac.m
new file mode 100644
index 0000000..66bacd8
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/MBEMetalViewMac.m
@@ -0,0 +1,72 @@
+//
+// MBEMetalViewMac.m
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalViewMac.h"
+
+@interface MBEMetalViewMac()
+@property (nonatomic) CVDisplayLinkRef displayLink;
+@property (nonatomic, strong) CAMetalLayer *metalLayer;
+@end
+
+static NSTimeInterval C3DTimeIntervalFromTimeStamp(const CVTimeStamp *timeStamp) {
+ return 1.0 / (timeStamp->rateScalar * (double)timeStamp->videoTimeScale / (double)timeStamp->videoRefreshPeriod);
+}
+
+static CVReturn C3DViewDisplayLink(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *view) {
+ @autoreleasepool {
+ [(__bridge MBEMetalView *)view renderWithDuration:C3DTimeIntervalFromTimeStamp(inOutputTime)];
+ }
+
+ return kCVReturnSuccess;
+}
+
+@implementation MBEMetalViewMac
+
+@synthesize metalLayer=_metalLayer;
+
+- (CALayer *)makeBackingLayer
+{
+ CAMetalLayer *layer = [[CAMetalLayer alloc] init];
+ _metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
+ _metalLayer = layer;
+ return layer;
+}
+
+- (CGSize)drawableSize {
+ return self.bounds.size;
+}
+
+- (void)viewDidMoveToSuperview
+{
+ [super viewDidMoveToSuperview];
+
+ if (self.metalLayer.device == nil) {
+ self.metalLayer.device = MTLCreateSystemDefaultDevice();
+ }
+ if (self.depthTexture == nil) {
+ [self makeDepthTexture];
+ }
+
+ if (self.superview) {
+ CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
+ CVDisplayLinkSetOutputCallback(_displayLink, C3DViewDisplayLink, (__bridge void *)(self));
+ CVDisplayLinkStart(_displayLink);
+ }
+ else {
+ CVDisplayLinkStop(_displayLink);
+ CVDisplayLinkRelease(_displayLink);
+ _displayLink = NULL;
+ }
+}
+
+@end
diff --git a/objc/06-Texturing/Texturing-Mac/Texturing_Mac.entitlements b/objc/06-Texturing/Texturing-Mac/Texturing_Mac.entitlements
new file mode 100644
index 0000000..f2ef3ae
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/Texturing_Mac.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+
+
diff --git a/objc/06-Texturing/Texturing-Mac/main.m b/objc/06-Texturing/Texturing-Mac/main.m
new file mode 100644
index 0000000..f1ea134
--- /dev/null
+++ b/objc/06-Texturing/Texturing-Mac/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// Texturing-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import
+
+int main(int argc, const char * argv[]) {
+ return NSApplicationMain(argc, argv);
+}
diff --git a/objc/06-Texturing/Texturing.xcodeproj/project.pbxproj b/objc/06-Texturing/Texturing.xcodeproj/project.pbxproj
index 331c2b0..faba112 100644
--- a/objc/06-Texturing/Texturing.xcodeproj/project.pbxproj
+++ b/objc/06-Texturing/Texturing.xcodeproj/project.pbxproj
@@ -22,11 +22,29 @@
839E18FF1BE3495400944528 /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18F71BE3495400944528 /* MBERenderer.m */; };
839E19021BE3497A00944528 /* MBEMaterial.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E19011BE3497A00944528 /* MBEMaterial.m */; };
839E190C1BE349AD00944528 /* moo.aiff in Resources */ = {isa = PBXBuildFile; fileRef = 839E19041BE349AC00944528 /* moo.aiff */; };
- 839E190D1BE349AD00944528 /* README.txt in Resources */ = {isa = PBXBuildFile; fileRef = 839E19051BE349AC00944528 /* README.txt */; };
839E190E1BE349AD00944528 /* spot.obj in Resources */ = {isa = PBXBuildFile; fileRef = 839E19061BE349AC00944528 /* spot.obj */; };
839E19111BE349AD00944528 /* spot_texture.png in Resources */ = {isa = PBXBuildFile; fileRef = 839E19091BE349AD00944528 /* spot_texture.png */; };
839E19191BE3583B00944528 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 839E19181BE3583B00944528 /* Shaders.metal */; };
839E191C1BE3596D00944528 /* MBETextureLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E191B1BE3596D00944528 /* MBETextureLoader.m */; };
+ 8451833420D918BA00BF473E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451833320D918BA00BF473E /* AppDelegate.m */; };
+ 8451833920D918BB00BF473E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8451833820D918BB00BF473E /* Assets.xcassets */; };
+ 8451833C20D918BB00BF473E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8451833A20D918BB00BF473E /* Main.storyboard */; };
+ 8451833F20D918BB00BF473E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451833E20D918BB00BF473E /* main.m */; };
+ 8451834420D919E200BF473E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18DA1BE348B800944528 /* ViewController.m */; };
+ 8451834520D919F100BF473E /* moo.aiff in Resources */ = {isa = PBXBuildFile; fileRef = 839E19041BE349AC00944528 /* moo.aiff */; };
+ 8451834620D91A6E00BF473E /* spot.obj in Resources */ = {isa = PBXBuildFile; fileRef = 839E19061BE349AC00944528 /* spot.obj */; };
+ 8451834720D91A7A00BF473E /* spot_texture.png in Resources */ = {isa = PBXBuildFile; fileRef = 839E19091BE349AD00944528 /* spot_texture.png */; };
+ 8451834820D91A9300BF473E /* MBEMathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18EB1BE3495400944528 /* MBEMathUtilities.m */; };
+ 8451834920D91A9300BF473E /* MBEMaterial.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E19011BE3497A00944528 /* MBEMaterial.m */; };
+ 8451834A20D91A9300BF473E /* MBEMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18ED1BE3495400944528 /* MBEMesh.m */; };
+ 8451834B20D91A9300BF473E /* MBETextureLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E191B1BE3596D00944528 /* MBETextureLoader.m */; };
+ 8451834C20D91A9300BF473E /* MBEOBJGroup.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839E18F11BE3495400944528 /* MBEOBJGroup.mm */; };
+ 8451834D20D91A9300BF473E /* MBEOBJMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18F31BE3495400944528 /* MBEOBJMesh.m */; };
+ 8451834E20D91A9300BF473E /* MBEOBJModel.mm in Sources */ = {isa = PBXBuildFile; fileRef = 839E18F51BE3495400944528 /* MBEOBJModel.mm */; };
+ 8451834F20D91A9300BF473E /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18F71BE3495400944528 /* MBERenderer.m */; };
+ 8451835020D91A9E00BF473E /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 839E19181BE3583B00944528 /* Shaders.metal */; };
+ 8451835320D91D9700BF473E /* MBEMetalViewMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451835220D91D9700BF473E /* MBEMetalViewMac.m */; };
+ 8451835420D91DAF00BF473E /* MBEMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 839E18EF1BE3495400944528 /* MBEMetalView.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -68,6 +86,16 @@
839E19181BE3583B00944528 /* Shaders.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = ""; };
839E191A1BE3596D00944528 /* MBETextureLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBETextureLoader.h; sourceTree = ""; };
839E191B1BE3596D00944528 /* MBETextureLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBETextureLoader.m; sourceTree = ""; };
+ 8451833020D918BA00BF473E /* Texturing.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Texturing.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8451833220D918BA00BF473E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
+ 8451833320D918BA00BF473E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
+ 8451833820D918BB00BF473E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 8451833B20D918BB00BF473E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 8451833D20D918BB00BF473E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 8451833E20D918BB00BF473E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 8451834020D918BB00BF473E /* Texturing_Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Texturing_Mac.entitlements; sourceTree = ""; };
+ 8451835120D91D9700BF473E /* MBEMetalViewMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewMac.h; sourceTree = ""; };
+ 8451835220D91D9700BF473E /* MBEMetalViewMac.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewMac.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -78,6 +106,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451832D20D918BA00BF473E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -85,6 +120,7 @@
isa = PBXGroup;
children = (
839E18D21BE348B800944528 /* Texturing */,
+ 8451833120D918BA00BF473E /* Texturing-Mac */,
839E18D11BE348B800944528 /* Products */,
);
sourceTree = "";
@@ -93,6 +129,7 @@
isa = PBXGroup;
children = (
839E18D01BE348B800944528 /* Texturing.app */,
+ 8451833020D918BA00BF473E /* Texturing.app */,
);
name = Products;
sourceTree = "";
@@ -157,6 +194,22 @@
path = spot;
sourceTree = "";
};
+ 8451833120D918BA00BF473E /* Texturing-Mac */ = {
+ isa = PBXGroup;
+ children = (
+ 8451833220D918BA00BF473E /* AppDelegate.h */,
+ 8451833320D918BA00BF473E /* AppDelegate.m */,
+ 8451833820D918BB00BF473E /* Assets.xcassets */,
+ 8451833D20D918BB00BF473E /* Info.plist */,
+ 8451833E20D918BB00BF473E /* main.m */,
+ 8451833A20D918BB00BF473E /* Main.storyboard */,
+ 8451835120D91D9700BF473E /* MBEMetalViewMac.h */,
+ 8451835220D91D9700BF473E /* MBEMetalViewMac.m */,
+ 8451834020D918BB00BF473E /* Texturing_Mac.entitlements */,
+ );
+ path = "Texturing-Mac";
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -177,18 +230,39 @@
productReference = 839E18D01BE348B800944528 /* Texturing.app */;
productType = "com.apple.product-type.application";
};
+ 8451832F20D918BA00BF473E /* Texturing-Mac */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 8451834320D918BB00BF473E /* Build configuration list for PBXNativeTarget "Texturing-Mac" */;
+ buildPhases = (
+ 8451832C20D918BA00BF473E /* Sources */,
+ 8451832D20D918BA00BF473E /* Frameworks */,
+ 8451832E20D918BA00BF473E /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Texturing-Mac";
+ productName = "Texturing-Mac";
+ productReference = 8451833020D918BA00BF473E /* Texturing.app */;
+ productType = "com.apple.product-type.application";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
839E18C81BE348B800944528 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "Metal by Example";
TargetAttributes = {
839E18CF1BE348B800944528 = {
CreatedOnToolsVersion = 7.1;
};
+ 8451832F20D918BA00BF473E = {
+ CreatedOnToolsVersion = 9.4;
+ ProvisioningStyle = Automatic;
+ };
};
};
buildConfigurationList = 839E18CB1BE348B800944528 /* Build configuration list for PBXProject "Texturing" */;
@@ -205,6 +279,7 @@
projectRoot = "";
targets = (
839E18CF1BE348B800944528 /* Texturing */,
+ 8451832F20D918BA00BF473E /* Texturing-Mac */,
);
};
/* End PBXProject section */
@@ -220,7 +295,18 @@
839E190E1BE349AD00944528 /* spot.obj in Resources */,
839E190C1BE349AD00944528 /* moo.aiff in Resources */,
839E19111BE349AD00944528 /* spot_texture.png in Resources */,
- 839E190D1BE349AD00944528 /* README.txt in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 8451832E20D918BA00BF473E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8451834720D91A7A00BF473E /* spot_texture.png in Resources */,
+ 8451834620D91A6E00BF473E /* spot.obj in Resources */,
+ 8451833920D918BB00BF473E /* Assets.xcassets in Resources */,
+ 8451833C20D918BB00BF473E /* Main.storyboard in Resources */,
+ 8451834520D919F100BF473E /* moo.aiff in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -247,6 +333,27 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451832C20D918BA00BF473E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8451835020D91A9E00BF473E /* Shaders.metal in Sources */,
+ 8451835420D91DAF00BF473E /* MBEMetalView.m in Sources */,
+ 8451834F20D91A9300BF473E /* MBERenderer.m in Sources */,
+ 8451834920D91A9300BF473E /* MBEMaterial.m in Sources */,
+ 8451834420D919E200BF473E /* ViewController.m in Sources */,
+ 8451834C20D91A9300BF473E /* MBEOBJGroup.mm in Sources */,
+ 8451833F20D918BB00BF473E /* main.m in Sources */,
+ 8451834E20D91A9300BF473E /* MBEOBJModel.mm in Sources */,
+ 8451833420D918BA00BF473E /* AppDelegate.m in Sources */,
+ 8451834820D91A9300BF473E /* MBEMathUtilities.m in Sources */,
+ 8451835320D91D9700BF473E /* MBEMetalViewMac.m in Sources */,
+ 8451834B20D91A9300BF473E /* MBETextureLoader.m in Sources */,
+ 8451834A20D91A9300BF473E /* MBEMesh.m in Sources */,
+ 8451834D20D91A9300BF473E /* MBEOBJMesh.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
@@ -266,6 +373,14 @@
name = LaunchScreen.storyboard;
sourceTree = "";
};
+ 8451833A20D918BB00BF473E /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 8451833B20D918BB00BF473E /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@@ -281,12 +396,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -333,12 +450,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -391,6 +510,54 @@
};
name = Release;
};
+ 8451834120D918BB00BF473E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "Texturing-Mac/Texturing_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "Texturing-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.Texturing-Mac";
+ PRODUCT_NAME = Texturing;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 8451834220D918BB00BF473E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "Texturing-Mac/Texturing_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "Texturing-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.Texturing-Mac";
+ PRODUCT_NAME = Texturing;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -412,6 +579,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 8451834320D918BB00BF473E /* Build configuration list for PBXNativeTarget "Texturing-Mac" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 8451834120D918BB00BF473E /* Debug */,
+ 8451834220D918BB00BF473E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 839E18C81BE348B800944528 /* Project object */;
diff --git a/objc/06-Texturing/Texturing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/objc/06-Texturing/Texturing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/objc/06-Texturing/Texturing.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/objc/06-Texturing/Texturing/MBEMesh.h b/objc/06-Texturing/Texturing/MBEMesh.h
index 95870b9..d46fc57 100644
--- a/objc/06-Texturing/Texturing/MBEMesh.h
+++ b/objc/06-Texturing/Texturing/MBEMesh.h
@@ -1,4 +1,4 @@
-@import UIKit;
+@import Foundation;
@import Metal;
@interface MBEMesh : NSObject
diff --git a/objc/06-Texturing/Texturing/MBEMetalView.h b/objc/06-Texturing/Texturing/MBEMetalView.h
index 3d4d533..c6c30f4 100644
--- a/objc/06-Texturing/Texturing/MBEMetalView.h
+++ b/objc/06-Texturing/Texturing/MBEMetalView.h
@@ -1,10 +1,18 @@
+#import
+
+#if TARGET_OS_IPHONE
@import UIKit;
+#define NSUIView UIView;
+#else
+@import AppKit;
+#define NSUIView NSView;
+#endif
@import Metal;
@import QuartzCore.CAMetalLayer;
@protocol MBEMetalViewDelegate;
-@interface MBEMetalView : UIView
+@interface MBEMetalView : NSUIView
/// The delegate of this view, responsible for drawing
@property (nonatomic, weak) id delegate;
@@ -36,6 +44,19 @@
/// size as its depth attachment's texture
@property (nonatomic, readonly) MTLRenderPassDescriptor *currentRenderPassDescriptor;
+// Subclass override points
+@property (nonatomic, readonly) CGSize drawableSize;
+
+- (void)makeDepthTexture;
+- (void)renderWithDuration:(NSTimeInterval)duration;
+
+@end
+
+// For subclasses
+@interface MBEMetalView ()
+@property (assign) NSTimeInterval frameDuration;
+@property (strong) id currentDrawable;
+@property (strong) id depthTexture;
@end
@protocol MBEMetalViewDelegate
diff --git a/objc/06-Texturing/Texturing/MBEMetalView.m b/objc/06-Texturing/Texturing/MBEMetalView.m
index 846f367..873e861 100644
--- a/objc/06-Texturing/Texturing/MBEMetalView.m
+++ b/objc/06-Texturing/Texturing/MBEMetalView.m
@@ -1,12 +1,5 @@
#import "MBEMetalView.h"
-@interface MBEMetalView ()
-@property (strong) id currentDrawable;
-@property (assign) NSTimeInterval frameDuration;
-@property (strong) id depthTexture;
-@property (strong) CADisplayLink *displayLink;
-@end
-
@implementation MBEMetalView
+ (Class)layerClass
@@ -52,24 +45,7 @@ - (void)commonInit
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
-
- // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
- CGFloat scale = [UIScreen mainScreen].scale;
-
- // If we've moved to a window by the time our frame is being set, we can take its scale as our own
- if (self.window)
- {
- scale = self.window.screen.scale;
- }
-
- CGSize drawableSize = self.bounds.size;
-
- // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
- drawableSize.width *= scale;
- drawableSize.height *= scale;
-
- self.metalLayer.drawableSize = drawableSize;
-
+ self.metalLayer.drawableSize = self.drawableSize;
[self makeDepthTexture];
}
@@ -83,37 +59,6 @@ - (MTLPixelFormat)colorPixelFormat
return self.metalLayer.pixelFormat;
}
-- (void)didMoveToWindow
-{
- const NSTimeInterval idealFrameDuration = (1.0 / 60);
- const NSTimeInterval targetFrameDuration = (1.0 / self.preferredFramesPerSecond);
- const NSInteger frameInterval = round(targetFrameDuration / idealFrameDuration);
-
- if (self.window)
- {
- [self.displayLink invalidate];
- self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
- self.displayLink.frameInterval = frameInterval;
- [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- }
- else
- {
- [self.displayLink invalidate];
- self.displayLink = nil;
- }
-}
-
-- (void)displayLinkDidFire:(CADisplayLink *)displayLink
-{
- self.currentDrawable = [self.metalLayer nextDrawable];
- self.frameDuration = displayLink.duration;
-
- if ([self.delegate respondsToSelector:@selector(drawInView:)])
- {
- [self.delegate drawInView:self];
- }
-}
-
- (void)makeDepthTexture
{
CGSize drawableSize = self.metalLayer.drawableSize;
@@ -126,6 +71,8 @@ - (void)makeDepthTexture
height:drawableSize.height
mipmapped:NO];
desc.usage = MTLTextureUsageRenderTarget;
+ desc.storageMode = MTLStorageModePrivate;
+
self.depthTexture = [self.metalLayer.device newTextureWithDescriptor:desc];
}
}
@@ -147,4 +94,14 @@ - (MTLRenderPassDescriptor *)currentRenderPassDescriptor
return passDescriptor;
}
+- (void)renderWithDuration:(NSTimeInterval)duration {
+ self.currentDrawable = [self.metalLayer nextDrawable];
+ self.frameDuration = duration;
+
+ if ([self.delegate respondsToSelector:@selector(drawInView:)])
+ {
+ [self.delegate drawInView:self];
+ }
+}
+
@end
diff --git a/objc/06-Texturing/Texturing/MBEMetalViewIOS.h b/objc/06-Texturing/Texturing/MBEMetalViewIOS.h
new file mode 100644
index 0000000..0547944
--- /dev/null
+++ b/objc/06-Texturing/Texturing/MBEMetalViewIOS.h
@@ -0,0 +1,13 @@
+//
+// MBEMetalViewIOS.h
+// DrawingIn3D
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalView.h"
+
+@interface MBEMetalViewIOS : MBEMetalView
+
+@end
diff --git a/objc/06-Texturing/Texturing/MBEMetalViewIOS.m b/objc/06-Texturing/Texturing/MBEMetalViewIOS.m
new file mode 100644
index 0000000..93710eb
--- /dev/null
+++ b/objc/06-Texturing/Texturing/MBEMetalViewIOS.m
@@ -0,0 +1,56 @@
+//
+// MBEMetalViewIOS.m
+// DrawingIn3D
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalViewIOS.h"
+
+@interface MBEMetalViewIOS()
+@property (strong) CADisplayLink *displayLink;
+@end
+
+@implementation MBEMetalViewIOS
+
+- (CGSize)drawableSize {
+
+ // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
+ // If we've moved to a window by the time our frame is being set, we can take its scale as our own
+ CGFloat scale = self.window ? self.window.screen.scale : [UIScreen mainScreen].scale;
+ CGSize drawableSize = self.bounds.size;
+
+ // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
+ drawableSize.width *= scale;
+ drawableSize.height *= scale;
+
+ return drawableSize;
+}
+
+- (void)didMoveToWindow
+{
+ const NSTimeInterval idealFrameDuration = (1.0 / 60);
+ const NSTimeInterval targetFrameDuration = (1.0 / self.preferredFramesPerSecond);
+ const NSInteger frameInterval = round(targetFrameDuration / idealFrameDuration);
+
+ if (self.window)
+ {
+ [self.displayLink invalidate];
+ self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkDidFire:)];
+ self.displayLink.frameInterval = frameInterval;
+ [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
+ }
+ else
+ {
+ [self.displayLink invalidate];
+ self.displayLink = nil;
+ }
+}
+
+- (void)displayLinkDidFire:(CADisplayLink *)displayLink
+{
+ [self renderWithDuration:displayLink.duration];
+}
+
+@end
diff --git a/objc/06-Texturing/Texturing/MBERenderer.m b/objc/06-Texturing/Texturing/MBERenderer.m
index d52f1c4..db0f210 100644
--- a/objc/06-Texturing/Texturing/MBERenderer.m
+++ b/objc/06-Texturing/Texturing/MBERenderer.m
@@ -81,7 +81,7 @@ - (void)makeResources
_mesh = [[MBEOBJMesh alloc] initWithGroup:group device:_device];
// create uniform storage
- _uniformBuffer = [self.device newBufferWithLength:sizeof(MBEUniforms) * MBEInFlightBufferCount
+ _uniformBuffer = [self.device newBufferWithLength:self.uniformSize * MBEInFlightBufferCount
options:MTLResourceOptionCPUCacheModeDefault];
[_uniformBuffer setLabel:@"Uniforms"];
@@ -120,7 +120,7 @@ - (void)updateUniformsForView:(MBEMetalView *)view duration:(NSTimeInterval)dura
uniforms.modelViewProjectionMatrix = matrix_multiply(projectionMatrix, uniforms.modelViewMatrix);
uniforms.normalMatrix = matrix_float4x4_extract_linear(uniforms.modelViewMatrix);
- const NSUInteger uniformBufferOffset = sizeof(MBEUniforms) * self.bufferIndex;
+ const NSUInteger uniformBufferOffset = self.uniformSize * self.bufferIndex;
memcpy([self.uniformBuffer contents] + uniformBufferOffset, &uniforms, sizeof(uniforms));
}
@@ -144,7 +144,7 @@ - (void)drawInView:(MBEMetalView *)view
[renderPass setFrontFacingWinding:MTLWindingCounterClockwise];
[renderPass setCullMode:MTLCullModeBack];
- const NSUInteger uniformBufferOffset = sizeof(MBEUniforms) * self.bufferIndex;
+ const NSUInteger uniformBufferOffset = self.uniformSize * self.bufferIndex;
[renderPass setVertexBuffer:self.mesh.vertexBuffer offset:0 atIndex:0];
[renderPass setVertexBuffer:self.uniformBuffer offset:uniformBufferOffset atIndex:1];
@@ -171,4 +171,13 @@ - (void)drawInView:(MBEMetalView *)view
}
}
+- (NSUInteger)uniformSize
+{
+ NSUInteger size = sizeof(MBEUniforms);
+#if TARGET_OS_MAC
+ size = (((NSUInteger)((CGFloat)(size - 1) / 256.0f) + 1) * 256);
+#endif
+ return size;
+}
+
@end
diff --git a/objc/06-Texturing/Texturing/MBETextureLoader.h b/objc/06-Texturing/Texturing/MBETextureLoader.h
index 24b6cda..7b07a82 100644
--- a/objc/06-Texturing/Texturing/MBETextureLoader.h
+++ b/objc/06-Texturing/Texturing/MBETextureLoader.h
@@ -1,4 +1,4 @@
-@import UIKit;
+@import Foundation;
@import Metal;
@interface MBETextureLoader : NSObject
diff --git a/objc/06-Texturing/Texturing/MBETextureLoader.m b/objc/06-Texturing/Texturing/MBETextureLoader.m
index ac709c9..0485746 100644
--- a/objc/06-Texturing/Texturing/MBETextureLoader.m
+++ b/objc/06-Texturing/Texturing/MBETextureLoader.m
@@ -1,5 +1,19 @@
#import "MBETextureLoader.h"
+#if TARGET_OS_IPHONE
+@import UIKit;
+#define NSUIImage UIImage
+
+#else
+@import AppKit;
+#define NSUIImage NSImage
+
+@interface NSImage (Scale)
+@property (nonatomic, readonly) CGFloat scale;
+@property (nonatomic, readonly) CGImageRef CGImage;
+@end
+#endif
+
@implementation MBETextureLoader
+ (instancetype)sharedTextureLoader
@@ -16,7 +30,7 @@ + (instancetype)sharedTextureLoader
mipmapped:(BOOL)mipmapped
commandQueue:(id)queue
{
- UIImage *image = [UIImage imageNamed:imageName];
+ NSUIImage *image = [NSUIImage imageNamed:imageName];
if (image == nil)
{
@@ -50,7 +64,7 @@ + (instancetype)sharedTextureLoader
return texture;
}
-- (uint8_t *)dataForImage:(UIImage *)image
+- (uint8_t *)dataForImage:(NSUIImage *)image
{
CGImageRef imageRef = image.CGImage;
@@ -91,3 +105,16 @@ - (void)generateMipmapsForTexture:(id)texture onQueue:(id
+
+#if TARGET_OS_IPHONE
@import UIKit;
+#define NSUIViewController UIViewController
+#define NSUIPanGestureRecognizer UIPanGestureRecognizer
+#else
+@import AppKit;
+#define NSUIViewController NSViewController
+#define NSUIPanGestureRecognizer NSPanGestureRecognizer
+#endif
-@interface ViewController : UIViewController
+@interface ViewController : NSUIViewController
@end
diff --git a/objc/06-Texturing/Texturing/ViewController.m b/objc/06-Texturing/Texturing/ViewController.m
index d749ae8..33a8383 100644
--- a/objc/06-Texturing/Texturing/ViewController.m
+++ b/objc/06-Texturing/Texturing/ViewController.m
@@ -33,8 +33,8 @@ - (void)viewDidLoad {
self.renderer = [MBERenderer new];
self.metalView.delegate = self;
- UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self
- action:@selector(gestureDidRecognize:)];
+ NSUIPanGestureRecognizer *panGesture = [[NSUIPanGestureRecognizer alloc] initWithTarget:self
+ action:@selector(gestureDidRecognize:)];
[self.view addGestureRecognizer:panGesture];
[self loadResources];
@@ -45,10 +45,9 @@ - (BOOL)prefersStatusBarHidden {
}
-- (void)gestureDidRecognize:(UIGestureRecognizer *)gestureRecognizer
+- (void)gestureDidRecognize:(NSUIPanGestureRecognizer *)gestureRecognizer
{
- UIPanGestureRecognizer *panGestureRecognizer = (UIPanGestureRecognizer *)gestureRecognizer;
- CGPoint velocity = [panGestureRecognizer velocityInView:self.view];
+ CGPoint velocity = [gestureRecognizer velocityInView:self.view];
self.angularVelocity = CGPointMake(velocity.x * kVelocityScale, velocity.y * kVelocityScale);
}
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/AppDelegate.h b/objc/07-Mipmapping/Mipmapping-Mac/AppDelegate.h
new file mode 100644
index 0000000..3f62ac9
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+// Mipmapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import
+
+@interface AppDelegate : NSObject
+
+
+@end
+
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/AppDelegate.m b/objc/07-Mipmapping/Mipmapping-Mac/AppDelegate.m
new file mode 100644
index 0000000..737c400
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/AppDelegate.m
@@ -0,0 +1,27 @@
+//
+// AppDelegate.m
+// Mipmapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
+}
+
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
+}
+
+
+@end
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json b/objc/07-Mipmapping/Mipmapping-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..2db2b1c
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/Assets.xcassets/Contents.json b/objc/07-Mipmapping/Mipmapping-Mac/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/Base.lproj/Main.storyboard b/objc/07-Mipmapping/Mipmapping-Mac/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..cc6a4ab
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/Base.lproj/Main.storyboard
@@ -0,0 +1,718 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+
+
+
+ Left to Right
+
+
+
+
+
+
+ Right to Left
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+
+
+
+ Left to Right
+
+
+
+
+
+
+ Right to Left
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/Info.plist b/objc/07-Mipmapping/Mipmapping-Mac/Info.plist
new file mode 100644
index 0000000..2f4af8f
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ Copyright © 2018 Metal By Example. All rights reserved.
+ NSMainStoryboardFile
+ Main
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/MBEMetalViewMac.h b/objc/07-Mipmapping/Mipmapping-Mac/MBEMetalViewMac.h
new file mode 100644
index 0000000..52b30ba
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/MBEMetalViewMac.h
@@ -0,0 +1,13 @@
+//
+// MBEMetalViewMac.h
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalView.h"
+
+@interface MBEMetalViewMac : MBEMetalView
+
+@end
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/MBEMetalViewMac.m b/objc/07-Mipmapping/Mipmapping-Mac/MBEMetalViewMac.m
new file mode 100644
index 0000000..44a5382
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/MBEMetalViewMac.m
@@ -0,0 +1,35 @@
+//
+// MBEMetalViewMac.m
+// DrawingIn3D-Mac
+//
+// Created by Brent Gulanowski on 2018-06-18.
+// Copyright © 2018 Metal by Example. All rights reserved.
+//
+
+#import "MBEMetalViewMac.h"
+
+@import Metal;
+@import QuartzCore;
+
+@interface MBEMetalViewMac()
+@property (nonatomic, strong) CAMetalLayer *metalLayer;
+@end
+
+
+@implementation MBEMetalViewMac
+
+@synthesize metalLayer=_metalLayer;
+
+- (CALayer *)makeBackingLayer
+{
+ CAMetalLayer *layer = [[CAMetalLayer alloc] init];
+ _metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
+ _metalLayer = layer;
+ return layer;
+}
+
+- (CGSize)drawableSize {
+ return self.bounds.size;
+}
+
+@end
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/Mipmapping_Mac.entitlements b/objc/07-Mipmapping/Mipmapping-Mac/Mipmapping_Mac.entitlements
new file mode 100644
index 0000000..f2ef3ae
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/Mipmapping_Mac.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+
+
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/ViewController.h b/objc/07-Mipmapping/Mipmapping-Mac/ViewController.h
new file mode 100644
index 0000000..01a0237
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/ViewController.h
@@ -0,0 +1,18 @@
+//
+// ViewController.h
+// Mipmapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+@import Cocoa;
+
+#import "MBEMetalView.h"
+
+@interface ViewController : NSViewController
+
+@property (nonatomic, readonly) MBEMetalView *metalView;
+
+@end
+
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/ViewController.m b/objc/07-Mipmapping/Mipmapping-Mac/ViewController.m
new file mode 100644
index 0000000..c72a1b5
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/ViewController.m
@@ -0,0 +1,75 @@
+//
+// ViewController.m
+// Mipmapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import "ViewController.h"
+#import "MBERenderer.h"
+
+@interface ViewController ()
+
+@property (nonatomic) CVDisplayLinkRef displayLink;
+@property (nonatomic, strong) MBERenderer *renderer;
+
+- (void)draw;
+
+@end
+
+static CVReturn C3DViewDisplayLink(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *viewController)
+{
+ @autoreleasepool {
+ [(__bridge ViewController *)viewController draw];
+ }
+
+ return kCVReturnSuccess;
+}
+
+@implementation ViewController
+
+- (void)dealloc
+{
+ CVDisplayLinkRelease(_displayLink);
+ _displayLink = NULL;
+}
+
+- (MBEMetalView *)metalView
+{
+ return (MBEMetalView *)self.view;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.renderer = [[MBERenderer alloc] initWithLayer:self.metalView.metalLayer];
+ self.renderer.cameraDistance = 2.0f;
+
+ CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
+ CVDisplayLinkSetOutputCallback(_displayLink, C3DViewDisplayLink, (__bridge void *)(self));
+}
+
+- (void)viewWillAppear
+{
+ CVDisplayLinkStart(_displayLink);
+}
+
+- (void)viewWillDisappear
+{
+ CVDisplayLinkStop(_displayLink);
+}
+
+- (void)draw
+{
+ // TODO: implement UI controls
+ [self.renderer draw];
+}
+
+@end
diff --git a/objc/07-Mipmapping/Mipmapping-Mac/main.m b/objc/07-Mipmapping/Mipmapping-Mac/main.m
new file mode 100644
index 0000000..67e690d
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping-Mac/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// Mipmapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import
+
+int main(int argc, const char * argv[]) {
+ return NSApplicationMain(argc, argv);
+}
diff --git a/objc/07-Mipmapping/Mipmapping.xcodeproj/project.pbxproj b/objc/07-Mipmapping/Mipmapping.xcodeproj/project.pbxproj
index 1bb1ac1..73315f3 100644
--- a/objc/07-Mipmapping/Mipmapping.xcodeproj/project.pbxproj
+++ b/objc/07-Mipmapping/Mipmapping.xcodeproj/project.pbxproj
@@ -15,11 +15,25 @@
83A1BDEA1A365434005638E2 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 83A1BDE81A365434005638E2 /* LaunchScreen.xib */; };
83A1BE081A36759E005638E2 /* MBEMatrixUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE001A36759E005638E2 /* MBEMatrixUtilities.m */; };
83A1BE091A36759E005638E2 /* MBEMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE021A36759E005638E2 /* MBEMesh.m */; };
- 83A1BE0A1A36759E005638E2 /* MBEMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE041A36759E005638E2 /* MBEMetalView.m */; };
+ 83A1BE0A1A36759E005638E2 /* MBEMetalViewIOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE041A36759E005638E2 /* MBEMetalViewIOS.m */; };
83A1BE0B1A36759E005638E2 /* MBETextureGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE061A36759E005638E2 /* MBETextureGenerator.m */; };
83A1BE111A3675D7005638E2 /* MBECubeMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE101A3675D7005638E2 /* MBECubeMesh.m */; };
83A1BE141A37E584005638E2 /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE131A37E584005638E2 /* MBERenderer.m */; };
83A1BE181A37ED7C005638E2 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE171A37ED7C005638E2 /* Shaders.metal */; };
+ 8451835D20D91F9600BF473E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451835C20D91F9600BF473E /* AppDelegate.m */; };
+ 8451836020D91F9600BF473E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451835F20D91F9600BF473E /* ViewController.m */; };
+ 8451836220D91F9600BF473E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8451836120D91F9600BF473E /* Assets.xcassets */; };
+ 8451836520D91F9600BF473E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8451836320D91F9600BF473E /* Main.storyboard */; };
+ 8451836820D91F9600BF473E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451836720D91F9600BF473E /* main.m */; };
+ 8451837220D9226800BF473E /* MBEMetalViewMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451837020D9226800BF473E /* MBEMetalViewMac.m */; };
+ 8451837520D9236E00BF473E /* MBEMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451837420D9236E00BF473E /* MBEMetalView.m */; };
+ 8451837620D9236E00BF473E /* MBEMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451837420D9236E00BF473E /* MBEMetalView.m */; };
+ 8451837820D9274300BF473E /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE131A37E584005638E2 /* MBERenderer.m */; };
+ 8451837920D9274300BF473E /* MBEMatrixUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE001A36759E005638E2 /* MBEMatrixUtilities.m */; };
+ 8451837A20D9274300BF473E /* MBETextureGenerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE061A36759E005638E2 /* MBETextureGenerator.m */; };
+ 8451837E20D9306300BF473E /* MBECubeMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE101A3675D7005638E2 /* MBECubeMesh.m */; };
+ 8451837F20D9306300BF473E /* MBEMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE021A36759E005638E2 /* MBEMesh.m */; };
+ 8451838020D9309500BF473E /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 83A1BE171A37ED7C005638E2 /* Shaders.metal */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -37,8 +51,8 @@
83A1BE001A36759E005638E2 /* MBEMatrixUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMatrixUtilities.m; sourceTree = ""; };
83A1BE011A36759E005638E2 /* MBEMesh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMesh.h; sourceTree = ""; };
83A1BE021A36759E005638E2 /* MBEMesh.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMesh.m; sourceTree = ""; };
- 83A1BE031A36759E005638E2 /* MBEMetalView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMetalView.h; sourceTree = ""; };
- 83A1BE041A36759E005638E2 /* MBEMetalView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMetalView.m; sourceTree = ""; };
+ 83A1BE031A36759E005638E2 /* MBEMetalViewIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewIOS.h; sourceTree = ""; };
+ 83A1BE041A36759E005638E2 /* MBEMetalViewIOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewIOS.m; sourceTree = ""; };
83A1BE051A36759E005638E2 /* MBETextureGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBETextureGenerator.h; sourceTree = ""; };
83A1BE061A36759E005638E2 /* MBETextureGenerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBETextureGenerator.m; sourceTree = ""; };
83A1BE071A36759E005638E2 /* MBETypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBETypes.h; sourceTree = ""; };
@@ -47,6 +61,20 @@
83A1BE121A37E584005638E2 /* MBERenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBERenderer.h; sourceTree = ""; };
83A1BE131A37E584005638E2 /* MBERenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBERenderer.m; sourceTree = ""; };
83A1BE171A37ED7C005638E2 /* Shaders.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = ""; };
+ 8451835920D91F9600BF473E /* Mipmapping.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Mipmapping.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8451835B20D91F9600BF473E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
+ 8451835C20D91F9600BF473E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
+ 8451835E20D91F9600BF473E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
+ 8451835F20D91F9600BF473E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
+ 8451836120D91F9600BF473E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 8451836420D91F9600BF473E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 8451836620D91F9600BF473E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 8451836720D91F9600BF473E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 8451836920D91F9600BF473E /* Mipmapping_Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Mipmapping_Mac.entitlements; sourceTree = ""; };
+ 8451837020D9226800BF473E /* MBEMetalViewMac.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewMac.m; sourceTree = ""; };
+ 8451837120D9226800BF473E /* MBEMetalViewMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewMac.h; sourceTree = ""; };
+ 8451837320D9236E00BF473E /* MBEMetalView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBEMetalView.h; sourceTree = ""; };
+ 8451837420D9236E00BF473E /* MBEMetalView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBEMetalView.m; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -57,6 +85,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451835620D91F9600BF473E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -64,6 +99,7 @@
isa = PBXGroup;
children = (
83A1BDD81A365434005638E2 /* Mipmapping */,
+ 8451835A20D91F9600BF473E /* Mipmapping-Mac */,
83A1BDD71A365434005638E2 /* Products */,
);
sourceTree = "";
@@ -72,6 +108,7 @@
isa = PBXGroup;
children = (
83A1BDD61A365434005638E2 /* Mipmapping.app */,
+ 8451835920D91F9600BF473E /* Mipmapping.app */,
);
name = Products;
sourceTree = "";
@@ -120,16 +157,36 @@
83A1BE161A37EBBC005638E2 /* User Interface */ = {
isa = PBXGroup;
children = (
- 83A1BE031A36759E005638E2 /* MBEMetalView.h */,
- 83A1BE041A36759E005638E2 /* MBEMetalView.m */,
83A1BDDD1A365434005638E2 /* AppDelegate.h */,
83A1BDDE1A365434005638E2 /* AppDelegate.m */,
+ 8451837320D9236E00BF473E /* MBEMetalView.h */,
+ 8451837420D9236E00BF473E /* MBEMetalView.m */,
+ 83A1BE031A36759E005638E2 /* MBEMetalViewIOS.h */,
+ 83A1BE041A36759E005638E2 /* MBEMetalViewIOS.m */,
83A1BDE01A365434005638E2 /* MBEViewController.h */,
83A1BDE11A365434005638E2 /* MBEViewController.m */,
);
name = "User Interface";
sourceTree = "";
};
+ 8451835A20D91F9600BF473E /* Mipmapping-Mac */ = {
+ isa = PBXGroup;
+ children = (
+ 8451835B20D91F9600BF473E /* AppDelegate.h */,
+ 8451835C20D91F9600BF473E /* AppDelegate.m */,
+ 8451836120D91F9600BF473E /* Assets.xcassets */,
+ 8451836620D91F9600BF473E /* Info.plist */,
+ 8451836720D91F9600BF473E /* main.m */,
+ 8451836320D91F9600BF473E /* Main.storyboard */,
+ 8451837120D9226800BF473E /* MBEMetalViewMac.h */,
+ 8451837020D9226800BF473E /* MBEMetalViewMac.m */,
+ 8451836920D91F9600BF473E /* Mipmapping_Mac.entitlements */,
+ 8451835E20D91F9600BF473E /* ViewController.h */,
+ 8451835F20D91F9600BF473E /* ViewController.m */,
+ );
+ path = "Mipmapping-Mac";
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -150,18 +207,39 @@
productReference = 83A1BDD61A365434005638E2 /* Mipmapping.app */;
productType = "com.apple.product-type.application";
};
+ 8451835820D91F9600BF473E /* Mipmapping-Mac */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 8451836C20D91F9600BF473E /* Build configuration list for PBXNativeTarget "Mipmapping-Mac" */;
+ buildPhases = (
+ 8451835520D91F9600BF473E /* Sources */,
+ 8451835620D91F9600BF473E /* Frameworks */,
+ 8451835720D91F9600BF473E /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Mipmapping-Mac";
+ productName = "Mipmapping-Mac";
+ productReference = 8451835920D91F9600BF473E /* Mipmapping.app */;
+ productType = "com.apple.product-type.application";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
83A1BDCE1A365434005638E2 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "Metal By Example";
TargetAttributes = {
83A1BDD51A365434005638E2 = {
CreatedOnToolsVersion = 6.1.1;
};
+ 8451835820D91F9600BF473E = {
+ CreatedOnToolsVersion = 9.4;
+ ProvisioningStyle = Automatic;
+ };
};
};
buildConfigurationList = 83A1BDD11A365434005638E2 /* Build configuration list for PBXProject "Mipmapping" */;
@@ -178,6 +256,7 @@
projectRoot = "";
targets = (
83A1BDD51A365434005638E2 /* Mipmapping */,
+ 8451835820D91F9600BF473E /* Mipmapping-Mac */,
);
};
/* End PBXProject section */
@@ -193,6 +272,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451835720D91F9600BF473E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8451836220D91F9600BF473E /* Assets.xcassets in Resources */,
+ 8451836520D91F9600BF473E /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -200,9 +288,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ 8451837520D9236E00BF473E /* MBEMetalView.m in Sources */,
83A1BE111A3675D7005638E2 /* MBECubeMesh.m in Sources */,
83A1BE081A36759E005638E2 /* MBEMatrixUtilities.m in Sources */,
- 83A1BE0A1A36759E005638E2 /* MBEMetalView.m in Sources */,
+ 83A1BE0A1A36759E005638E2 /* MBEMetalViewIOS.m in Sources */,
83A1BDE21A365434005638E2 /* MBEViewController.m in Sources */,
83A1BDDF1A365434005638E2 /* AppDelegate.m in Sources */,
83A1BDDC1A365434005638E2 /* main.m in Sources */,
@@ -213,6 +302,24 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451835520D91F9600BF473E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8451836020D91F9600BF473E /* ViewController.m in Sources */,
+ 8451836820D91F9600BF473E /* main.m in Sources */,
+ 8451835D20D91F9600BF473E /* AppDelegate.m in Sources */,
+ 8451837920D9274300BF473E /* MBEMatrixUtilities.m in Sources */,
+ 8451837E20D9306300BF473E /* MBECubeMesh.m in Sources */,
+ 8451837A20D9274300BF473E /* MBETextureGenerator.m in Sources */,
+ 8451837820D9274300BF473E /* MBERenderer.m in Sources */,
+ 8451837620D9236E00BF473E /* MBEMetalView.m in Sources */,
+ 8451838020D9309500BF473E /* Shaders.metal in Sources */,
+ 8451837220D9226800BF473E /* MBEMetalViewMac.m in Sources */,
+ 8451837F20D9306300BF473E /* MBEMesh.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
@@ -232,6 +339,14 @@
name = LaunchScreen.xib;
sourceTree = "";
};
+ 8451836320D91F9600BF473E /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 8451836420D91F9600BF473E /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@@ -247,12 +362,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -299,12 +416,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -356,6 +475,57 @@
};
name = Release;
};
+ 8451836A20D91F9600BF473E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "Mipmapping-Mac/Mipmapping_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "Mipmapping-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.Mipmapping-Mac";
+ PRODUCT_NAME = Mipmapping;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 8451836B20D91F9600BF473E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "Mipmapping-Mac/Mipmapping_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "Mipmapping-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.Mipmapping-Mac";
+ PRODUCT_NAME = Mipmapping;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -377,6 +547,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 8451836C20D91F9600BF473E /* Build configuration list for PBXNativeTarget "Mipmapping-Mac" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 8451836A20D91F9600BF473E /* Debug */,
+ 8451836B20D91F9600BF473E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 83A1BDCE1A365434005638E2 /* Project object */;
diff --git a/objc/07-Mipmapping/Mipmapping.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/objc/07-Mipmapping/Mipmapping.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Contents.json b/objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Contents.json
index 77c57de..269b146 100644
--- a/objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Contents.json
+++ b/objc/07-Mipmapping/Mipmapping/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -1,5 +1,15 @@
{
"images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "3x"
+ },
{
"idiom" : "iphone",
"size" : "29x29",
@@ -32,6 +42,16 @@
"filename" : "Icon@3x.png",
"scale" : "3x"
},
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
{
"idiom" : "ipad",
"size" : "29x29",
@@ -63,6 +83,16 @@
"idiom" : "ipad",
"filename" : "Icon~ipad@2x.png",
"scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "size" : "1024x1024",
+ "scale" : "1x"
}
],
"info" : {
diff --git a/objc/07-Mipmapping/Mipmapping/MBEMesh.h b/objc/07-Mipmapping/Mipmapping/MBEMesh.h
index 34e366d..141d891 100644
--- a/objc/07-Mipmapping/Mipmapping/MBEMesh.h
+++ b/objc/07-Mipmapping/Mipmapping/MBEMesh.h
@@ -1,4 +1,4 @@
-@import UIKit;
+@import Foundation;
@import Metal;
#import "MBETypes.h"
diff --git a/objc/07-Mipmapping/Mipmapping/MBEMetalView.h b/objc/07-Mipmapping/Mipmapping/MBEMetalView.h
index a24c2cd..d865241 100644
--- a/objc/07-Mipmapping/Mipmapping/MBEMetalView.h
+++ b/objc/07-Mipmapping/Mipmapping/MBEMetalView.h
@@ -1,8 +1,26 @@
+//
+// MBEMetalView.h
+// Mipmapping
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import
+
+#if TARGET_OS_IPHONE
@import UIKit;
+#define NSUIView UIView;
+#else
+@import AppKit;
+#define NSUIView NSView;
+#endif
+
@import QuartzCore.CAMetalLayer;
-@interface MBEMetalView : UIView
+@interface MBEMetalView : NSUIView
@property (nonatomic, readonly) CAMetalLayer *metalLayer;
+@property (nonatomic, readonly) CGSize drawableSize;
@end
diff --git a/objc/07-Mipmapping/Mipmapping/MBEMetalView.m b/objc/07-Mipmapping/Mipmapping/MBEMetalView.m
index 04dd768..d8598b8 100644
--- a/objc/07-Mipmapping/Mipmapping/MBEMetalView.m
+++ b/objc/07-Mipmapping/Mipmapping/MBEMetalView.m
@@ -1,37 +1,19 @@
+//
+// MBEMetalView.m
+// Mipmapping
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
#import "MBEMetalView.h"
@implementation MBEMetalView
-+ (Class)layerClass
-{
- return [CAMetalLayer class];
-}
-
-- (CAMetalLayer *)metalLayer
-{
- return (CAMetalLayer *)self.layer;
-}
-
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
-
- // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
- CGFloat scale = [UIScreen mainScreen].scale;
-
- // If we've moved to a window by the time our frame is being set, we can take its scale as our own
- if (self.window)
- {
- scale = self.window.screen.scale;
- }
-
- CGSize drawableSize = self.bounds.size;
-
- // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
- drawableSize.width *= scale;
- drawableSize.height *= scale;
-
- self.metalLayer.drawableSize = drawableSize;
+ self.metalLayer.drawableSize = self.drawableSize;
}
@end
diff --git a/objc/07-Mipmapping/Mipmapping/MBEMetalViewIOS.h b/objc/07-Mipmapping/Mipmapping/MBEMetalViewIOS.h
new file mode 100644
index 0000000..a7b24dd
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping/MBEMetalViewIOS.h
@@ -0,0 +1,6 @@
+@import UIKit;
+@import QuartzCore.CAMetalLayer;
+
+@interface MBEMetalViewIOS : UIView
+
+@end
diff --git a/objc/07-Mipmapping/Mipmapping/MBEMetalViewIOS.m b/objc/07-Mipmapping/Mipmapping/MBEMetalViewIOS.m
new file mode 100644
index 0000000..055511a
--- /dev/null
+++ b/objc/07-Mipmapping/Mipmapping/MBEMetalViewIOS.m
@@ -0,0 +1,29 @@
+#import "MBEMetalViewIOS.h"
+
+@implementation MBEMetalViewIOS
+
++ (Class)layerClass
+{
+ return [CAMetalLayer class];
+}
+
+- (CAMetalLayer *)metalLayer
+{
+ return (CAMetalLayer *)self.layer;
+}
+
+- (CGSize)drawableSize {
+
+ // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
+ // If we've moved to a window by the time our frame is being set, we can take its scale as our own
+ CGFloat scale = self.window ? self.window.screen.scale : [UIScreen mainScreen].scale;
+ CGSize drawableSize = self.bounds.size;
+
+ // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
+ drawableSize.width *= scale;
+ drawableSize.height *= scale;
+
+ return drawableSize;
+}
+
+@end
diff --git a/objc/07-Mipmapping/Mipmapping/MBERenderer.h b/objc/07-Mipmapping/Mipmapping/MBERenderer.h
index 25d1a2e..a9b2059 100644
--- a/objc/07-Mipmapping/Mipmapping/MBERenderer.h
+++ b/objc/07-Mipmapping/Mipmapping/MBERenderer.h
@@ -1,4 +1,4 @@
-@import UIKit;
+@import Foundation;
@import QuartzCore.CAMetalLayer;
@import Metal;
diff --git a/objc/07-Mipmapping/Mipmapping/MBERenderer.m b/objc/07-Mipmapping/Mipmapping/MBERenderer.m
index aaf28f9..237611f 100644
--- a/objc/07-Mipmapping/Mipmapping/MBERenderer.m
+++ b/objc/07-Mipmapping/Mipmapping/MBERenderer.m
@@ -118,7 +118,7 @@ - (void)buildResources
device:_device
completion:^(id texture)
{
- _checkerTexture = texture;
+ self->_checkerTexture = texture;
}];
[MBETextureGenerator checkerboardTextureWithSize:textureSize
@@ -127,7 +127,7 @@ - (void)buildResources
device:_device
completion:^(id texture)
{
- _vibrantCheckerTexture = texture;
+ self->_vibrantCheckerTexture = texture;
}];
@@ -143,6 +143,7 @@ - (void)buildDepthBuffer
height:drawableSize.height
mipmapped:NO];
depthTexDesc.usage = MTLTextureUsageRenderTarget;
+ depthTexDesc.storageMode = MTLStorageModePrivate;
self.depthTexture = [self.device newTextureWithDescriptor:depthTexDesc];
}
diff --git a/objc/07-Mipmapping/Mipmapping/MBETextureGenerator.h b/objc/07-Mipmapping/Mipmapping/MBETextureGenerator.h
index 7d93a5f..438f12e 100644
--- a/objc/07-Mipmapping/Mipmapping/MBETextureGenerator.h
+++ b/objc/07-Mipmapping/Mipmapping/MBETextureGenerator.h
@@ -1,4 +1,4 @@
-@import UIKit;
+@import Foundation;
@import Metal;
@interface MBETextureGenerator : NSObject
diff --git a/objc/07-Mipmapping/Mipmapping/MBETextureGenerator.m b/objc/07-Mipmapping/Mipmapping/MBETextureGenerator.m
index 84da6a9..68d2749 100644
--- a/objc/07-Mipmapping/Mipmapping/MBETextureGenerator.m
+++ b/objc/07-Mipmapping/Mipmapping/MBETextureGenerator.m
@@ -1,5 +1,13 @@
#import "MBETextureGenerator.h"
+#if TARGET_OS_IPHONE
+@import UIKit;
+#define NSUIColor UIColor
+#else
+@import AppKit;
+#define NSUIColor NSColor
+#endif
+
static const NSUInteger bytesPerPixel = 4;
@implementation MBETextureGenerator
@@ -109,7 +117,7 @@ + (void)generateTintedMipmapsForTexture:(id)texture
{
NSUInteger mipBytesPerRow = bytesPerPixel * mipWidth;
- UIColor *tintColor = [self tintColorAtIndex:level - 1];
+ NSUIColor *tintColor = [self tintColorAtIndex:level - 1];
NSData *mipData = [self createResizedImageDataForImage:image
size:CGSizeMake(mipWidth, mipHeight)
tintColor:tintColor
@@ -148,7 +156,7 @@ + (void)generateMipmapsAcceleratedForTexture:(id)texture
+ (NSData *)createResizedImageDataForImage:(CGImageRef)image
size:(CGSize)size
- tintColor:(UIColor *)tintColor
+ tintColor:(NSUIColor *)tintColor
image:(CGImageRef *)outImage
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
@@ -191,24 +199,24 @@ + (NSData *)createResizedImageDataForImage:(CGImageRef)image
return [NSData dataWithBytesNoCopy:data length:dataLength freeWhenDone:YES];
}
-+ (UIColor *)tintColorAtIndex:(size_t)index
++ (NSUIColor *)tintColorAtIndex:(size_t)index
{
switch (index % 7) {
case 0:
- return [UIColor redColor];
+ return [NSUIColor redColor];
case 1:
- return [UIColor orangeColor];
+ return [NSUIColor orangeColor];
case 2:
- return [UIColor yellowColor];
+ return [NSUIColor yellowColor];
case 3:
- return [UIColor greenColor];
+ return [NSUIColor greenColor];
case 4:
- return [UIColor blueColor];
+ return [NSUIColor blueColor];
case 5:
- return [UIColor colorWithRed:0.5 green:0.0 blue:1.0 alpha:1.0]; // indigo
+ return [NSUIColor colorWithRed:0.5 green:0.0 blue:1.0 alpha:1.0]; // indigo
case 6:
default:
- return [UIColor purpleColor];
+ return [NSUIColor purpleColor];
}
}
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/AppDelegate.h b/objc/08-CubeMapping/CubeMapping-Mac/AppDelegate.h
new file mode 100644
index 0000000..619fbc1
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/AppDelegate.h
@@ -0,0 +1,15 @@
+//
+// AppDelegate.h
+// CubeMapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import
+
+@interface AppDelegate : NSObject
+
+
+@end
+
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/AppDelegate.m b/objc/08-CubeMapping/CubeMapping-Mac/AppDelegate.m
new file mode 100644
index 0000000..7f79b8f
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/AppDelegate.m
@@ -0,0 +1,27 @@
+//
+// AppDelegate.m
+// CubeMapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import "AppDelegate.h"
+
+@interface AppDelegate ()
+
+@end
+
+@implementation AppDelegate
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
+}
+
+
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
+}
+
+
+@end
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json b/objc/08-CubeMapping/CubeMapping-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..2db2b1c
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/Assets.xcassets/Contents.json b/objc/08-CubeMapping/CubeMapping-Mac/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/Base.lproj/Main.storyboard b/objc/08-CubeMapping/CubeMapping-Mac/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..609fe83
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/Base.lproj/Main.storyboard
@@ -0,0 +1,718 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+
+
+
+ Left to Right
+
+
+
+
+
+
+ Right to Left
+
+
+
+
+
+
+
+
+
+
+ Default
+
+
+
+
+
+
+ Left to Right
+
+
+
+
+
+
+ Right to Left
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/CubeMapping_Mac.entitlements b/objc/08-CubeMapping/CubeMapping-Mac/CubeMapping_Mac.entitlements
new file mode 100644
index 0000000..f2ef3ae
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/CubeMapping_Mac.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.app-sandbox
+
+ com.apple.security.files.user-selected.read-only
+
+
+
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/Info.plist b/objc/08-CubeMapping/CubeMapping-Mac/Info.plist
new file mode 100644
index 0000000..2f4af8f
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/Info.plist
@@ -0,0 +1,32 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIconFile
+
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSMinimumSystemVersion
+ $(MACOSX_DEPLOYMENT_TARGET)
+ NSHumanReadableCopyright
+ Copyright © 2018 Metal By Example. All rights reserved.
+ NSMainStoryboardFile
+ Main
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/ViewController.h b/objc/08-CubeMapping/CubeMapping-Mac/ViewController.h
new file mode 100644
index 0000000..01a0237
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/ViewController.h
@@ -0,0 +1,18 @@
+//
+// ViewController.h
+// Mipmapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+@import Cocoa;
+
+#import "MBEMetalView.h"
+
+@interface ViewController : NSViewController
+
+@property (nonatomic, readonly) MBEMetalView *metalView;
+
+@end
+
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/ViewController.m b/objc/08-CubeMapping/CubeMapping-Mac/ViewController.m
new file mode 100644
index 0000000..2efe4a0
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/ViewController.m
@@ -0,0 +1,74 @@
+//
+// ViewController.m
+// Mipmapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import "ViewController.h"
+#import "MBERenderer.h"
+
+@interface ViewController ()
+
+@property (nonatomic) CVDisplayLinkRef displayLink;
+@property (nonatomic, strong) MBERenderer *renderer;
+
+- (void)draw;
+
+@end
+
+static CVReturn C3DViewDisplayLink(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *viewController)
+{
+ @autoreleasepool {
+ [(__bridge ViewController *)viewController draw];
+ }
+
+ return kCVReturnSuccess;
+}
+
+@implementation ViewController
+
+- (void)dealloc
+{
+ CVDisplayLinkRelease(_displayLink);
+ _displayLink = NULL;
+}
+
+- (MBEMetalView *)metalView
+{
+ return (MBEMetalView *)self.view;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ self.renderer = [[MBERenderer alloc] initWithLayer:self.metalView.metalLayer];
+
+ CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
+ CVDisplayLinkSetOutputCallback(_displayLink, C3DViewDisplayLink, (__bridge void *)(self));
+}
+
+- (void)viewWillAppear
+{
+ CVDisplayLinkStart(_displayLink);
+}
+
+- (void)viewWillDisappear
+{
+ CVDisplayLinkStop(_displayLink);
+}
+
+- (void)draw
+{
+ // TODO: implement UI controls
+ [self.renderer draw];
+}
+
+@end
diff --git a/objc/08-CubeMapping/CubeMapping-Mac/main.m b/objc/08-CubeMapping/CubeMapping-Mac/main.m
new file mode 100644
index 0000000..1987f92
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping-Mac/main.m
@@ -0,0 +1,13 @@
+//
+// main.m
+// CubeMapping-Mac
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import
+
+int main(int argc, const char * argv[]) {
+ return NSApplicationMain(argc, argv);
+}
diff --git a/objc/08-CubeMapping/CubeMapping.xcodeproj/project.pbxproj b/objc/08-CubeMapping/CubeMapping.xcodeproj/project.pbxproj
index 1c1601c..21f381a 100644
--- a/objc/08-CubeMapping/CubeMapping.xcodeproj/project.pbxproj
+++ b/objc/08-CubeMapping/CubeMapping.xcodeproj/project.pbxproj
@@ -27,6 +27,27 @@
8362D1EA1A0D6BE500A6D9A8 /* MBETextureLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8362D1E91A0D6BE500A6D9A8 /* MBETextureLoader.m */; };
8362D1ED1A0D735800A6D9A8 /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8362D1EC1A0D735800A6D9A8 /* MBERenderer.m */; };
8362D1F11A0EA75F00A6D9A8 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 8362D1F01A0EA75F00A6D9A8 /* Shaders.metal */; };
+ 8451838920D932F000BF473E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451838820D932F000BF473E /* AppDelegate.m */; };
+ 8451838C20D932F000BF473E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451838B20D932F000BF473E /* ViewController.m */; };
+ 8451838E20D932F000BF473E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8451838D20D932F000BF473E /* Assets.xcassets */; };
+ 8451839120D932F000BF473E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8451838F20D932F000BF473E /* Main.storyboard */; };
+ 8451839420D932F000BF473E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8451839320D932F000BF473E /* main.m */; };
+ 8451839920D9337C00BF473E /* nx.png in Resources */ = {isa = PBXBuildFile; fileRef = 8362D1DC1A0D6B6E00A6D9A8 /* nx.png */; };
+ 8451839A20D9337C00BF473E /* ny.png in Resources */ = {isa = PBXBuildFile; fileRef = 8362D1DD1A0D6B6E00A6D9A8 /* ny.png */; };
+ 8451839B20D9337C00BF473E /* nz.png in Resources */ = {isa = PBXBuildFile; fileRef = 8362D1DE1A0D6B6E00A6D9A8 /* nz.png */; };
+ 8451839C20D9337C00BF473E /* px.png in Resources */ = {isa = PBXBuildFile; fileRef = 8362D1DF1A0D6B6E00A6D9A8 /* px.png */; };
+ 8451839D20D9337C00BF473E /* py.png in Resources */ = {isa = PBXBuildFile; fileRef = 8362D1E01A0D6B6E00A6D9A8 /* py.png */; };
+ 8451839E20D9337C00BF473E /* pz.png in Resources */ = {isa = PBXBuildFile; fileRef = 8362D1E11A0D6B6E00A6D9A8 /* pz.png */; };
+ 8451839F20D9339700BF473E /* MBERenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8362D1EC1A0D735800A6D9A8 /* MBERenderer.m */; };
+ 845183A020D9339700BF473E /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 8362D1F01A0EA75F00A6D9A8 /* Shaders.metal */; };
+ 845183A120D9339700BF473E /* MBEMatrixUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 832493251A1196B7001E2340 /* MBEMatrixUtilities.m */; };
+ 845183A220D9339700BF473E /* MBETextureLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8362D1E91A0D6BE500A6D9A8 /* MBETextureLoader.m */; };
+ 845183A320D9339700BF473E /* MBEMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 832493221A116424001E2340 /* MBEMesh.m */; };
+ 845183A420D9339700BF473E /* MBESkyboxMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 834B3CD51A0F1628009646DA /* MBESkyboxMesh.m */; };
+ 845183A520D9339700BF473E /* MBETorusKnotMesh.m in Sources */ = {isa = PBXBuildFile; fileRef = 8324931F1A113520001E2340 /* MBETorusKnotMesh.m */; };
+ 845183A820D934AD00BF473E /* MBEMetalViewMac.m in Sources */ = {isa = PBXBuildFile; fileRef = 845183A620D934AD00BF473E /* MBEMetalViewMac.m */; };
+ 845183AB20D9354400BF473E /* MBEMetalViewIOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 845183A920D9354400BF473E /* MBEMetalViewIOS.m */; };
+ 845183AC20D9356200BF473E /* MBEMetalView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8362D1CB1A0D653900A6D9A8 /* MBEMetalView.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -62,6 +83,20 @@
8362D1EB1A0D735800A6D9A8 /* MBERenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBERenderer.h; sourceTree = ""; };
8362D1EC1A0D735800A6D9A8 /* MBERenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBERenderer.m; sourceTree = ""; };
8362D1F01A0EA75F00A6D9A8 /* Shaders.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = ""; };
+ 8451838520D932F000BF473E /* Cube Mapping.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cube Mapping.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 8451838720D932F000BF473E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
+ 8451838820D932F000BF473E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
+ 8451838A20D932F000BF473E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
+ 8451838B20D932F000BF473E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
+ 8451838D20D932F000BF473E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 8451839020D932F000BF473E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 8451839220D932F000BF473E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 8451839320D932F000BF473E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 8451839520D932F000BF473E /* CubeMapping_Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CubeMapping_Mac.entitlements; sourceTree = ""; };
+ 845183A620D934AD00BF473E /* MBEMetalViewMac.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MBEMetalViewMac.m; path = "../../07-Mipmapping/Mipmapping-Mac/MBEMetalViewMac.m"; sourceTree = ""; };
+ 845183A720D934AD00BF473E /* MBEMetalViewMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MBEMetalViewMac.h; path = "../../07-Mipmapping/Mipmapping-Mac/MBEMetalViewMac.h"; sourceTree = ""; };
+ 845183A920D9354400BF473E /* MBEMetalViewIOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MBEMetalViewIOS.m; sourceTree = ""; };
+ 845183AA20D9354400BF473E /* MBEMetalViewIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MBEMetalViewIOS.h; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -72,6 +107,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451838220D932F000BF473E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@@ -92,6 +134,7 @@
isa = PBXGroup;
children = (
8362D1A31A0D5BEB00A6D9A8 /* CubeMapping */,
+ 8451838620D932F000BF473E /* CubeMapping-Mac */,
8362D1A21A0D5BEB00A6D9A8 /* Products */,
);
sourceTree = "";
@@ -100,6 +143,7 @@
isa = PBXGroup;
children = (
8362D1A11A0D5BEB00A6D9A8 /* CubeMapping.app */,
+ 8451838520D932F000BF473E /* Cube Mapping.app */,
);
name = Products;
sourceTree = "";
@@ -110,6 +154,8 @@
832493271A119747001E2340 /* MBETypes.h */,
8362D1CA1A0D653900A6D9A8 /* MBEMetalView.h */,
8362D1CB1A0D653900A6D9A8 /* MBEMetalView.m */,
+ 845183AA20D9354400BF473E /* MBEMetalViewIOS.h */,
+ 845183A920D9354400BF473E /* MBEMetalViewIOS.m */,
8362D1AB1A0D5BEB00A6D9A8 /* MBEViewController.h */,
8362D1AC1A0D5BEB00A6D9A8 /* MBEViewController.m */,
8362D1EB1A0D735800A6D9A8 /* MBERenderer.h */,
@@ -169,6 +215,24 @@
name = "User Interface";
sourceTree = "";
};
+ 8451838620D932F000BF473E /* CubeMapping-Mac */ = {
+ isa = PBXGroup;
+ children = (
+ 8451838720D932F000BF473E /* AppDelegate.h */,
+ 8451838820D932F000BF473E /* AppDelegate.m */,
+ 8451838D20D932F000BF473E /* Assets.xcassets */,
+ 8451839520D932F000BF473E /* CubeMapping_Mac.entitlements */,
+ 8451839220D932F000BF473E /* Info.plist */,
+ 8451839320D932F000BF473E /* main.m */,
+ 8451838F20D932F000BF473E /* Main.storyboard */,
+ 845183A720D934AD00BF473E /* MBEMetalViewMac.h */,
+ 845183A620D934AD00BF473E /* MBEMetalViewMac.m */,
+ 8451838A20D932F000BF473E /* ViewController.h */,
+ 8451838B20D932F000BF473E /* ViewController.m */,
+ );
+ path = "CubeMapping-Mac";
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -189,18 +253,39 @@
productReference = 8362D1A11A0D5BEB00A6D9A8 /* CubeMapping.app */;
productType = "com.apple.product-type.application";
};
+ 8451838420D932F000BF473E /* CubeMapping-Mac */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 8451839820D932F000BF473E /* Build configuration list for PBXNativeTarget "CubeMapping-Mac" */;
+ buildPhases = (
+ 8451838120D932F000BF473E /* Sources */,
+ 8451838220D932F000BF473E /* Frameworks */,
+ 8451838320D932F000BF473E /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "CubeMapping-Mac";
+ productName = "CubeMapping-Mac";
+ productReference = 8451838520D932F000BF473E /* Cube Mapping.app */;
+ productType = "com.apple.product-type.application";
+ };
/* End PBXNativeTarget section */
/* Begin PBXProject section */
8362D1991A0D5BEB00A6D9A8 /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0900;
+ LastUpgradeCheck = 0940;
ORGANIZATIONNAME = "Metal By Example";
TargetAttributes = {
8362D1A01A0D5BEB00A6D9A8 = {
CreatedOnToolsVersion = 6.1;
};
+ 8451838420D932F000BF473E = {
+ CreatedOnToolsVersion = 9.4;
+ ProvisioningStyle = Automatic;
+ };
};
};
buildConfigurationList = 8362D19C1A0D5BEB00A6D9A8 /* Build configuration list for PBXProject "CubeMapping" */;
@@ -217,6 +302,7 @@
projectRoot = "";
targets = (
8362D1A01A0D5BEB00A6D9A8 /* CubeMapping */,
+ 8451838420D932F000BF473E /* CubeMapping-Mac */,
);
};
/* End PBXProject section */
@@ -238,6 +324,21 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451838320D932F000BF473E /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8451839920D9337C00BF473E /* nx.png in Resources */,
+ 8451839A20D9337C00BF473E /* ny.png in Resources */,
+ 8451839B20D9337C00BF473E /* nz.png in Resources */,
+ 8451839C20D9337C00BF473E /* px.png in Resources */,
+ 8451839D20D9337C00BF473E /* py.png in Resources */,
+ 8451839E20D9337C00BF473E /* pz.png in Resources */,
+ 8451838E20D932F000BF473E /* Assets.xcassets in Resources */,
+ 8451839120D932F000BF473E /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -250,6 +351,7 @@
832493231A116424001E2340 /* MBEMesh.m in Sources */,
8362D1ED1A0D735800A6D9A8 /* MBERenderer.m in Sources */,
8362D1AD1A0D5BEB00A6D9A8 /* MBEViewController.m in Sources */,
+ 845183AB20D9354400BF473E /* MBEMetalViewIOS.m in Sources */,
832493261A1196B7001E2340 /* MBEMatrixUtilities.m in Sources */,
8362D1AA1A0D5BEB00A6D9A8 /* AppDelegate.m in Sources */,
8362D1A71A0D5BEB00A6D9A8 /* main.m in Sources */,
@@ -259,6 +361,25 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 8451838120D932F000BF473E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 845183A420D9339700BF473E /* MBESkyboxMesh.m in Sources */,
+ 8451838C20D932F000BF473E /* ViewController.m in Sources */,
+ 8451839420D932F000BF473E /* main.m in Sources */,
+ 845183A120D9339700BF473E /* MBEMatrixUtilities.m in Sources */,
+ 8451838920D932F000BF473E /* AppDelegate.m in Sources */,
+ 8451839F20D9339700BF473E /* MBERenderer.m in Sources */,
+ 845183A320D9339700BF473E /* MBEMesh.m in Sources */,
+ 845183AC20D9356200BF473E /* MBEMetalView.m in Sources */,
+ 845183A520D9339700BF473E /* MBETorusKnotMesh.m in Sources */,
+ 845183A820D934AD00BF473E /* MBEMetalViewMac.m in Sources */,
+ 845183A220D9339700BF473E /* MBETextureLoader.m in Sources */,
+ 845183A020D9339700BF473E /* Shaders.metal in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
@@ -278,6 +399,14 @@
name = LaunchScreen.xib;
sourceTree = "";
};
+ 8451838F20D932F000BF473E /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 8451839020D932F000BF473E /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@@ -293,12 +422,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -345,12 +476,14 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -402,6 +535,57 @@
};
name = Release;
};
+ 8451839620D932F000BF473E /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "CubeMapping-Mac/CubeMapping_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "CubeMapping-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.CubeMapping-Mac";
+ PRODUCT_NAME = "Cube Mapping";
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 8451839720D932F000BF473E /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_ENTITLEMENTS = "CubeMapping-Mac/CubeMapping_Mac.entitlements";
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ INFOPLIST_FILE = "CubeMapping-Mac/Info.plist";
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ PRODUCT_BUNDLE_IDENTIFIER = "com.Metal-by-Example.CubeMapping-Mac";
+ PRODUCT_NAME = "Cube Mapping";
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -423,6 +607,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 8451839820D932F000BF473E /* Build configuration list for PBXNativeTarget "CubeMapping-Mac" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 8451839620D932F000BF473E /* Debug */,
+ 8451839720D932F000BF473E /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
/* End XCConfigurationList section */
};
rootObject = 8362D1991A0D5BEB00A6D9A8 /* Project object */;
diff --git a/objc/08-CubeMapping/CubeMapping.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/objc/08-CubeMapping/CubeMapping.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/objc/08-CubeMapping/CubeMapping/Base.lproj/Main.storyboard b/objc/08-CubeMapping/CubeMapping/Base.lproj/Main.storyboard
index 4977ca9..41b683c 100644
--- a/objc/08-CubeMapping/CubeMapping/Base.lproj/Main.storyboard
+++ b/objc/08-CubeMapping/CubeMapping/Base.lproj/Main.storyboard
@@ -1,7 +1,12 @@
-
-
+
+
+
+
+
-
+
+
+
@@ -12,10 +17,10 @@
-
-
+
+
-
+
diff --git a/objc/08-CubeMapping/CubeMapping/MBEMesh.h b/objc/08-CubeMapping/CubeMapping/MBEMesh.h
index a51685d..7a9db36 100644
--- a/objc/08-CubeMapping/CubeMapping/MBEMesh.h
+++ b/objc/08-CubeMapping/CubeMapping/MBEMesh.h
@@ -1,4 +1,4 @@
-@import UIKit;
+@import Foundation;
@import Metal;
@interface MBEMesh : NSObject
diff --git a/objc/08-CubeMapping/CubeMapping/MBEMetalView.h b/objc/08-CubeMapping/CubeMapping/MBEMetalView.h
index a24c2cd..d865241 100644
--- a/objc/08-CubeMapping/CubeMapping/MBEMetalView.h
+++ b/objc/08-CubeMapping/CubeMapping/MBEMetalView.h
@@ -1,8 +1,26 @@
+//
+// MBEMetalView.h
+// Mipmapping
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
+#import
+
+#if TARGET_OS_IPHONE
@import UIKit;
+#define NSUIView UIView;
+#else
+@import AppKit;
+#define NSUIView NSView;
+#endif
+
@import QuartzCore.CAMetalLayer;
-@interface MBEMetalView : UIView
+@interface MBEMetalView : NSUIView
@property (nonatomic, readonly) CAMetalLayer *metalLayer;
+@property (nonatomic, readonly) CGSize drawableSize;
@end
diff --git a/objc/08-CubeMapping/CubeMapping/MBEMetalView.m b/objc/08-CubeMapping/CubeMapping/MBEMetalView.m
index 04dd768..189ebd3 100644
--- a/objc/08-CubeMapping/CubeMapping/MBEMetalView.m
+++ b/objc/08-CubeMapping/CubeMapping/MBEMetalView.m
@@ -1,37 +1,22 @@
+//
+// MBEMetalView.m
+// Mipmapping
+//
+// Created by Brent Gulanowski on 2018-06-19.
+// Copyright © 2018 Metal By Example. All rights reserved.
+//
+
#import "MBEMetalView.h"
@implementation MBEMetalView
-+ (Class)layerClass
-{
- return [CAMetalLayer class];
-}
-
-- (CAMetalLayer *)metalLayer
-{
- return (CAMetalLayer *)self.layer;
-}
+@dynamic metalLayer;
+@dynamic drawableSize;
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
-
- // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
- CGFloat scale = [UIScreen mainScreen].scale;
-
- // If we've moved to a window by the time our frame is being set, we can take its scale as our own
- if (self.window)
- {
- scale = self.window.screen.scale;
- }
-
- CGSize drawableSize = self.bounds.size;
-
- // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
- drawableSize.width *= scale;
- drawableSize.height *= scale;
-
- self.metalLayer.drawableSize = drawableSize;
+ self.metalLayer.drawableSize = self.drawableSize;
}
@end
diff --git a/objc/08-CubeMapping/CubeMapping/MBEMetalViewIOS.h b/objc/08-CubeMapping/CubeMapping/MBEMetalViewIOS.h
new file mode 100644
index 0000000..5c1ab91
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping/MBEMetalViewIOS.h
@@ -0,0 +1,8 @@
+@import UIKit;
+@import QuartzCore.CAMetalLayer;
+
+#import "MBEMetalView.h"
+
+@interface MBEMetalViewIOS : MBEMetalView
+
+@end
diff --git a/objc/08-CubeMapping/CubeMapping/MBEMetalViewIOS.m b/objc/08-CubeMapping/CubeMapping/MBEMetalViewIOS.m
new file mode 100644
index 0000000..055511a
--- /dev/null
+++ b/objc/08-CubeMapping/CubeMapping/MBEMetalViewIOS.m
@@ -0,0 +1,29 @@
+#import "MBEMetalViewIOS.h"
+
+@implementation MBEMetalViewIOS
+
++ (Class)layerClass
+{
+ return [CAMetalLayer class];
+}
+
+- (CAMetalLayer *)metalLayer
+{
+ return (CAMetalLayer *)self.layer;
+}
+
+- (CGSize)drawableSize {
+
+ // During the first layout pass, we will not be in a view hierarchy, so we guess our scale
+ // If we've moved to a window by the time our frame is being set, we can take its scale as our own
+ CGFloat scale = self.window ? self.window.screen.scale : [UIScreen mainScreen].scale;
+ CGSize drawableSize = self.bounds.size;
+
+ // Since drawable size is in pixels, we need to multiply by the scale to move from points to pixels
+ drawableSize.width *= scale;
+ drawableSize.height *= scale;
+
+ return drawableSize;
+}
+
+@end
diff --git a/objc/08-CubeMapping/CubeMapping/MBERenderer.h b/objc/08-CubeMapping/CubeMapping/MBERenderer.h
index 3b0b85a..d489571 100644
--- a/objc/08-CubeMapping/CubeMapping/MBERenderer.h
+++ b/objc/08-CubeMapping/CubeMapping/MBERenderer.h
@@ -1,4 +1,4 @@
-@import UIKit;
+@import Foundation;
@import QuartzCore.CAMetalLayer;
@import Metal;
@import simd;
diff --git a/objc/08-CubeMapping/CubeMapping/MBERenderer.m b/objc/08-CubeMapping/CubeMapping/MBERenderer.m
index 3a85144..1d94387 100644
--- a/objc/08-CubeMapping/CubeMapping/MBERenderer.m
+++ b/objc/08-CubeMapping/CubeMapping/MBERenderer.m
@@ -34,6 +34,7 @@ - (instancetype)initWithLayer:(CAMetalLayer *)layer
_layer = layer;
_layer.device = _device;
+ _sceneOrientation = matrix_identity_float4x4;
}
return self;
}
@@ -102,7 +103,7 @@ - (void)buildResources
tubeSlices:32
device:self.device];
- self.uniformBuffer = [self.device newBufferWithLength:sizeof(MBEUniforms) * 2
+ self.uniformBuffer = [self.device newBufferWithLength:self.uniformSize * 2
options:MTLResourceOptionCPUCacheModeDefault];
MTLSamplerDescriptor *samplerDescriptor = [MTLSamplerDescriptor new];
@@ -119,6 +120,7 @@ - (void)buildDepthBuffer
height:drawableSize.height
mipmapped:NO];
depthTexDesc.usage = MTLTextureUsageRenderTarget;
+ depthTexDesc.storageMode = MTLStorageModePrivate;
self.depthTexture = [self.device newTextureWithDescriptor:depthTexDesc];
}
@@ -154,8 +156,8 @@ - (void)drawTorusWithCommandEncoder:(id)commandEncoder
[commandEncoder setRenderPipelineState:self.useRefractionMaterial ? self.torusRefractPipeline : self.torusReflectPipeline];
[commandEncoder setDepthStencilState:depthState];
[commandEncoder setVertexBuffer:self.torus.vertexBuffer offset:0 atIndex:0];
- [commandEncoder setVertexBuffer:self.uniformBuffer offset:sizeof(MBEUniforms) atIndex:1];
- [commandEncoder setFragmentBuffer:self.uniformBuffer offset:sizeof(MBEUniforms) atIndex:0];
+ [commandEncoder setVertexBuffer:self.uniformBuffer offset:self.uniformSize atIndex:1];
+ [commandEncoder setFragmentBuffer:self.uniformBuffer offset:self.uniformSize atIndex:0];
[commandEncoder setFragmentTexture:self.cubeTexture atIndex:0];
[commandEncoder setFragmentSamplerState:self.samplerState atIndex:0];
@@ -205,7 +207,7 @@ - (void)updateUniforms
skyboxUniforms.normalMatrix = matrix_transpose(matrix_invert(skyboxUniforms.modelMatrix));
skyboxUniforms.modelViewProjectionMatrix = matrix_multiply(projectionMatrix, matrix_multiply(skyboxViewMatrix, modelMatrix));
skyboxUniforms.worldCameraPosition = worldCameraPosition;
- memcpy(self.uniformBuffer.contents, &skyboxUniforms, sizeof(MBEUniforms));
+ memcpy(self.uniformBuffer.contents, &skyboxUniforms, self.uniformSize);
MBEUniforms torusUniforms;
torusUniforms.modelMatrix = modelMatrix;
@@ -213,7 +215,7 @@ - (void)updateUniforms
torusUniforms.normalMatrix = matrix_transpose(matrix_invert(torusUniforms.modelMatrix));
torusUniforms.modelViewProjectionMatrix = matrix_multiply(projectionMatrix, matrix_multiply(torusViewMatrix, modelMatrix));
torusUniforms.worldCameraPosition = worldCameraPosition;
- memcpy(self.uniformBuffer.contents + sizeof(MBEUniforms), &torusUniforms, sizeof(MBEUniforms));
+ memcpy(self.uniformBuffer.contents + self.uniformSize, &torusUniforms, self.uniformSize);
}
- (void)draw
@@ -247,4 +249,13 @@ - (void)draw
}
}
+- (NSUInteger)uniformSize
+{
+ NSUInteger size = sizeof(MBEUniforms);
+#if TARGET_OS_MAC
+ size = (((NSUInteger)((CGFloat)(size - 1) / 256.0f) + 1) * 256);
+#endif
+ return size;
+}
+
@end
diff --git a/objc/08-CubeMapping/CubeMapping/MBETextureLoader.h b/objc/08-CubeMapping/CubeMapping/MBETextureLoader.h
index 6354b4d..c6bde2a 100644
--- a/objc/08-CubeMapping/CubeMapping/MBETextureLoader.h
+++ b/objc/08-CubeMapping/CubeMapping/MBETextureLoader.h
@@ -1,4 +1,4 @@
-@import UIKit;
+@import Foundation;
@import Metal;
@interface MBETextureLoader : NSObject
diff --git a/objc/08-CubeMapping/CubeMapping/MBETextureLoader.m b/objc/08-CubeMapping/CubeMapping/MBETextureLoader.m
index 6f886ff..72fffff 100644
--- a/objc/08-CubeMapping/CubeMapping/MBETextureLoader.m
+++ b/objc/08-CubeMapping/CubeMapping/MBETextureLoader.m
@@ -1,8 +1,22 @@
#import "MBETextureLoader.h"
+#if TARGET_OS_IPHONE
+@import UIKit;
+#define NSUIImage UIImage
+
+#else
+@import AppKit;
+#define NSUIImage NSImage
+
+@interface NSImage (Scale)
+@property (nonatomic, readonly) CGFloat scale;
+@property (nonatomic, readonly) CGImageRef CGImage;
+@end
+#endif
+
@implementation MBETextureLoader
-+ (uint8_t *)dataForImage:(UIImage *)image
++ (uint8_t *)dataForImage:(NSUIImage *)image
{
CGImageRef imageRef = [image CGImage];
@@ -27,7 +41,7 @@ + (uint8_t *)dataForImage:(UIImage *)image
+ (id)texture2DWithImageNamed:(NSString *)imageName device:(id)device
{
- UIImage *image = [UIImage imageNamed:imageName];
+ NSUIImage *image = [NSUIImage imageNamed:imageName];
CGSize imageSize = CGSizeMake(image.size.width * image.scale, image.size.height * image.scale);
const NSUInteger bytesPerPixel = 4;
const NSUInteger bytesPerRow = bytesPerPixel * imageSize.width;
@@ -51,7 +65,7 @@ + (uint8_t *)dataForImage:(UIImage *)image
{
NSAssert(imageNameArray.count == 6, @"Cube texture can only be created from exactly six images");
- UIImage *firstImage = [UIImage imageNamed:[imageNameArray firstObject]];
+ NSUIImage *firstImage = [NSUIImage imageNamed:[imageNameArray firstObject]];
const CGFloat cubeSize = firstImage.size.width * firstImage.scale;
const NSUInteger bytesPerPixel = 4;
@@ -69,7 +83,7 @@ + (uint8_t *)dataForImage:(UIImage *)image
for (size_t slice = 0; slice < 6; ++slice)
{
NSString *imageName = imageNameArray[slice];
- UIImage *image = [UIImage imageNamed:imageName];
+ NSUIImage *image = [NSUIImage imageNamed:imageName];
uint8_t *imageData = [self dataForImage:image];
NSAssert(image.size.width == cubeSize && image.size.height == cubeSize, @"Cube map images must be square and uniformly-sized");
@@ -87,3 +101,15 @@ + (uint8_t *)dataForImage:(UIImage *)image
}
@end
+
+#if TARGET_OS_OSX
+@implementation NSImage (Scale)
+
+- (CGFloat)scale { return 1.0; }
+
+- (CGImageRef)CGImage {
+ return [self CGImageForProposedRect:NULL context:NULL hints:nil];
+}
+
+@end
+#endif
diff --git a/objc/08-CubeMapping/CubeMapping/MBETorusKnotMesh.h b/objc/08-CubeMapping/CubeMapping/MBETorusKnotMesh.h
index 2a079e1..2c4cec7 100644
--- a/objc/08-CubeMapping/CubeMapping/MBETorusKnotMesh.h
+++ b/objc/08-CubeMapping/CubeMapping/MBETorusKnotMesh.h
@@ -1,5 +1,6 @@
#import "MBEMesh.h"
@import Metal;
+@import CoreGraphics;
@interface MBETorusKnotMesh : MBEMesh