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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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