diff --git a/README.md b/README.md index 4bf80c5..e021d1a 100644 --- a/README.md +++ b/README.md @@ -15,4 +15,8 @@ Repository to accompany the following blog posts: - [Using MetalKit part 11](http://mhorga.org/2016/05/10/using-metalkit-part-11.html) - [Using MetalKit part 12](http://mhorga.org/2016/05/18/using-metalkit-part-12.html) - [Using MetalKit part 13](http://mhorga.org/2016/05/25/using-metalkit-part-13.html) -- [Using MetalKit part 14](http://mhorga.org/2016/06/01/using-metalkit-part-14.html) \ No newline at end of file +- [Using MetalKit part 14](http://mhorga.org/2016/06/01/using-metalkit-part-14.html) +- [Using MetalKit part 15](http://mhorga.org/2016/06/23/using-metalkit-part-15.html) +- [Using MetalKit part 16](http://mhorga.org/2016/07/06/using-metalkit-part-16.html) +- [Using MetalKit part 17](http://mhorga.org/2016/09/24/using-metalkit-part-17.html) +- [Using MetalKit part 18](http://mhorga.org/2016/09/30/using-metalkit-part-2-3-2.html) diff --git a/ch01/chapter01.xcodeproj/project.pbxproj b/ch01/chapter01.xcodeproj/project.pbxproj index 2d5df56..2d19679 100644 --- a/ch01/chapter01.xcodeproj/project.pbxproj +++ b/ch01/chapter01.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 29400C7D1C3AEE1300345568 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29400C7C1C3AEE1300345568 /* AppDelegate.swift */; }; 29400C7F1C3AEE1300345568 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29400C7E1C3AEE1300345568 /* ViewController.swift */; }; - 29400C811C3AEE1300345568 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 29400C801C3AEE1300345568 /* Assets.xcassets */; }; 29400C841C3AEE1300345568 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 29400C821C3AEE1300345568 /* Main.storyboard */; }; /* End PBXBuildFile section */ @@ -17,7 +16,6 @@ 29400C791C3AEE1300345568 /* chapter01.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = chapter01.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29400C7C1C3AEE1300345568 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 29400C7E1C3AEE1300345568 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 29400C801C3AEE1300345568 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 29400C831C3AEE1300345568 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 29400C851C3AEE1300345568 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ @@ -53,12 +51,19 @@ isa = PBXGroup; children = ( 29400C7E1C3AEE1300345568 /* ViewController.swift */, - 29400C801C3AEE1300345568 /* Assets.xcassets */, + 297F43031DE8C78100638FC8 /* Supporting files */, + ); + path = chapter01; + sourceTree = ""; + }; + 297F43031DE8C78100638FC8 /* Supporting files */ = { + isa = PBXGroup; + children = ( 29400C821C3AEE1300345568 /* Main.storyboard */, 29400C851C3AEE1300345568 /* Info.plist */, 29400C7C1C3AEE1300345568 /* AppDelegate.swift */, ); - path = chapter01; + name = "Supporting files"; sourceTree = ""; }; /* End PBXGroup section */ @@ -88,11 +93,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = "Marius Horga"; TargetAttributes = { 29400C781C3AEE1300345568 = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; }; }; @@ -119,7 +125,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 29400C811C3AEE1300345568 /* Assets.xcassets in Resources */, 29400C841C3AEE1300345568 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -163,8 +168,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -186,7 +193,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -207,8 +214,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -224,7 +233,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; @@ -233,24 +242,25 @@ 29400C891C3AEE1300345568 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter01/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter01; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; 29400C8A1C3AEE1300345568 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter01/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter01; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -273,6 +283,7 @@ 29400C8A1C3AEE1300345568 /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/ch01/chapter01.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch01/chapter01.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index 18e3b2b..457e0b6 100644 Binary files a/ch01/chapter01.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch01/chapter01.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch01/chapter01.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter01.xcscheme b/ch01/chapter01.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter01.xcscheme index b3bc40d..eca02c6 100644 --- a/ch01/chapter01.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter01.xcscheme +++ b/ch01/chapter01.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter01.xcscheme @@ -1,6 +1,6 @@ - + + - + @@ -673,8 +673,11 @@ - - + + + + + @@ -682,6 +685,11 @@ + + + + + diff --git a/ch01/chapter01/ViewController.swift b/ch01/chapter01/ViewController.swift index 65fd44c..994db6f 100644 --- a/ch01/chapter01/ViewController.swift +++ b/ch01/chapter01/ViewController.swift @@ -6,7 +6,7 @@ // Copyright © 2016 Marius Horga. All rights reserved. // -import Cocoa // contains Metal +import Cocoa class ViewController: NSViewController { @@ -15,10 +15,15 @@ class ViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() - if let device = MTLCreateSystemDefaultDevice() { - label.stringValue = "Your GPU name is:\n\(device.name!)" - } else { - label.stringValue = "Your GPU does not support Metal!" + /* The MTLCopyAllDevices() function is only available in macOS. + For iOS/tvOS devices use MTLCreateSystemDefaultDevice() instead. */ + let devices = MTLCopyAllDevices() + guard let _ = devices.first else { + fatalError("Your GPU does not support Metal!") + } + label.stringValue = "Your system has the following GPU(s):\n" + for device in devices { + label.stringValue += "\(device.name!)\n" } } } diff --git a/ch02/chapter02.xcodeproj/project.pbxproj b/ch02/chapter02.xcodeproj/project.pbxproj index c91e5c5..98f74a4 100644 --- a/ch02/chapter02.xcodeproj/project.pbxproj +++ b/ch02/chapter02.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 29E74AD11C4159D60023A39A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29E74AD01C4159D60023A39A /* AppDelegate.swift */; }; - 29E74AD51C4159D60023A39A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 29E74AD41C4159D60023A39A /* Assets.xcassets */; }; 29E74AD81C4159D60023A39A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 29E74AD61C4159D60023A39A /* Main.storyboard */; }; 29E74AE01C415A020023A39A /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29E74ADF1C415A020023A39A /* MetalView.swift */; }; /* End PBXBuildFile section */ @@ -16,7 +15,6 @@ /* Begin PBXFileReference section */ 29E74ACD1C4159D60023A39A /* chapter02.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = chapter02.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29E74AD01C4159D60023A39A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 29E74AD41C4159D60023A39A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 29E74AD71C4159D60023A39A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 29E74AD91C4159D60023A39A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29E74ADF1C415A020023A39A /* MetalView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalView.swift; sourceTree = ""; }; @@ -33,6 +31,16 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 297F43041DE8C7B500638FC8 /* Supporting files */ = { + isa = PBXGroup; + children = ( + 29E74AD61C4159D60023A39A /* Main.storyboard */, + 29E74AD91C4159D60023A39A /* Info.plist */, + 29E74AD01C4159D60023A39A /* AppDelegate.swift */, + ); + name = "Supporting files"; + sourceTree = ""; + }; 29E74AC41C4159D60023A39A = { isa = PBXGroup; children = ( @@ -53,10 +61,7 @@ isa = PBXGroup; children = ( 29E74ADF1C415A020023A39A /* MetalView.swift */, - 29E74AD61C4159D60023A39A /* Main.storyboard */, - 29E74AD41C4159D60023A39A /* Assets.xcassets */, - 29E74AD91C4159D60023A39A /* Info.plist */, - 29E74AD01C4159D60023A39A /* AppDelegate.swift */, + 297F43041DE8C7B500638FC8 /* Supporting files */, ); path = chapter02; sourceTree = ""; @@ -88,11 +93,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = "Marius Horga"; TargetAttributes = { 29E74ACC1C4159D60023A39A = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; }; }; @@ -119,7 +125,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 29E74AD51C4159D60023A39A /* Assets.xcassets in Resources */, 29E74AD81C4159D60023A39A /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -163,8 +168,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -186,7 +193,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -207,8 +214,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -224,7 +233,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; @@ -233,24 +242,25 @@ 29E74ADD1C4159D60023A39A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter02/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter02; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; 29E74ADE1C4159D60023A39A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter02/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter02; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -273,6 +283,7 @@ 29E74ADE1C4159D60023A39A /* Release */, ); defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; diff --git a/ch02/chapter02.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch02/chapter02.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index e571953..b96e1aa 100644 Binary files a/ch02/chapter02.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch02/chapter02.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch02/chapter02.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter02.xcscheme b/ch02/chapter02.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter02.xcscheme index c6b8bd5..9033806 100644 --- a/ch02/chapter02.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter02.xcscheme +++ b/ch02/chapter02.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter02.xcscheme @@ -1,6 +1,6 @@ .size + vertexBuffer = device!.makeBuffer(bytes: vertexData!, length: dataSize, options: []) let library = device!.newDefaultLibrary()! - let vertex_func = library.newFunctionWithName("vertex_func") - let frag_func = library.newFunctionWithName("fragment_func") + let vertex_func = library.makeFunction(name: "vertex_func") + let frag_func = library.makeFunction(name: "fragment_func") let rpld = MTLRenderPipelineDescriptor() rpld.vertexFunction = vertex_func rpld.fragmentFunction = frag_func - rpld.colorAttachments[0].pixelFormat = .BGRA8Unorm - var rps: MTLRenderPipelineState! = nil + rpld.colorAttachments[0].pixelFormat = .bgra8Unorm do { - try rps = device!.newRenderPipelineStateWithDescriptor(rpld) + try rps = device!.makeRenderPipelineState(descriptor: rpld) } catch let error { self.print("\(error)") } - if let rpd = currentRenderPassDescriptor, drawable = currentDrawable { + } + + override func draw(_ dirtyRect: NSRect) { + if let drawable = currentDrawable, let rpd = currentRenderPassDescriptor { rpd.colorAttachments[0].clearColor = MTLClearColorMake(0, 0.5, 0.5, 1.0) - let command_buffer = device!.newCommandQueue().commandBuffer() - let command_encoder = command_buffer.renderCommandEncoderWithDescriptor(rpd) - command_encoder.setRenderPipelineState(rps) - command_encoder.setVertexBuffer(vertex_buffer, offset: 0, atIndex: 0) - command_encoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) - command_encoder.endEncoding() - command_buffer.presentDrawable(drawable) - command_buffer.commit() + let commandBuffer = commandQueue!.makeCommandBuffer() + let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: rpd) + commandEncoder.setRenderPipelineState(rps!) + commandEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0) + commandEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() } } } diff --git a/ch03/chapter03/Shaders.metal b/ch03/chapter03/Shaders.metal index dd09adb..20264cd 100644 --- a/ch03/chapter03/Shaders.metal +++ b/ch03/chapter03/Shaders.metal @@ -13,7 +13,8 @@ struct Vertex { float4 position [[position]]; }; -vertex Vertex vertex_func(constant Vertex *vertices [[buffer(0)]], uint vid [[vertex_id]]) { +vertex Vertex vertex_func(constant Vertex *vertices [[buffer(0)]], + uint vid [[vertex_id]]) { return vertices[vid]; } diff --git a/ch04/chapter04.xcodeproj/project.pbxproj b/ch04/chapter04.xcodeproj/project.pbxproj index 760ab6c..758c724 100644 --- a/ch04/chapter04.xcodeproj/project.pbxproj +++ b/ch04/chapter04.xcodeproj/project.pbxproj @@ -8,8 +8,6 @@ /* Begin PBXBuildFile section */ 29C87D411C56E93A005F4615 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C87D401C56E93A005F4615 /* AppDelegate.swift */; }; - 29C87D431C56E93A005F4615 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C87D421C56E93A005F4615 /* ViewController.swift */; }; - 29C87D451C56E93A005F4615 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 29C87D441C56E93A005F4615 /* Assets.xcassets */; }; 29C87D481C56E93B005F4615 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 29C87D461C56E93B005F4615 /* Main.storyboard */; }; 29C87D501C56E9C2005F4615 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 29C87D4F1C56E9C2005F4615 /* Shaders.metal */; }; 29C87D521C56E9DE005F4615 /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C87D511C56E9DE005F4615 /* MetalView.swift */; }; @@ -18,8 +16,6 @@ /* Begin PBXFileReference section */ 29C87D3D1C56E93A005F4615 /* chapter04.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = chapter04.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29C87D401C56E93A005F4615 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 29C87D421C56E93A005F4615 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; - 29C87D441C56E93A005F4615 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 29C87D471C56E93B005F4615 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 29C87D491C56E93B005F4615 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29C87D4F1C56E9C2005F4615 /* Shaders.metal */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = ""; }; @@ -37,6 +33,16 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 293936291D96FDD500008B3A /* Supporting files */ = { + isa = PBXGroup; + children = ( + 29C87D461C56E93B005F4615 /* Main.storyboard */, + 29C87D491C56E93B005F4615 /* Info.plist */, + 29C87D401C56E93A005F4615 /* AppDelegate.swift */, + ); + name = "Supporting files"; + sourceTree = ""; + }; 29C87D341C56E93A005F4615 = { isa = PBXGroup; children = ( @@ -58,11 +64,7 @@ children = ( 29C87D511C56E9DE005F4615 /* MetalView.swift */, 29C87D4F1C56E9C2005F4615 /* Shaders.metal */, - 29C87D441C56E93A005F4615 /* Assets.xcassets */, - 29C87D421C56E93A005F4615 /* ViewController.swift */, - 29C87D461C56E93B005F4615 /* Main.storyboard */, - 29C87D491C56E93B005F4615 /* Info.plist */, - 29C87D401C56E93A005F4615 /* AppDelegate.swift */, + 293936291D96FDD500008B3A /* Supporting files */, ); path = chapter04; sourceTree = ""; @@ -94,11 +96,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = "Marius Horga"; TargetAttributes = { 29C87D3C1C56E93A005F4615 = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; }; }; @@ -125,7 +128,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 29C87D451C56E93A005F4615 /* Assets.xcassets in Resources */, 29C87D481C56E93B005F4615 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -139,7 +141,6 @@ files = ( 29C87D521C56E9DE005F4615 /* MetalView.swift in Sources */, 29C87D501C56E9C2005F4615 /* Shaders.metal in Sources */, - 29C87D431C56E93A005F4615 /* ViewController.swift in Sources */, 29C87D411C56E93A005F4615 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -171,8 +172,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -194,7 +197,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -215,8 +218,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -232,7 +237,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; @@ -241,24 +246,25 @@ 29C87D4D1C56E93B005F4615 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter04/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter04; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; 29C87D4E1C56E93B005F4615 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter04/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter04; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/ch04/chapter04.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch04/chapter04.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index 0ea0b23..004c588 100644 Binary files a/ch04/chapter04.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch04/chapter04.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch04/chapter04.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter04.xcscheme b/ch04/chapter04.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter04.xcscheme index a541f24..dbdb0d2 100644 --- a/ch04/chapter04.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter04.xcscheme +++ b/ch04/chapter04.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter04.xcscheme @@ -1,6 +1,6 @@ diff --git a/ch04/chapter04/AppDelegate.swift b/ch04/chapter04/AppDelegate.swift index d94af3b..4d01e47 100644 --- a/ch04/chapter04/AppDelegate.swift +++ b/ch04/chapter04/AppDelegate.swift @@ -10,17 +10,4 @@ import Cocoa @NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate { - - - - func applicationDidFinishLaunching(aNotification: NSNotification) { - // Insert code here to initialize your application - } - - func applicationWillTerminate(aNotification: NSNotification) { - // Insert code here to tear down your application - } - - } - diff --git a/ch04/chapter04/Assets.xcassets/AppIcon.appiconset/Contents.json b/ch04/chapter04/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 2db2b1c..0000000 --- a/ch04/chapter04/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "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/ch04/chapter04/Base.lproj/Main.storyboard b/ch04/chapter04/Base.lproj/Main.storyboard index 4b8d6f1..8252dc9 100644 --- a/ch04/chapter04/Base.lproj/Main.storyboard +++ b/ch04/chapter04/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - - + + - + @@ -668,7 +668,7 @@ - + diff --git a/ch04/chapter04/MetalView.swift b/ch04/chapter04/MetalView.swift index 847b46e..13712ee 100644 --- a/ch04/chapter04/MetalView.swift +++ b/ch04/chapter04/MetalView.swift @@ -10,59 +10,52 @@ import MetalKit class MetalView: MTKView { - var vertex_buffer: MTLBuffer! - var rps: MTLRenderPipelineState! = nil - - override func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) - render() - } - - func render() { - device = MTLCreateSystemDefaultDevice() - createBuffer() - registerShaders() - sendToGPU() - } + var commandQueue: MTLCommandQueue? + var rps: MTLRenderPipelineState? + var vertexBuffer: MTLBuffer? struct Vertex { var position: vector_float4 var color: vector_float4 - }; + } + + required init(coder: NSCoder) { + super.init(coder: coder) + createBuffer() + registerShaders() + } func createBuffer() { - let vertex_data = [Vertex(position: [-1.0, -1.0, 0.0, 1.0], color: [1, 0, 0, 1]), - Vertex(position: [ 1.0, -1.0, 0.0, 1.0], color: [0, 1, 0, 1]), - Vertex(position: [ 0.0, 1.0, 0.0, 1.0], color: [0, 0, 1, 1])] - vertex_buffer = device!.newBufferWithBytes(vertex_data, length: sizeof(Vertex) * 3, options:[]) + device = MTLCreateSystemDefaultDevice()! + commandQueue = device!.makeCommandQueue() + let vertexData = [Vertex(position: [-0.5, -0.5, 0.0, 1.0], color: [1, 0, 0, 1]), + Vertex(position: [ 0.5, -0.5, 0.0, 1.0], color: [0, 1, 0, 1]), + Vertex(position: [ 0.0, 0.5, 0.0, 1.0], color: [0, 0, 1, 1])] + vertexBuffer = device!.makeBuffer(bytes: vertexData, length: MemoryLayout.size * 3, options:[]) } func registerShaders() { let library = device!.newDefaultLibrary()! - let vertex_func = library.newFunctionWithName("vertex_func") - let frag_func = library.newFunctionWithName("fragment_func") + let vertex_func = library.makeFunction(name: "vertex_func") + let frag_func = library.makeFunction(name: "fragment_func") let rpld = MTLRenderPipelineDescriptor() rpld.vertexFunction = vertex_func rpld.fragmentFunction = frag_func - rpld.colorAttachments[0].pixelFormat = .BGRA8Unorm - do { - try rps = device!.newRenderPipelineStateWithDescriptor(rpld) - } catch let error { - self.print("\(error)") - } + rpld.colorAttachments[0].pixelFormat = .bgra8Unorm + rps = try! device!.makeRenderPipelineState(descriptor: rpld) } - func sendToGPU() { - if let rpd = currentRenderPassDescriptor, drawable = currentDrawable { + override func draw(_ dirtyRect: NSRect) { + if let drawable = currentDrawable, let rpd = currentRenderPassDescriptor { rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0) - let command_buffer = device!.newCommandQueue().commandBuffer() - let command_encoder = command_buffer.renderCommandEncoderWithDescriptor(rpd) - command_encoder.setRenderPipelineState(rps) - command_encoder.setVertexBuffer(vertex_buffer, offset: 0, atIndex: 0) - command_encoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) - command_encoder.endEncoding() - command_buffer.presentDrawable(drawable) - command_buffer.commit() + let commandBuffer = commandQueue!.makeCommandBuffer() + let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: rpd) + commandEncoder.setRenderPipelineState(rps!) + commandEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0) + commandEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() } } } diff --git a/ch04/chapter04/Shaders.metal b/ch04/chapter04/Shaders.metal index 87188e5..958e762 100644 --- a/ch04/chapter04/Shaders.metal +++ b/ch04/chapter04/Shaders.metal @@ -14,7 +14,8 @@ struct Vertex { float4 color; }; -vertex Vertex vertex_func(constant Vertex *vertices [[buffer(0)]], uint vid [[vertex_id]]) { +vertex Vertex vertex_func(constant Vertex *vertices [[buffer(0)]], + uint vid [[vertex_id]]) { return vertices[vid]; } diff --git a/ch04/chapter04/ViewController.swift b/ch04/chapter04/ViewController.swift deleted file mode 100644 index d8740a2..0000000 --- a/ch04/chapter04/ViewController.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// ViewController.swift -// chapter04 -// -// Created by Marius on 1/26/16. -// Copyright © 2016 Marius Horga. All rights reserved. -// - -import Cocoa - -class ViewController: NSViewController { - - override func viewDidLoad() { - super.viewDidLoad() - - // Do any additional setup after loading the view. - } - - override var representedObject: AnyObject? { - didSet { - // Update the view, if already loaded. - } - } - - -} - diff --git a/ch05/chapter05.xcodeproj/project.pbxproj b/ch05/chapter05.xcodeproj/project.pbxproj index 4ffaaea..f1362b3 100644 --- a/ch05/chapter05.xcodeproj/project.pbxproj +++ b/ch05/chapter05.xcodeproj/project.pbxproj @@ -8,7 +8,6 @@ /* Begin PBXBuildFile section */ 298037231C62437900FBBC6A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 298037221C62437900FBBC6A /* AppDelegate.swift */; }; - 298037271C62437900FBBC6A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 298037261C62437900FBBC6A /* Assets.xcassets */; }; 2980372A1C62437900FBBC6A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 298037281C62437900FBBC6A /* Main.storyboard */; }; 298037321C6243CB00FBBC6A /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 298037311C6243CB00FBBC6A /* MetalView.swift */; }; 298037341C62440400FBBC6A /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 298037331C62440400FBBC6A /* Shaders.metal */; }; @@ -17,7 +16,6 @@ /* Begin PBXFileReference section */ 2980371F1C62437900FBBC6A /* chapter05.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = chapter05.app; sourceTree = BUILT_PRODUCTS_DIR; }; 298037221C62437900FBBC6A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 298037261C62437900FBBC6A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 298037291C62437900FBBC6A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 2980372B1C62437900FBBC6A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 298037311C6243CB00FBBC6A /* MetalView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalView.swift; sourceTree = ""; }; @@ -35,6 +33,16 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 297F43061DE9960800638FC8 /* Supporting files */ = { + isa = PBXGroup; + children = ( + 298037281C62437900FBBC6A /* Main.storyboard */, + 2980372B1C62437900FBBC6A /* Info.plist */, + 298037221C62437900FBBC6A /* AppDelegate.swift */, + ); + name = "Supporting files"; + sourceTree = ""; + }; 298037161C62437900FBBC6A = { isa = PBXGroup; children = ( @@ -56,10 +64,7 @@ children = ( 298037311C6243CB00FBBC6A /* MetalView.swift */, 298037331C62440400FBBC6A /* Shaders.metal */, - 298037261C62437900FBBC6A /* Assets.xcassets */, - 298037281C62437900FBBC6A /* Main.storyboard */, - 2980372B1C62437900FBBC6A /* Info.plist */, - 298037221C62437900FBBC6A /* AppDelegate.swift */, + 297F43061DE9960800638FC8 /* Supporting files */, ); path = chapter05; sourceTree = ""; @@ -91,11 +96,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = "Marius Horga"; TargetAttributes = { 2980371E1C62437900FBBC6A = { CreatedOnToolsVersion = 7.2.1; + LastSwiftMigration = 0800; }; }; }; @@ -122,7 +128,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 298037271C62437900FBBC6A /* Assets.xcassets in Resources */, 2980372A1C62437900FBBC6A /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -167,8 +172,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -190,7 +197,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -211,8 +218,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -228,7 +237,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; @@ -237,7 +246,6 @@ 2980372F1C62437900FBBC6A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter05/Info.plist; @@ -245,19 +253,21 @@ PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter05; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; 298037301C62437900FBBC6A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter05/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter05; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/ch05/chapter05.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch05/chapter05.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index d5df0be..e04aa46 100644 Binary files a/ch05/chapter05.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch05/chapter05.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch05/chapter05.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter05.xcscheme b/ch05/chapter05.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter05.xcscheme index 1ad0d75..45e4f67 100644 --- a/ch05/chapter05.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter05.xcscheme +++ b/ch05/chapter05.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter05.xcscheme @@ -1,6 +1,6 @@ Matrix { + func translationMatrix(_ matrix: Matrix, _ position: float3) -> Matrix { + var matrix = matrix matrix.m[12] = position.x matrix.m[13] = position.y matrix.m[14] = position.z return matrix } - - func scalingMatrix(var matrix: Matrix, _ scale: Float) -> Matrix { + func scalingMatrix(_ matrix: Matrix, _ scale: Float) -> Matrix { + var matrix = matrix matrix.m[0] = scale matrix.m[5] = scale matrix.m[10] = scale matrix.m[15] = 1.0 return matrix } - - func rotationMatrix(var matrix: Matrix, _ rot: float3) -> Matrix { + func rotationMatrix(_ matrix: Matrix, _ rot: float3) -> Matrix { + var matrix = matrix matrix.m[0] = cos(rot.y) * cos(rot.z) matrix.m[4] = cos(rot.z) * sin(rot.x) * sin(rot.y) - cos(rot.x) * sin(rot.z) matrix.m[8] = cos(rot.x) * cos(rot.z) * sin(rot.y) + sin(rot.x) * sin(rot.z) @@ -70,8 +64,8 @@ class MetalView: MTKView { matrix.m[15] = 1.0 return matrix } - - func modelMatrix(var matrix: Matrix) -> Matrix { + func modelMatrix(_ matrix: Matrix) -> Matrix { + var matrix = matrix matrix = rotationMatrix(matrix, float3(0.0, 0.0, 0.1)) matrix = scalingMatrix(matrix, 0.25) matrix = translationMatrix(matrix, float3(0.0, 0.5, 0.0)) @@ -80,44 +74,45 @@ class MetalView: MTKView { } func createBuffers() { - let vertex_data = [ - Vertex(position: [-1.0, -1.0, 0.0, 1.0], color: [1, 0, 0, 1]), - Vertex(position: [ 1.0, -1.0, 0.0, 1.0], color: [0, 1, 0, 1]), - Vertex(position: [ 0.0, 1.0, 0.0, 1.0], color: [0, 0, 1, 1]) + device = MTLCreateSystemDefaultDevice()! + commandQueue = device!.makeCommandQueue() + let vertex_data = [Vertex(position: [-1.0, -1.0, 0.0, 1.0], color: [1, 0, 0, 1]), + Vertex(position: [ 1.0, -1.0, 0.0, 1.0], color: [0, 1, 0, 1]), + Vertex(position: [ 0.0, 1.0, 0.0, 1.0], color: [0, 0, 1, 1]) ] - vertex_buffer = device!.newBufferWithBytes(vertex_data, length: sizeof(Vertex) * 3, options:[]) - uniform_buffer = device!.newBufferWithLength(sizeof(Float) * 16, options: []) - let bufferPointer = uniform_buffer.contents() - memcpy(bufferPointer, Matrix().modelMatrix(Matrix()).m, sizeof(Float) * 16) + vertexBuffer = device!.makeBuffer(bytes: vertex_data, length: MemoryLayout.size * 3, options:[]) + uniformBuffer = device!.makeBuffer(length: MemoryLayout.size * 16, options: []) + let bufferPointer = uniformBuffer.contents() + memcpy(bufferPointer, Matrix().modelMatrix(Matrix()).m, MemoryLayout.size * 16) } func registerShaders() { let library = device!.newDefaultLibrary()! - let vertex_func = library.newFunctionWithName("vertex_func") - let frag_func = library.newFunctionWithName("fragment_func") + let vertex_func = library.makeFunction(name: "vertex_func") + let frag_func = library.makeFunction(name: "fragment_func") let rpld = MTLRenderPipelineDescriptor() rpld.vertexFunction = vertex_func rpld.fragmentFunction = frag_func - rpld.colorAttachments[0].pixelFormat = .BGRA8Unorm + rpld.colorAttachments[0].pixelFormat = .bgra8Unorm do { - try rps = device!.newRenderPipelineStateWithDescriptor(rpld) + try rps = device!.makeRenderPipelineState(descriptor: rpld) } catch let error { self.print("\(error)") } } - func sendToGPU() { - if let rpd = currentRenderPassDescriptor, drawable = currentDrawable { + override func draw(_ dirtyRect: NSRect) { + if let rpd = currentRenderPassDescriptor, let drawable = currentDrawable { rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0) - let command_buffer = device!.newCommandQueue().commandBuffer() - let command_encoder = command_buffer.renderCommandEncoderWithDescriptor(rpd) - command_encoder.setRenderPipelineState(rps) - command_encoder.setVertexBuffer(vertex_buffer, offset: 0, atIndex: 0) - command_encoder.setVertexBuffer(uniform_buffer, offset: 0, atIndex: 1) - command_encoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) - command_encoder.endEncoding() - command_buffer.presentDrawable(drawable) - command_buffer.commit() + let commandBuffer = device!.makeCommandQueue().makeCommandBuffer() + let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: rpd) + commandEncoder.setRenderPipelineState(rps!) + commandEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0) + commandEncoder.setVertexBuffer(uniformBuffer, offset: 0, at: 1) + commandEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() } } } diff --git a/ch06/chapter06.xcodeproj/project.pbxproj b/ch06/chapter06.xcodeproj/project.pbxproj index d5b5d90..d317b25 100644 --- a/ch06/chapter06.xcodeproj/project.pbxproj +++ b/ch06/chapter06.xcodeproj/project.pbxproj @@ -7,23 +7,21 @@ objects = { /* Begin PBXBuildFile section */ - 292765421C6BDE3400094CA9 /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 292765411C6BDE3400094CA9 /* MetalView.swift */; }; - 29DB1AF61C6BDDD500BCC31B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29DB1AF51C6BDDD500BCC31B /* AppDelegate.swift */; }; - 29DB1AFA1C6BDDD500BCC31B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 29DB1AF91C6BDDD500BCC31B /* Assets.xcassets */; }; - 29DB1AFD1C6BDDD500BCC31B /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 29DB1AFB1C6BDDD500BCC31B /* Main.storyboard */; }; + 298451301D47EF08008D81B9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2984512F1D47EF08008D81B9 /* AppDelegate.swift */; }; + 298451351D47EF08008D81B9 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 298451331D47EF08008D81B9 /* Main.storyboard */; }; + 298451421D47F0BF008D81B9 /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 298451411D47F0BF008D81B9 /* MetalView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 292765411C6BDE3400094CA9 /* MetalView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalView.swift; sourceTree = ""; }; - 29DB1AF21C6BDDD500BCC31B /* chapter06.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = chapter06.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 29DB1AF51C6BDDD500BCC31B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 29DB1AF91C6BDDD500BCC31B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 29DB1AFC1C6BDDD500BCC31B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 29DB1AFE1C6BDDD500BCC31B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 2984512C1D47EF08008D81B9 /* chapter06.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = chapter06.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 2984512F1D47EF08008D81B9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 298451341D47EF08008D81B9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 2984513B1D47EF08008D81B9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 298451411D47F0BF008D81B9 /* MetalView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 29DB1AEF1C6BDDD500BCC31B /* Frameworks */ = { + 298451291D47EF08008D81B9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -33,30 +31,37 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 29DB1AE91C6BDDD400BCC31B = { + 297F43071DEA287400638FC8 /* Supporting files */ = { isa = PBXGroup; children = ( - 29DB1AF41C6BDDD500BCC31B /* chapter06 */, - 29DB1AF31C6BDDD500BCC31B /* Products */, + 298451331D47EF08008D81B9 /* Main.storyboard */, + 2984513B1D47EF08008D81B9 /* Info.plist */, + 2984512F1D47EF08008D81B9 /* AppDelegate.swift */, + ); + name = "Supporting files"; + sourceTree = ""; + }; + 298451231D47EF07008D81B9 = { + isa = PBXGroup; + children = ( + 2984512E1D47EF08008D81B9 /* chapter06 */, + 2984512D1D47EF08008D81B9 /* Products */, ); sourceTree = ""; }; - 29DB1AF31C6BDDD500BCC31B /* Products */ = { + 2984512D1D47EF08008D81B9 /* Products */ = { isa = PBXGroup; children = ( - 29DB1AF21C6BDDD500BCC31B /* chapter06.app */, + 2984512C1D47EF08008D81B9 /* chapter06.app */, ); name = Products; sourceTree = ""; }; - 29DB1AF41C6BDDD500BCC31B /* chapter06 */ = { + 2984512E1D47EF08008D81B9 /* chapter06 */ = { isa = PBXGroup; children = ( - 292765411C6BDE3400094CA9 /* MetalView.swift */, - 29DB1AF91C6BDDD500BCC31B /* Assets.xcassets */, - 29DB1AFB1C6BDDD500BCC31B /* Main.storyboard */, - 29DB1AFE1C6BDDD500BCC31B /* Info.plist */, - 29DB1AF51C6BDDD500BCC31B /* AppDelegate.swift */, + 298451411D47F0BF008D81B9 /* MetalView.swift */, + 297F43071DEA287400638FC8 /* Supporting files */, ); path = chapter06; sourceTree = ""; @@ -64,13 +69,13 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 29DB1AF11C6BDDD500BCC31B /* chapter06 */ = { + 2984512B1D47EF08008D81B9 /* chapter06 */ = { isa = PBXNativeTarget; - buildConfigurationList = 29DB1B011C6BDDD500BCC31B /* Build configuration list for PBXNativeTarget "chapter06" */; + buildConfigurationList = 2984513E1D47EF08008D81B9 /* Build configuration list for PBXNativeTarget "chapter06" */; buildPhases = ( - 29DB1AEE1C6BDDD500BCC31B /* Sources */, - 29DB1AEF1C6BDDD500BCC31B /* Frameworks */, - 29DB1AF01C6BDDD500BCC31B /* Resources */, + 298451281D47EF08008D81B9 /* Sources */, + 298451291D47EF08008D81B9 /* Frameworks */, + 2984512A1D47EF08008D81B9 /* Resources */, ); buildRules = ( ); @@ -78,25 +83,28 @@ ); name = chapter06; productName = chapter06; - productReference = 29DB1AF21C6BDDD500BCC31B /* chapter06.app */; + productReference = 2984512C1D47EF08008D81B9 /* chapter06.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - 29DB1AEA1C6BDDD400BCC31B /* Project object */ = { + 298451241D47EF07008D81B9 /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; - ORGANIZATIONNAME = "Marius Horga"; + LastSwiftUpdateCheck = 0800; + LastUpgradeCheck = 0810; + ORGANIZATIONNAME = Marius; TargetAttributes = { - 29DB1AF11C6BDDD500BCC31B = { - CreatedOnToolsVersion = 7.2.1; + 2984512B1D47EF08008D81B9 = { + CreatedOnToolsVersion = 8.0; + DevelopmentTeam = C2X9Q6VFVJ; + DevelopmentTeamName = "Marius Horga"; + ProvisioningStyle = Automatic; }; }; }; - buildConfigurationList = 29DB1AED1C6BDDD400BCC31B /* Build configuration list for PBXProject "chapter06" */; + buildConfigurationList = 298451271D47EF07008D81B9 /* Build configuration list for PBXProject "chapter06" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; @@ -104,45 +112,44 @@ en, Base, ); - mainGroup = 29DB1AE91C6BDDD400BCC31B; - productRefGroup = 29DB1AF31C6BDDD500BCC31B /* Products */; + mainGroup = 298451231D47EF07008D81B9; + productRefGroup = 2984512D1D47EF08008D81B9 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 29DB1AF11C6BDDD500BCC31B /* chapter06 */, + 2984512B1D47EF08008D81B9 /* chapter06 */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 29DB1AF01C6BDDD500BCC31B /* Resources */ = { + 2984512A1D47EF08008D81B9 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 29DB1AFA1C6BDDD500BCC31B /* Assets.xcassets in Resources */, - 29DB1AFD1C6BDDD500BCC31B /* Main.storyboard in Resources */, + 298451351D47EF08008D81B9 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 29DB1AEE1C6BDDD500BCC31B /* Sources */ = { + 298451281D47EF08008D81B9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 292765421C6BDE3400094CA9 /* MetalView.swift in Sources */, - 29DB1AF61C6BDDD500BCC31B /* AppDelegate.swift in Sources */, + 298451421D47F0BF008D81B9 /* MetalView.swift in Sources */, + 298451301D47EF08008D81B9 /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ - 29DB1AFB1C6BDDD500BCC31B /* Main.storyboard */ = { + 298451331D47EF08008D81B9 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( - 29DB1AFC1C6BDDD500BCC31B /* Base */, + 298451341D47EF08008D81B9 /* Base */, ); name = Main.storyboard; sourceTree = ""; @@ -150,10 +157,11 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 29DB1AFF1C6BDDD500BCC31B /* Debug */ = { + 2984513C1D47EF08008D81B9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -161,13 +169,16 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -186,18 +197,21 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - 29DB1B001C6BDDD500BCC31B /* Release */ = { + 2984513D1D47EF08008D81B9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -205,13 +219,16 @@ CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "-"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; @@ -224,58 +241,63 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = macosx; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; name = Release; }; - 29DB1B021C6BDDD500BCC31B /* Debug */ = { + 2984513F1D47EF08008D81B9 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - COMBINE_HIDPI_IMAGES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; INFOPLIST_FILE = chapter06/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter06; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = org.metalkit.chapter06; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 3.0; }; name = Debug; }; - 29DB1B031C6BDDD500BCC31B /* Release */ = { + 298451401D47EF08008D81B9 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - COMBINE_HIDPI_IMAGES = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; INFOPLIST_FILE = chapter06/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter06; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = org.metalkit.chapter06; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 29DB1AED1C6BDDD400BCC31B /* Build configuration list for PBXProject "chapter06" */ = { + 298451271D47EF07008D81B9 /* Build configuration list for PBXProject "chapter06" */ = { isa = XCConfigurationList; buildConfigurations = ( - 29DB1AFF1C6BDDD500BCC31B /* Debug */, - 29DB1B001C6BDDD500BCC31B /* Release */, + 2984513C1D47EF08008D81B9 /* Debug */, + 2984513D1D47EF08008D81B9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 29DB1B011C6BDDD500BCC31B /* Build configuration list for PBXNativeTarget "chapter06" */ = { + 2984513E1D47EF08008D81B9 /* Build configuration list for PBXNativeTarget "chapter06" */ = { isa = XCConfigurationList; buildConfigurations = ( - 29DB1B021C6BDDD500BCC31B /* Debug */, - 29DB1B031C6BDDD500BCC31B /* Release */, + 2984513F1D47EF08008D81B9 /* Debug */, + 298451401D47EF08008D81B9 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; - rootObject = 29DB1AEA1C6BDDD400BCC31B /* Project object */; + rootObject = 298451241D47EF07008D81B9 /* Project object */; } diff --git a/ch06/chapter06.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch06/chapter06.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index b174838..e303281 100644 Binary files a/ch06/chapter06.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch06/chapter06.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch06/chapter06.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter06.xcscheme b/ch06/chapter06.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter06.xcscheme index d92b1b7..ec3e3fb 100644 --- a/ch06/chapter06.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter06.xcscheme +++ b/ch06/chapter06.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter06.xcscheme @@ -1,6 +1,6 @@ @@ -32,7 +32,7 @@ @@ -55,7 +55,7 @@ runnableDebuggingMode = "0"> @@ -74,7 +74,7 @@ runnableDebuggingMode = "0"> diff --git a/ch06/chapter06.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/xcschememanagement.plist b/ch06/chapter06.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/xcschememanagement.plist index 8e90fc7..9b1a329 100644 --- a/ch06/chapter06.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/ch06/chapter06.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/xcschememanagement.plist @@ -12,7 +12,7 @@ SuppressBuildableAutocreation - 29DB1AF11C6BDDD500BCC31B + 2984512B1D47EF08008D81B9 primary diff --git a/ch06/chapter06/AppDelegate.swift b/ch06/chapter06/AppDelegate.swift index 247cfb6..b492ba3 100644 --- a/ch06/chapter06/AppDelegate.swift +++ b/ch06/chapter06/AppDelegate.swift @@ -2,13 +2,14 @@ // AppDelegate.swift // chapter06 // -// Created by Marius on 2/10/16. -// Copyright © 2016 Marius Horga. All rights reserved. +// Created by Marius on 7/26/16. +// Copyright © 2016 Marius. All rights reserved. // -import Cocoa +import UIKit -@NSApplicationMain -class AppDelegate: NSObject, NSApplicationDelegate { +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + var window: UIWindow? } diff --git a/ch06/chapter06/Assets.xcassets/AppIcon.appiconset/Contents.json b/ch06/chapter06/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 2db2b1c..0000000 --- a/ch06/chapter06/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "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/ch06/chapter06/Base.lproj/Main.storyboard b/ch06/chapter06/Base.lproj/Main.storyboard index 46163bb..5327e07 100644 --- a/ch06/chapter06/Base.lproj/Main.storyboard +++ b/ch06/chapter06/Base.lproj/Main.storyboard @@ -1,682 +1,27 @@ - - + + - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + + + + + + + + + - + - diff --git a/ch06/chapter06/Info.plist b/ch06/chapter06/Info.plist index 69d1345..e4ece02 100644 --- a/ch06/chapter06/Info.plist +++ b/ch06/chapter06/Info.plist @@ -6,8 +6,6 @@ en CFBundleExecutable $(EXECUTABLE_NAME) - CFBundleIconFile - CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion @@ -18,17 +16,28 @@ APPL CFBundleShortVersionString 1.0 - CFBundleSignature - ???? CFBundleVersion 1 - LSMinimumSystemVersion - $(MACOSX_DEPLOYMENT_TARGET) - NSHumanReadableCopyright - Copyright © 2016 Marius Horga. All rights reserved. - NSMainStoryboardFile + LSRequiresIPhoneOS + + UILaunchStoryboardName Main - NSPrincipalClass - NSApplication + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + diff --git a/ch06/chapter06/MetalView.swift b/ch06/chapter06/MetalView.swift old mode 100644 new mode 100755 index 33682be..7570bd4 --- a/ch06/chapter06/MetalView.swift +++ b/ch06/chapter06/MetalView.swift @@ -1,44 +1,37 @@ // // MetalView.swift // chapter06 -// +// // Created by Marius on 2/10/16. // Copyright © 2016 Marius Horga. All rights reserved. // -import Cocoa +import UIKit -class MetalView: NSView { +class MetalView: UIView { - override func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) - render() + var commandQueue: MTLCommandQueue! + var metalLayer: CAMetalLayer! + + override func didMoveToWindow() { + super.didMoveToWindow() + metalLayer = CAMetalLayer() + metalLayer.device = MTLCreateSystemDefaultDevice()! + metalLayer.frame = layer.frame + layer.addSublayer(metalLayer) + commandQueue = metalLayer.device?.makeCommandQueue() + redraw() } - override class func layerClass() -> AnyClass { - return CAMetalLayer.self - } - - var metalLayer: CAMetalLayer { - return layer as! CAMetalLayer - } - - func render() { - let device = MTLCreateSystemDefaultDevice()! - metalLayer.device = device - metalLayer.pixelFormat = .BGRA8Unorm - let drawable = metalLayer.nextDrawable() - let texture = drawable!.texture - let rpd = MTLRenderPassDescriptor() - rpd.colorAttachments[0].texture = texture - rpd.colorAttachments[0].loadAction = .Clear - rpd.colorAttachments[0].storeAction = .Store - rpd.colorAttachments[0].clearColor = MTLClearColor(red: 1, green: 0, blue: 0, alpha: 1) - let commandQueue = device.newCommandQueue() - let commandBuffer = commandQueue.commandBuffer() - let commandEncoder = commandBuffer.renderCommandEncoderWithDescriptor(rpd) + private func redraw() { + let drawable = metalLayer.nextDrawable()! + let descriptor = MTLRenderPassDescriptor() + descriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0.5, 0.5, 1) + descriptor.colorAttachments[0].texture = drawable.texture + let commandBuffer = commandQueue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor) commandEncoder.endEncoding() - commandBuffer.presentDrawable(drawable!) + commandBuffer.present(drawable) commandBuffer.commit() } } diff --git a/ch07/chapter07.xcodeproj/project.pbxproj b/ch07/chapter07.xcodeproj/project.pbxproj index bc672e5..0d1d83c 100644 --- a/ch07/chapter07.xcodeproj/project.pbxproj +++ b/ch07/chapter07.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 29B186261C84FF5800E9C0AA /* MathUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29B186251C84FF5800E9C0AA /* MathUtils.swift */; }; 29D8782A1C84D2B0007B5F17 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29D878291C84D2B0007B5F17 /* AppDelegate.swift */; }; - 29D8782E1C84D2B0007B5F17 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 29D8782D1C84D2B0007B5F17 /* Assets.xcassets */; }; 29D878311C84D2B0007B5F17 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 29D8782F1C84D2B0007B5F17 /* Main.storyboard */; }; 29D878391C84D309007B5F17 /* MetalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29D878381C84D309007B5F17 /* MetalView.swift */; }; 29D8783B1C84D335007B5F17 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 29D8783A1C84D335007B5F17 /* Shaders.metal */; }; @@ -19,7 +18,6 @@ 29B186251C84FF5800E9C0AA /* MathUtils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MathUtils.swift; sourceTree = ""; }; 29D878261C84D2B0007B5F17 /* chapter07.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = chapter07.app; sourceTree = BUILT_PRODUCTS_DIR; }; 29D878291C84D2B0007B5F17 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 29D8782D1C84D2B0007B5F17 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 29D878301C84D2B0007B5F17 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 29D878321C84D2B0007B5F17 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 29D878381C84D309007B5F17 /* MetalView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MetalView.swift; sourceTree = ""; }; @@ -37,6 +35,16 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 297F43081DEA2E3400638FC8 /* Supporting files */ = { + isa = PBXGroup; + children = ( + 29D8782F1C84D2B0007B5F17 /* Main.storyboard */, + 29D878321C84D2B0007B5F17 /* Info.plist */, + 29D878291C84D2B0007B5F17 /* AppDelegate.swift */, + ); + name = "Supporting files"; + sourceTree = ""; + }; 29D8781D1C84D2B0007B5F17 = { isa = PBXGroup; children = ( @@ -59,10 +67,7 @@ 29D878381C84D309007B5F17 /* MetalView.swift */, 29B186251C84FF5800E9C0AA /* MathUtils.swift */, 29D8783A1C84D335007B5F17 /* Shaders.metal */, - 29D8782D1C84D2B0007B5F17 /* Assets.xcassets */, - 29D8782F1C84D2B0007B5F17 /* Main.storyboard */, - 29D878321C84D2B0007B5F17 /* Info.plist */, - 29D878291C84D2B0007B5F17 /* AppDelegate.swift */, + 297F43081DEA2E3400638FC8 /* Supporting files */, ); path = chapter07; sourceTree = ""; @@ -94,11 +99,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = "Marius Horga"; TargetAttributes = { 29D878251C84D2B0007B5F17 = { CreatedOnToolsVersion = 7.2.1; + LastSwiftMigration = 0800; }; }; }; @@ -125,7 +131,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 29D8782E1C84D2B0007B5F17 /* Assets.xcassets in Resources */, 29D878311C84D2B0007B5F17 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -171,8 +176,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -194,7 +201,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -215,8 +222,10 @@ 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_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -232,7 +241,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; }; @@ -241,24 +250,25 @@ 29D878361C84D2B0007B5F17 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter07/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter07; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; 29D878371C84D2B0007B5F17 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = chapter07/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = org.mhorga.chapter07; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/ch07/chapter07.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch07/chapter07.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index 4118b49..c961a24 100644 Binary files a/ch07/chapter07.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch07/chapter07.xcodeproj/project.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch07/chapter07.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter07.xcscheme b/ch07/chapter07.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter07.xcscheme index 7ba25a7..1f22050 100644 --- a/ch07/chapter07.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter07.xcscheme +++ b/ch07/chapter07.xcodeproj/xcuserdata/marius.xcuserdatad/xcschemes/chapter07.xcscheme @@ -1,6 +1,6 @@ Matrix { + func translationMatrix(_ matrix: Matrix, _ position: float3) -> Matrix { + var matrix = matrix matrix.m[12] = position.x matrix.m[13] = position.y matrix.m[14] = position.z return matrix } - func scalingMatrix(var matrix: Matrix, _ scale: Float) -> Matrix { + func scalingMatrix(_ matrix: Matrix, _ scale: Float) -> Matrix { + var matrix = matrix matrix.m[0] = scale matrix.m[5] = scale matrix.m[10] = scale @@ -39,7 +41,8 @@ struct Matrix { return matrix } - func rotationMatrix(var matrix: Matrix, _ rot: float3) -> Matrix { + func rotationMatrix(_ matrix: Matrix, _ rot: float3) -> Matrix { + var matrix = matrix matrix.m[0] = cos(rot.y) * cos(rot.z) matrix.m[4] = cos(rot.z) * sin(rot.x) * sin(rot.y) - cos(rot.x) * sin(rot.z) matrix.m[8] = cos(rot.x) * cos(rot.z) * sin(rot.y) + sin(rot.x) * sin(rot.z) @@ -53,7 +56,8 @@ struct Matrix { return matrix } - func modelMatrix(var matrix: Matrix) -> Matrix { + func modelMatrix(_ matrix: Matrix) -> Matrix { + var matrix = matrix matrix = rotationMatrix(matrix, float3(0.0, 0.0, 0.1)) matrix = scalingMatrix(matrix, 0.25) matrix = translationMatrix(matrix, float3(0.0, 0.5, 0.0)) diff --git a/ch07/chapter07/MetalView.swift b/ch07/chapter07/MetalView.swift index a042c98..b20b49c 100644 --- a/ch07/chapter07/MetalView.swift +++ b/ch07/chapter07/MetalView.swift @@ -1,7 +1,7 @@ // // MetalView.swift // chapter07 -// +// // Created by Marius on 2/29/16. // Copyright © 2016 Marius Horga. All rights reserved. // @@ -10,57 +10,58 @@ import MetalKit class MetalView: MTKView { - var vertex_buffer: MTLBuffer! - var uniform_buffer: MTLBuffer! - var rps: MTLRenderPipelineState! = nil + var commandQueue: MTLCommandQueue? + var rps: MTLRenderPipelineState? + var vertexBuffer: MTLBuffer! + var uniformBuffer: MTLBuffer! required init(coder: NSCoder) { super.init(coder: coder) - device = MTLCreateSystemDefaultDevice() createBuffers() registerShaders() } - override func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) - if let rpd = currentRenderPassDescriptor, drawable = currentDrawable { - rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0) - let command_buffer = device!.newCommandQueue().commandBuffer() - let command_encoder = command_buffer.renderCommandEncoderWithDescriptor(rpd) - command_encoder.setRenderPipelineState(rps) - command_encoder.setVertexBuffer(vertex_buffer, offset: 0, atIndex: 0) - command_encoder.setVertexBuffer(uniform_buffer, offset: 0, atIndex: 1) - command_encoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) - command_encoder.endEncoding() - command_buffer.presentDrawable(drawable) - command_buffer.commit() - } - } - func createBuffers() { - let vertex_data = [ - Vertex(position: [-1.0, -1.0, 0.0, 1.0], color: [1, 0, 0, 1]), - Vertex(position: [ 1.0, -1.0, 0.0, 1.0], color: [0, 1, 0, 1]), - Vertex(position: [ 0.0, 1.0, 0.0, 1.0], color: [0, 0, 1, 1]) + device = MTLCreateSystemDefaultDevice()! + commandQueue = device!.makeCommandQueue() + let vertex_data = [Vertex(position: [-1.0, -1.0, 0.0, 1.0], color: [1, 0, 0, 1]), + Vertex(position: [ 1.0, -1.0, 0.0, 1.0], color: [0, 1, 0, 1]), + Vertex(position: [ 0.0, 1.0, 0.0, 1.0], color: [0, 0, 1, 1]) ] - vertex_buffer = device!.newBufferWithBytes(vertex_data, length: sizeof(Vertex) * 3, options:[]) - uniform_buffer = device!.newBufferWithLength(sizeof(Float) * 16, options: []) - let bufferPointer = uniform_buffer.contents() - memcpy(bufferPointer, Matrix().modelMatrix(Matrix()).m, sizeof(Float) * 16) + vertexBuffer = device!.makeBuffer(bytes: vertex_data, length: MemoryLayout.size * 3, options:[]) + uniformBuffer = device!.makeBuffer(length: MemoryLayout.size * 16, options: []) + let bufferPointer = uniformBuffer.contents() + memcpy(bufferPointer, Matrix().modelMatrix(Matrix()).m, MemoryLayout.size * 16) } func registerShaders() { let library = device!.newDefaultLibrary()! - let vertex_func = library.newFunctionWithName("vertex_func") - let frag_func = library.newFunctionWithName("fragment_func") + let vertex_func = library.makeFunction(name: "vertex_func") + let frag_func = library.makeFunction(name: "fragment_func") let rpld = MTLRenderPipelineDescriptor() rpld.vertexFunction = vertex_func rpld.fragmentFunction = frag_func - rpld.colorAttachments[0].pixelFormat = .BGRA8Unorm + rpld.colorAttachments[0].pixelFormat = .bgra8Unorm do { - try rps = device!.newRenderPipelineStateWithDescriptor(rpld) + try rps = device!.makeRenderPipelineState(descriptor: rpld) } catch let error { self.print("\(error)") } } + + override func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) + if let rpd = currentRenderPassDescriptor, let drawable = currentDrawable { + rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0) + let commandBuffer = device!.makeCommandQueue().makeCommandBuffer() + let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: rpd) + commandEncoder.setRenderPipelineState(rps!) + commandEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0) + commandEncoder.setVertexBuffer(uniformBuffer, offset: 0, at: 1) + commandEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() + } + } } diff --git a/ch08/chapter08.playground/Contents.swift b/ch08/chapter08.playground/Contents.swift index 96ca6ff..694d377 100644 --- a/ch08/chapter08.playground/Contents.swift +++ b/ch08/chapter08.playground/Contents.swift @@ -1,8 +1,9 @@ -import Cocoa -import XCPlayground +import MetalKit +import PlaygroundSupport -let device = MTLCreateSystemDefaultDevice()! -let frame = NSRect(x: 0, y: 0, width: 300, height: 300) -let view = MetalView(frame: frame, device: device) -XCPlaygroundPage.currentPage.liveView = view +let frame = NSRect(x: 0, y: 0, width: 400, height: 400) +let delegate = MetalView() +let view = MTKView(frame: frame, device: delegate.device) +view.delegate = delegate +PlaygroundPage.current.liveView = view diff --git a/ch08/chapter08.playground/Resources/Shaders.metal b/ch08/chapter08.playground/Resources/Shaders.metal index a9bad7e..2234835 100644 --- a/ch08/chapter08.playground/Resources/Shaders.metal +++ b/ch08/chapter08.playground/Resources/Shaders.metal @@ -11,7 +11,9 @@ struct Uniforms { float4x4 modelMatrix; }; -vertex Vertex vertex_func(constant Vertex *vertices [[buffer(0)]], constant Uniforms &uniforms [[buffer(1)]], uint vid [[vertex_id]]) { +vertex Vertex vertex_func(constant Vertex *vertices [[buffer(0)]], + constant Uniforms &uniforms [[buffer(1)]], + uint vid [[vertex_id]]) { float4x4 matrix = uniforms.modelMatrix; Vertex in = vertices[vid]; Vertex out; diff --git a/ch08/chapter08.playground/Sources/MathUtils.swift b/ch08/chapter08.playground/Sources/MathUtils.swift index cc13d82..3461891 100644 --- a/ch08/chapter08.playground/Sources/MathUtils.swift +++ b/ch08/chapter08.playground/Sources/MathUtils.swift @@ -21,14 +21,16 @@ struct Matrix { ] } - func translationMatrix(var matrix: Matrix, _ position: float3) -> Matrix { + func translationMatrix(_ matrix: Matrix, _ position: float3) -> Matrix { + var matrix = matrix matrix.m[12] = position.x matrix.m[13] = position.y matrix.m[14] = position.z return matrix } - func scalingMatrix(var matrix: Matrix, _ scale: Float) -> Matrix { + func scalingMatrix(_ matrix: Matrix, _ scale: Float) -> Matrix { + var matrix = matrix matrix.m[0] = scale matrix.m[5] = scale matrix.m[10] = scale @@ -36,7 +38,8 @@ struct Matrix { return matrix } - func rotationMatrix(var matrix: Matrix, _ rot: float3) -> Matrix { + func rotationMatrix(_ matrix: Matrix, _ rot: float3) -> Matrix { + var matrix = matrix matrix.m[0] = cos(rot.y) * cos(rot.z) matrix.m[4] = cos(rot.z) * sin(rot.x) * sin(rot.y) - cos(rot.x) * sin(rot.z) matrix.m[8] = cos(rot.x) * cos(rot.z) * sin(rot.y) + sin(rot.x) * sin(rot.z) @@ -50,7 +53,8 @@ struct Matrix { return matrix } - func modelMatrix(var matrix: Matrix) -> Matrix { + func modelMatrix(matrix: Matrix) -> Matrix { + var matrix = matrix matrix = rotationMatrix(matrix, float3(0.0, 0.0, 0.1)) matrix = scalingMatrix(matrix, 0.25) matrix = translationMatrix(matrix, float3(0.0, 0.5, 0.0)) diff --git a/ch08/chapter08.playground/Sources/MetalView.swift b/ch08/chapter08.playground/Sources/MetalView.swift index 9305067..a425315 100644 --- a/ch08/chapter08.playground/Sources/MetalView.swift +++ b/ch08/chapter08.playground/Sources/MetalView.swift @@ -1,69 +1,68 @@ import MetalKit -public class MetalView: MTKView { +public class MetalView: NSObject, MTKViewDelegate { - var vertex_buffer: MTLBuffer! - var uniform_buffer: MTLBuffer! - var rps: MTLRenderPipelineState! = nil + public var device: MTLDevice! + var queue: MTLCommandQueue! + var vertexBuffer: MTLBuffer! + var uniformBuffer: MTLBuffer! + var rps: MTLRenderPipelineState! - required public init(coder: NSCoder) { - super.init(coder: coder) - } - - override public init(frame frameRect: CGRect, device: MTLDevice?) { - super.init(frame: frameRect, device: device) + override public init() { + super.init() createBuffers() registerShaders() } - override public func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) - if let rpd = currentRenderPassDescriptor, drawable = currentDrawable { - rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0) - let command_buffer = device!.newCommandQueue().commandBuffer() - let command_encoder = command_buffer.renderCommandEncoderWithDescriptor(rpd) - command_encoder.setRenderPipelineState(rps) - command_encoder.setVertexBuffer(vertex_buffer, offset: 0, atIndex: 0) - command_encoder.setVertexBuffer(uniform_buffer, offset: 0, atIndex: 1) - command_encoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) - command_encoder.endEncoding() - command_buffer.presentDrawable(drawable) - command_buffer.commit() - } - } - func createBuffers() { - let vertex_data = [ - Vertex(pos: [-1.0, -1.0, 0.0, 1.0], col: [1, 0, 0, 1]), - Vertex(pos: [ 1.0, -1.0, 0.0, 1.0], col: [0, 1, 0, 1]), - Vertex(pos: [ 0.0, 1.0, 0.0, 1.0], col: [0, 0, 1, 1]) + device = MTLCreateSystemDefaultDevice() + queue = device.makeCommandQueue() + let vertexData = [Vertex(pos: [-1.0, -1.0, 0.0, 1.0], col: [1, 0, 0, 1]), + Vertex(pos: [ 1.0, -1.0, 0.0, 1.0], col: [0, 1, 0, 1]), + Vertex(pos: [ 0.0, 1.0, 0.0, 1.0], col: [0, 0, 1, 1]) ] - vertex_buffer = device!.newBufferWithBytes(vertex_data, length: sizeof(Vertex) * 3, options:[]) - uniform_buffer = device!.newBufferWithLength(sizeof(Float) * 16, options: []) - let bufferPointer = uniform_buffer.contents() - memcpy(bufferPointer, Matrix().modelMatrix(Matrix()).m, sizeof(Float) * 16) + vertexBuffer = device!.makeBuffer(bytes: vertexData, length: MemoryLayout.size * 3, options:[]) + uniformBuffer = device!.makeBuffer(length: MemoryLayout.size * 16, options: []) + let bufferPointer = uniformBuffer.contents() + memcpy(bufferPointer, Matrix().modelMatrix(matrix: Matrix()).m, MemoryLayout.size * 16) } func registerShaders() { - let path = NSBundle.mainBundle().pathForResource("Shaders", ofType: "metal") + let path = Bundle.main.path(forResource: "Shaders", ofType: "metal") let input: String? let library: MTLLibrary let vert_func: MTLFunction let frag_func: MTLFunction do { - input = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding) - library = try device!.newLibraryWithSource(input!, options: nil) - //print(library.functionNames) - vert_func = library.newFunctionWithName("vertex_func")! - frag_func = library.newFunctionWithName("fragment_func")! + input = try String(contentsOfFile: path!, encoding: String.Encoding.utf8) + library = try device!.makeLibrary(source: input!, options: nil) + vert_func = library.makeFunction(name: "vertex_func")! + frag_func = library.makeFunction(name: "fragment_func")! let rpld = MTLRenderPipelineDescriptor() rpld.vertexFunction = vert_func rpld.fragmentFunction = frag_func - rpld.colorAttachments[0].pixelFormat = .BGRA8Unorm - rps = try device!.newRenderPipelineStateWithDescriptor(rpld) + rpld.colorAttachments[0].pixelFormat = .bgra8Unorm + rps = try device!.makeRenderPipelineState(descriptor: rpld) } catch let e { Swift.print("\(e)") } } + + public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} + + public func draw(in view: MTKView) { + if let rpd = view.currentRenderPassDescriptor, let drawable = view.currentDrawable { + rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0) + let commandBuffer = queue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: rpd) + commandEncoder.setRenderPipelineState(rps) + commandEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0) + commandEncoder.setVertexBuffer(uniformBuffer, offset: 0, at: 1) + commandEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() + } + } } diff --git a/ch08/chapter08.playground/contents.xcplayground b/ch08/chapter08.playground/contents.xcplayground index 06828af..9f9eecc 100644 --- a/ch08/chapter08.playground/contents.xcplayground +++ b/ch08/chapter08.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/ch08/chapter08.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch08/chapter08.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index 4b12b70..2b92eb4 100644 Binary files a/ch08/chapter08.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch08/chapter08.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch09/chapter09.playground/Contents.swift b/ch09/chapter09.playground/Contents.swift index 96ca6ff..694d377 100644 --- a/ch09/chapter09.playground/Contents.swift +++ b/ch09/chapter09.playground/Contents.swift @@ -1,8 +1,9 @@ -import Cocoa -import XCPlayground +import MetalKit +import PlaygroundSupport -let device = MTLCreateSystemDefaultDevice()! -let frame = NSRect(x: 0, y: 0, width: 300, height: 300) -let view = MetalView(frame: frame, device: device) -XCPlaygroundPage.currentPage.liveView = view +let frame = NSRect(x: 0, y: 0, width: 400, height: 400) +let delegate = MetalView() +let view = MTKView(frame: frame, device: delegate.device) +view.delegate = delegate +PlaygroundPage.current.liveView = view diff --git a/ch09/chapter09.playground/Resources/Shaders.metal b/ch09/chapter09.playground/Resources/Shaders.metal index e52b42e..f2464b2 100755 --- a/ch09/chapter09.playground/Resources/Shaders.metal +++ b/ch09/chapter09.playground/Resources/Shaders.metal @@ -20,6 +20,6 @@ vertex Vertex vertex_func(constant Vertex *vertices [[buffer(0)]], constant Unif return out; } -fragment float4 fragment_func(Vertex vert [[stage_in]]) { - return vert.color; +fragment half4 fragment_func(Vertex vert [[stage_in]]) { + return half4(vert.color); } diff --git a/ch09/chapter09.playground/Sources/MathUtils.swift b/ch09/chapter09.playground/Sources/MathUtils.swift index 81ef738..cd61a82 100755 --- a/ch09/chapter09.playground/Sources/MathUtils.swift +++ b/ch09/chapter09.playground/Sources/MathUtils.swift @@ -30,7 +30,7 @@ func scalingMatrix(scale: Float) -> matrix_float4x4 { return matrix_float4x4(columns:(X, Y, Z, W)) } -func rotationMatrix(angle: Float, _ axis: vector_float3) -> matrix_float4x4 { +func rotationMatrix(angle: Float, axis: vector_float3) -> matrix_float4x4 { var X = vector_float4(0, 0, 0, 0) X.x = axis.x * axis.x + (1 - axis.x * axis.x) * cos(angle) X.y = axis.x * axis.y * (1 - cos(angle)) - axis.z * sin(angle) diff --git a/ch09/chapter09.playground/Sources/MetalView.swift b/ch09/chapter09.playground/Sources/MetalView.swift index 27e9042..795b1ae 100755 --- a/ch09/chapter09.playground/Sources/MetalView.swift +++ b/ch09/chapter09.playground/Sources/MetalView.swift @@ -1,28 +1,26 @@ import MetalKit -public class MetalView: MTKView { +public class MetalView: NSObject, MTKViewDelegate { - var vertex_buffer: MTLBuffer! - var uniform_buffer: MTLBuffer! - var index_buffer: MTLBuffer! - var dss: MTLDepthStencilState! + public var device: MTLDevice! + var queue: MTLCommandQueue! + var vertexBuffer: MTLBuffer! + var uniformBuffer: MTLBuffer! + var indexBuffer: MTLBuffer! var rps: MTLRenderPipelineState! - var commandQueue: MTLCommandQueue! var rotation: Float = 0 - required public init(coder: NSCoder) { - super.init(coder: coder) - } - - override public init(frame frameRect: CGRect, device: MTLDevice?) { - super.init(frame: frameRect, device: device) + override public init() { + super.init() + device = MTLCreateSystemDefaultDevice() + queue = device.makeCommandQueue() createBuffers() createPipeline() } func createBuffers() { - let vertex_data = [ + let vertexData = [ Vertex(pos: [-1.0, -1.0, 1.0, 1.0], col: [1, 1, 1, 1]), Vertex(pos: [ 1.0, -1.0, 1.0, 1.0], col: [1, 0, 0, 1]), Vertex(pos: [ 1.0, 1.0, 1.0, 1.0], col: [1, 1, 0, 1]), @@ -30,71 +28,73 @@ public class MetalView: MTKView { Vertex(pos: [-1.0, -1.0, -1.0, 1.0], col: [0, 0, 1, 1]), Vertex(pos: [ 1.0, -1.0, -1.0, 1.0], col: [1, 0, 1, 1]), Vertex(pos: [ 1.0, 1.0, -1.0, 1.0], col: [0, 0, 0, 1]), - Vertex(pos: [-1.0, 1.0, -1.0, 1.0], col: [0, 1, 1, 1]) - ] - let index_data: [UInt16] = [ - 0, 1, 2, 2, 3, 0, // front - 1, 5, 6, 6, 2, 1, // right - 3, 2, 6, 6, 7, 3, // top - 4, 5, 1, 1, 0, 4, // bottom - 4, 0, 3, 3, 7, 4, // left - 7, 6, 5, 5, 4, 7, // back - ] - vertex_buffer = device!.newBufferWithBytes(vertex_data, length: sizeof(Vertex) * vertex_data.count, options: []) - index_buffer = device!.newBufferWithBytes(index_data, length: sizeof(UInt16) * index_data.count , options: []) - uniform_buffer = device!.newBufferWithLength(sizeof(matrix_float4x4), options: []) + Vertex(pos: [-1.0, 1.0, -1.0, 1.0], col: [0, 1, 1, 1])] + + let indexData: [UInt16] = [0, 1, 2, 2, 3, 0, // front + 1, 5, 6, 6, 2, 1, // right + 3, 2, 6, 6, 7, 3, // top + 4, 5, 1, 1, 0, 4, // bottom + 4, 0, 3, 3, 7, 4, // left + 7, 6, 5, 5, 4, 7] // back + + vertexBuffer = device!.makeBuffer(bytes: vertexData, length: MemoryLayout.size * vertexData.count, options: []) + indexBuffer = device!.makeBuffer(bytes: indexData, length: MemoryLayout.size * indexData.count , options: []) + uniformBuffer = device!.makeBuffer(length: MemoryLayout.size, options: []) } func createPipeline() { + let path = Bundle.main.path(forResource: "Shaders", ofType: "metal") + let input: String? + let library: MTLLibrary + let vert_func: MTLFunction + let frag_func: MTLFunction do { - let path = NSBundle.mainBundle().pathForResource("Shaders", ofType: "metal") - let input = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding) - let library = try device!.newLibraryWithSource(input, options: nil) - let vert_func = library.newFunctionWithName("vertex_func")! - let frag_func = library.newFunctionWithName("fragment_func")! + input = try String(contentsOfFile: path!, encoding: String.Encoding.utf8) + library = try device!.makeLibrary(source: input!, options: nil) + vert_func = library.makeFunction(name: "vertex_func")! + frag_func = library.makeFunction(name: "fragment_func")! let rpld = MTLRenderPipelineDescriptor() rpld.vertexFunction = vert_func rpld.fragmentFunction = frag_func - rpld.colorAttachments[0].pixelFormat = .BGRA8Unorm - rps = try device!.newRenderPipelineStateWithDescriptor(rpld) + rpld.colorAttachments[0].pixelFormat = .bgra8Unorm + rps = try device!.makeRenderPipelineState(descriptor: rpld) } catch let e { Swift.print("\(e)") } - commandQueue = device?.newCommandQueue() } func update() { - let scaled = scalingMatrix(0.5) + let scaled = scalingMatrix(scale: 0.5) rotation += 1 / 100 * Float(M_PI) / 4 - let rotatedY = rotationMatrix(rotation, float3(0, 1, 0)) - let rotatedX = rotationMatrix(Float(M_PI) / 4, float3(1, 0, 0)) + let rotatedY = rotationMatrix(angle: rotation, axis: float3(0, 1, 0)) + let rotatedX = rotationMatrix(angle: Float(M_PI) / 4, axis: float3(1, 0, 0)) let modelMatrix = matrix_multiply(matrix_multiply(rotatedX, rotatedY), scaled) let cameraPosition = vector_float3(0, 0, -3) - let viewMatrix = translationMatrix(cameraPosition) - let aspect = Float(drawableSize.width / drawableSize.height) - let projMatrix = projectionMatrix(0, far: 10, aspect: aspect, fovy: 1) + let viewMatrix = translationMatrix(position: cameraPosition) + let projMatrix = projectionMatrix(near: 0, far: 10, aspect: 1, fovy: 1) let modelViewProjectionMatrix = matrix_multiply(projMatrix, matrix_multiply(viewMatrix, modelMatrix)) - let bufferPointer = uniform_buffer.contents() + let bufferPointer = uniformBuffer.contents() var uniforms = Uniforms(modelViewProjectionMatrix: modelViewProjectionMatrix) - memcpy(bufferPointer, &uniforms, sizeof(Uniforms)) + memcpy(bufferPointer, &uniforms, MemoryLayout.size) } - override public func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) + public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} + + public func draw(in view: MTKView) { update() - if let rpd = currentRenderPassDescriptor, drawable = currentDrawable { - rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.3, 0.5, 0.5, 1.0) - let command_buffer = commandQueue.commandBuffer() - let command_encoder = command_buffer.renderCommandEncoderWithDescriptor(rpd) - command_encoder.setRenderPipelineState(rps) - command_encoder.setFrontFacingWinding(.CounterClockwise) - command_encoder.setCullMode(.Back) - command_encoder.setVertexBuffer(vertex_buffer, offset: 0, atIndex: 0) - command_encoder.setVertexBuffer(uniform_buffer, offset: 0, atIndex: 1) - command_encoder.drawIndexedPrimitives(.Triangle, indexCount: index_buffer.length / sizeof(UInt16), indexType: MTLIndexType.UInt16, indexBuffer: index_buffer, indexBufferOffset: 0) - command_encoder.endEncoding() - command_buffer.presentDrawable(drawable) - command_buffer.commit() + if let rpd = view.currentRenderPassDescriptor, let drawable = view.currentDrawable { + rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0) + let commandBuffer = queue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: rpd) + commandEncoder.setRenderPipelineState(rps) + commandEncoder.setFrontFacing(.counterClockwise) + commandEncoder.setCullMode(.back) + commandEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0) + commandEncoder.setVertexBuffer(uniformBuffer, offset: 0, at: 1) + commandEncoder.drawIndexedPrimitives(type: .triangle, indexCount: indexBuffer.length / MemoryLayout.size, indexType: MTLIndexType.uint16, indexBuffer: indexBuffer, indexBufferOffset: 0) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() } } } diff --git a/ch09/chapter09.playground/contents.xcplayground b/ch09/chapter09.playground/contents.xcplayground index 06828af..9f9eecc 100644 --- a/ch09/chapter09.playground/contents.xcplayground +++ b/ch09/chapter09.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/ch09/chapter09.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch09/chapter09.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index 6294b51..9c3f516 100755 Binary files a/ch09/chapter09.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch09/chapter09.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch10/chapter10.playground/Contents.swift b/ch10/chapter10.playground/Contents.swift old mode 100755 new mode 100644 index 96ca6ff..694d377 --- a/ch10/chapter10.playground/Contents.swift +++ b/ch10/chapter10.playground/Contents.swift @@ -1,8 +1,9 @@ -import Cocoa -import XCPlayground +import MetalKit +import PlaygroundSupport -let device = MTLCreateSystemDefaultDevice()! -let frame = NSRect(x: 0, y: 0, width: 300, height: 300) -let view = MetalView(frame: frame, device: device) -XCPlaygroundPage.currentPage.liveView = view +let frame = NSRect(x: 0, y: 0, width: 400, height: 400) +let delegate = MetalView() +let view = MTKView(frame: frame, device: delegate.device) +view.delegate = delegate +PlaygroundPage.current.liveView = view diff --git a/ch10/chapter10.playground/Sources/MetalView.swift b/ch10/chapter10.playground/Sources/MetalView.swift index 6cbc65c..879e690 100755 --- a/ch10/chapter10.playground/Sources/MetalView.swift +++ b/ch10/chapter10.playground/Sources/MetalView.swift @@ -1,46 +1,45 @@ import MetalKit -public class MetalView: MTKView { +public class MetalView: NSObject, MTKViewDelegate { - var queue: MTLCommandQueue! = nil - var cps: MTLComputePipelineState! = nil + public var device: MTLDevice! + var queue: MTLCommandQueue! + var cps: MTLComputePipelineState! - required public init(coder: NSCoder) { - super.init(coder: coder) - } - - override public init(frame frameRect: CGRect, device: MTLDevice?) { - super.init(frame: frameRect, device: device) + override public init() { + super.init() registerShaders() } - override public func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) - if let drawable = currentDrawable { - let command_buffer = queue.commandBuffer() - let command_encoder = command_buffer.computeCommandEncoder() - command_encoder.setComputePipelineState(cps) - command_encoder.setTexture(drawable.texture, atIndex: 0) - let threadGroupCount = MTLSizeMake(8, 8, 1) - let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1) - command_encoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount) - command_encoder.endEncoding() - command_buffer.presentDrawable(drawable) - command_buffer.commit() - } - } - func registerShaders() { - queue = device!.newCommandQueue() - let path = NSBundle.mainBundle().pathForResource("Shaders", ofType: "metal") + device = MTLCreateSystemDefaultDevice()! + queue = device.makeCommandQueue() + let path = Bundle.main.path(forResource: "Shaders", ofType: "metal") do { - let input = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding) - let library = try device!.newLibraryWithSource(input, options: nil) - let kernel = library.newFunctionWithName("compute")! - cps = try device!.newComputePipelineStateWithFunction(kernel) + let input = try String(contentsOfFile: path!, encoding: String.Encoding.utf8) + let library = try device.makeLibrary(source: input, options: nil) + let kernel = library.makeFunction(name: "compute")! + cps = try device.makeComputePipelineState(function: kernel) } catch let e { Swift.print("\(e)") } } + + public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} + + public func draw(in view: MTKView) { + if let drawable = view.currentDrawable { + let commandBuffer = queue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeComputeCommandEncoder() + commandEncoder.setComputePipelineState(cps) + commandEncoder.setTexture(drawable.texture, at: 0) + let threadGroupCount = MTLSizeMake(8, 8, 1) + let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1) + commandEncoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() + } + } } diff --git a/ch10/chapter10.playground/contents.xcplayground b/ch10/chapter10.playground/contents.xcplayground old mode 100755 new mode 100644 diff --git a/ch10/chapter10.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch10/chapter10.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index b0371a6..70c0b8b 100755 Binary files a/ch10/chapter10.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch10/chapter10.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch11/chapter11.playground/Contents.swift b/ch11/chapter11.playground/Contents.swift index 00f436f..694d377 100644 --- a/ch11/chapter11.playground/Contents.swift +++ b/ch11/chapter11.playground/Contents.swift @@ -1,8 +1,9 @@ -import Cocoa -import XCPlayground +import MetalKit +import PlaygroundSupport -let device = MTLCreateSystemDefaultDevice()! -let frame = NSRect(x:0, y:0, width:300, height:300) -let view = MetalView(frame: frame, device: device) -XCPlaygroundPage.currentPage.liveView = view +let frame = NSRect(x: 0, y: 0, width: 400, height: 400) +let delegate = MetalView() +let view = MTKView(frame: frame, device: delegate.device) +view.delegate = delegate +PlaygroundPage.current.liveView = view diff --git a/ch11/chapter11.playground/Sources/MetalView.swift b/ch11/chapter11.playground/Sources/MetalView.swift index 425569a..24c4256 100755 --- a/ch11/chapter11.playground/Sources/MetalView.swift +++ b/ch11/chapter11.playground/Sources/MetalView.swift @@ -1,56 +1,45 @@ import MetalKit -public class MetalView: MTKView { - - var queue: MTLCommandQueue! = nil - var cps: MTLComputePipelineState! = nil - - var shader = - "#include \n" + - "using namespace metal;" + - "kernel void compute(texture2d output [[texture(0)]]," + - " uint2 gid [[thread_position_in_grid]])" + - "{" + - " output.write(float4(1, 1, 0, 1), gid);" + - "}" - - required public init(coder: NSCoder) { - super.init(coder: coder) +public class MetalView: NSObject, MTKViewDelegate { + + public var device: MTLDevice! + var queue: MTLCommandQueue! + var cps: MTLComputePipelineState! + + override public init() { + super.init() + registerShaders() + } + + func registerShaders() { + device = MTLCreateSystemDefaultDevice()! + queue = device.makeCommandQueue() + let path = Bundle.main.path(forResource: "Shaders", ofType: "metal") + do { + let input = try String(contentsOfFile: path!, encoding: String.Encoding.utf8) + let library = try device.makeLibrary(source: input, options: nil) + let kernel = library.makeFunction(name: "compute")! + cps = try device.makeComputePipelineState(function: kernel) + } catch let e { + Swift.print("\(e)") } - - override public init(frame frameRect: CGRect, device: MTLDevice?) { - super.init(frame: frameRect, device: device) - registerShaders() - } - - override public func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) - if let drawable = currentDrawable { - let command_buffer = queue.commandBuffer() - let command_encoder = command_buffer.computeCommandEncoder() - command_encoder.setComputePipelineState(cps) - command_encoder.setTexture(drawable.texture, atIndex: 0) - let threadGroupCount = MTLSizeMake(8, 8, 1) - let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1) - command_encoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount) - command_encoder.endEncoding() - command_buffer.presentDrawable(drawable) - command_buffer.commit() - } - } - - func registerShaders() { - queue = device!.newCommandQueue() - let path = NSBundle.mainBundle().pathForResource("Shaders", ofType: "metal") - do { - let input = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding) - let library = try device!.newLibraryWithSource(input, options: nil) -// let library = try device!.newLibraryWithSource(shader, options: nil) - let kernel = library.newFunctionWithName("compute")! - cps = try device!.newComputePipelineStateWithFunction(kernel) - } catch let e { - Swift.print("\(e)") - } + } + + public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} + + public func draw(in view: MTKView) { + if let drawable = view.currentDrawable { + let commandBuffer = queue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeComputeCommandEncoder() + commandEncoder.setComputePipelineState(cps) + commandEncoder.setTexture(drawable.texture, at: 0) + let threadGroupCount = MTLSizeMake(8, 8, 1) + let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1) + commandEncoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() } + } } diff --git a/ch11/chapter11.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch11/chapter11.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index f4c9511..ce8659e 100755 Binary files a/ch11/chapter11.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch11/chapter11.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch11/chapter11.playground/timeline.xctimeline b/ch11/chapter11.playground/timeline.xctimeline deleted file mode 100644 index bf468af..0000000 --- a/ch11/chapter11.playground/timeline.xctimeline +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/ch12/chapter12.playground/Contents.swift b/ch12/chapter12.playground/Contents.swift index 9faf781..939e603 100644 --- a/ch12/chapter12.playground/Contents.swift +++ b/ch12/chapter12.playground/Contents.swift @@ -1,8 +1,8 @@ -import Cocoa -import XCPlayground +import MetalKit +import PlaygroundSupport let device = MTLCreateSystemDefaultDevice()! -let frame = NSRect(x:0, y:0, width:300, height:300) -let metalView = MetalView(frame: frame, device: device) -XCPlaygroundPage.currentPage.liveView = metalView +let frame = NSRect(x: 0, y: 0, width: 400, height: 400) +let view = MetalView(frame: frame, device: device) +PlaygroundPage.current.liveView = view diff --git a/ch12/chapter12.playground/Sources/MetalView.swift b/ch12/chapter12.playground/Sources/MetalView.swift index 37c8100..e84b3f7 100755 --- a/ch12/chapter12.playground/Sources/MetalView.swift +++ b/ch12/chapter12.playground/Sources/MetalView.swift @@ -10,8 +10,8 @@ public class MetalView: MTKView, NSWindowDelegate { var mouseBuffer: MTLBuffer! var pos: NSPoint! - override public func mouseDown(event: NSEvent) { - pos = convertPointToLayer(convertPoint(event.locationInWindow, fromView: nil)) + override public func mouseDown(with event: NSEvent) { + pos = convertToLayer(convert(event.locationInWindow, from: nil)) let scale = layer!.contentsScale pos.x *= scale pos.y *= scale @@ -26,21 +26,21 @@ public class MetalView: MTKView, NSWindowDelegate { registerShaders() } - override public func drawRect(dirtyRect: NSRect) { - super.drawRect(dirtyRect) + override public func draw(_ dirtyRect: NSRect) { + super.draw(dirtyRect) if let drawable = currentDrawable { - let commandBuffer = queue.commandBuffer() - let commandEncoder = commandBuffer.computeCommandEncoder() + let commandBuffer = queue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeComputeCommandEncoder() commandEncoder.setComputePipelineState(cps) - commandEncoder.setTexture(drawable.texture, atIndex: 0) - commandEncoder.setBuffer(mouseBuffer, offset: 0, atIndex: 2) - commandEncoder.setBuffer(timerBuffer, offset: 0, atIndex: 1) + commandEncoder.setTexture(drawable.texture, at: 0) + commandEncoder.setBuffer(mouseBuffer, offset: 0, at: 2) + commandEncoder.setBuffer(timerBuffer, offset: 0, at: 1) update() let threadGroupCount = MTLSizeMake(8, 8, 1) let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1) commandEncoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount) commandEncoder.endEncoding() - commandBuffer.presentDrawable(drawable) + commandBuffer.present(drawable) commandBuffer.commit() } @@ -49,23 +49,23 @@ public class MetalView: MTKView, NSWindowDelegate { func update() { timer += 0.01 var bufferPointer = timerBuffer.contents() - memcpy(bufferPointer, &timer, sizeof(Float)) + memcpy(bufferPointer, &timer, MemoryLayout.size) bufferPointer = mouseBuffer.contents() - memcpy(bufferPointer, &pos, sizeof(NSPoint)) + memcpy(bufferPointer, &pos, MemoryLayout.size) } func registerShaders() { - queue = device!.newCommandQueue() - let path = NSBundle.mainBundle().pathForResource("Shaders", ofType: "metal") + queue = device!.makeCommandQueue() + let path = Bundle.main.path(forResource: "Shaders", ofType: "metal") do { - let input = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding) - let library = try device!.newLibraryWithSource(input, options: nil) - let kernel = library.newFunctionWithName("compute")! - cps = try device!.newComputePipelineStateWithFunction(kernel) + let input = try String(contentsOfFile: path!, encoding: String.Encoding.utf8) + let library = try device!.makeLibrary(source: input, options: nil) + let kernel = library.makeFunction(name: "compute")! + cps = try device!.makeComputePipelineState(function: kernel) } catch let e { Swift.print("\(e)") } - timerBuffer = device!.newBufferWithLength(sizeof(Float), options: []) - mouseBuffer = device!.newBufferWithLength(sizeof(NSPoint), options: []) + timerBuffer = device!.makeBuffer(length: MemoryLayout.size, options: []) + mouseBuffer = device!.makeBuffer(length: MemoryLayout.size, options: []) } } diff --git a/ch12/chapter12.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch12/chapter12.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index 746466e..4d3e7a8 100755 Binary files a/ch12/chapter12.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch12/chapter12.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch13/chapter13.playground/Contents.swift b/ch13/chapter13.playground/Contents.swift index 366d424..feabd6e 100644 --- a/ch13/chapter13.playground/Contents.swift +++ b/ch13/chapter13.playground/Contents.swift @@ -1,8 +1,8 @@ -import Cocoa -import XCPlayground +import MetalKit +import PlaygroundSupport let device = MTLCreateSystemDefaultDevice()! let frame = NSRect(x:0, y:0, width:400, height:400) let view = MetalView(frame: frame, device: device) -XCPlaygroundPage.currentPage.liveView = view +PlaygroundPage.current.liveView = view diff --git a/ch13/chapter13.playground/Sources/MetalView.swift b/ch13/chapter13.playground/Sources/MetalView.swift index 7120f0b..e41a720 100755 --- a/ch13/chapter13.playground/Sources/MetalView.swift +++ b/ch13/chapter13.playground/Sources/MetalView.swift @@ -10,8 +10,8 @@ public class MetalView: MTKView, NSWindowDelegate { var mouseBuffer: MTLBuffer! var pos: NSPoint! - override public func mouseDown(event: NSEvent) { - pos = convertPointToLayer(convertPoint(event.locationInWindow, fromView: nil)) + override public func mouseDown(with event: NSEvent) { + pos = convertToLayer(convert(event.locationInWindow, from: nil)) let scale = layer!.contentsScale pos.x *= scale pos.y *= scale @@ -26,20 +26,20 @@ public class MetalView: MTKView, NSWindowDelegate { registerShaders() } - override public func drawRect(dirtyRect: NSRect) { + override public func draw(_ dirtyRect: NSRect) { if let drawable = currentDrawable { - let commandBuffer = queue.commandBuffer() - let commandEncoder = commandBuffer.computeCommandEncoder() + let commandBuffer = queue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeComputeCommandEncoder() commandEncoder.setComputePipelineState(cps) - commandEncoder.setTexture(drawable.texture, atIndex: 0) - commandEncoder.setBuffer(mouseBuffer, offset: 0, atIndex: 2) - commandEncoder.setBuffer(timerBuffer, offset: 0, atIndex: 1) + commandEncoder.setTexture(drawable.texture, at: 0) + commandEncoder.setBuffer(mouseBuffer, offset: 0, at: 2) + commandEncoder.setBuffer(timerBuffer, offset: 0, at: 1) update() let threadGroupCount = MTLSizeMake(8, 8, 1) let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1) commandEncoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount) commandEncoder.endEncoding() - commandBuffer.presentDrawable(drawable) + commandBuffer.present(drawable) commandBuffer.commit() } @@ -48,23 +48,23 @@ public class MetalView: MTKView, NSWindowDelegate { func update() { timer += 0.01 var bufferPointer = timerBuffer.contents() - memcpy(bufferPointer, &timer, sizeof(Float)) + memcpy(bufferPointer, &timer, MemoryLayout.size) bufferPointer = mouseBuffer.contents() - memcpy(bufferPointer, &pos, sizeof(NSPoint)) + memcpy(bufferPointer, &pos, MemoryLayout.size) } func registerShaders() { - queue = device!.newCommandQueue() - let path = NSBundle.mainBundle().pathForResource("Shaders", ofType: "metal") + queue = device!.makeCommandQueue() + let path = Bundle.main.path(forResource: "Shaders", ofType: "metal") do { - let input = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding) - let library = try device!.newLibraryWithSource(input, options: nil) - let kernel = library.newFunctionWithName("compute")! - cps = try device!.newComputePipelineStateWithFunction(kernel) + let input = try String(contentsOfFile: path!, encoding: String.Encoding.utf8) + let library = try device!.makeLibrary(source: input, options: nil) + let kernel = library.makeFunction(name: "compute")! + cps = try device!.makeComputePipelineState(function: kernel) } catch let e { Swift.print("\(e)") } - timerBuffer = device!.newBufferWithLength(sizeof(Float), options: []) - mouseBuffer = device!.newBufferWithLength(sizeof(NSPoint), options: []) + timerBuffer = device!.makeBuffer(length: MemoryLayout.size, options: []) + mouseBuffer = device!.makeBuffer(length: MemoryLayout.size, options: []) } } diff --git a/ch13/chapter13.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch13/chapter13.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index ac9ca7b..a500de3 100755 Binary files a/ch13/chapter13.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch13/chapter13.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch14/chapter14.playground/Contents.swift b/ch14/chapter14.playground/Contents.swift index 366d424..abfc392 100644 --- a/ch14/chapter14.playground/Contents.swift +++ b/ch14/chapter14.playground/Contents.swift @@ -1,8 +1,8 @@ import Cocoa -import XCPlayground +import PlaygroundSupport let device = MTLCreateSystemDefaultDevice()! let frame = NSRect(x:0, y:0, width:400, height:400) let view = MetalView(frame: frame, device: device) -XCPlaygroundPage.currentPage.liveView = view +PlaygroundPage.current.liveView = view diff --git a/ch14/chapter14.playground/Resources/Shaders.metal b/ch14/chapter14.playground/Resources/Shaders.metal index 946c689..cddf12f 100755 --- a/ch14/chapter14.playground/Resources/Shaders.metal +++ b/ch14/chapter14.playground/Resources/Shaders.metal @@ -33,8 +33,7 @@ float fbm(float2 uv) } kernel void compute(texture2d output [[texture(0)]], - constant float2 &mouse [[buffer(0)]], - constant float &timer [[buffer(1)]], + constant float &timer [[buffer(0)]], uint2 gid [[thread_position_in_grid]]) { int width = output.get_width(); diff --git a/ch14/chapter14.playground/Sources/MetalView.swift b/ch14/chapter14.playground/Sources/MetalView.swift index 7120f0b..c53b382 100755 --- a/ch14/chapter14.playground/Sources/MetalView.swift +++ b/ch14/chapter14.playground/Sources/MetalView.swift @@ -7,15 +7,6 @@ public class MetalView: MTKView, NSWindowDelegate { var cps: MTLComputePipelineState! = nil var timer: Float = 0 var timerBuffer: MTLBuffer! - var mouseBuffer: MTLBuffer! - var pos: NSPoint! - - override public func mouseDown(event: NSEvent) { - pos = convertPointToLayer(convertPoint(event.locationInWindow, fromView: nil)) - let scale = layer!.contentsScale - pos.x *= scale - pos.y *= scale - } required public init(coder: NSCoder) { super.init(coder: coder) @@ -26,20 +17,19 @@ public class MetalView: MTKView, NSWindowDelegate { registerShaders() } - override public func drawRect(dirtyRect: NSRect) { + override public func draw(_ dirtyRect: NSRect) { if let drawable = currentDrawable { - let commandBuffer = queue.commandBuffer() - let commandEncoder = commandBuffer.computeCommandEncoder() + let commandBuffer = queue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeComputeCommandEncoder() commandEncoder.setComputePipelineState(cps) - commandEncoder.setTexture(drawable.texture, atIndex: 0) - commandEncoder.setBuffer(mouseBuffer, offset: 0, atIndex: 2) - commandEncoder.setBuffer(timerBuffer, offset: 0, atIndex: 1) + commandEncoder.setTexture(drawable.texture, at: 0) + commandEncoder.setBuffer(timerBuffer, offset: 0, at: 0) update() let threadGroupCount = MTLSizeMake(8, 8, 1) let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1) commandEncoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount) commandEncoder.endEncoding() - commandBuffer.presentDrawable(drawable) + commandBuffer.present(drawable) commandBuffer.commit() } @@ -47,24 +37,21 @@ public class MetalView: MTKView, NSWindowDelegate { func update() { timer += 0.01 - var bufferPointer = timerBuffer.contents() - memcpy(bufferPointer, &timer, sizeof(Float)) - bufferPointer = mouseBuffer.contents() - memcpy(bufferPointer, &pos, sizeof(NSPoint)) + let bufferPointer = timerBuffer.contents() + memcpy(bufferPointer, &timer, MemoryLayout.size) } func registerShaders() { - queue = device!.newCommandQueue() - let path = NSBundle.mainBundle().pathForResource("Shaders", ofType: "metal") + queue = device!.makeCommandQueue() + let path = Bundle.main.path(forResource: "Shaders", ofType: "metal") do { - let input = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding) - let library = try device!.newLibraryWithSource(input, options: nil) - let kernel = library.newFunctionWithName("compute")! - cps = try device!.newComputePipelineStateWithFunction(kernel) + let input = try String(contentsOfFile: path!, encoding: String.Encoding.utf8) + let library = try device!.makeLibrary(source: input, options: nil) + let kernel = library.makeFunction(name: "compute")! + cps = try device!.makeComputePipelineState(function: kernel) } catch let e { Swift.print("\(e)") } - timerBuffer = device!.newBufferWithLength(sizeof(Float), options: []) - mouseBuffer = device!.newBufferWithLength(sizeof(NSPoint), options: []) + timerBuffer = device!.makeBuffer(length: MemoryLayout.size, options: []) } } diff --git a/ch14/chapter14.playground/contents.xcplayground b/ch14/chapter14.playground/contents.xcplayground index 06828af..9f9eecc 100644 --- a/ch14/chapter14.playground/contents.xcplayground +++ b/ch14/chapter14.playground/contents.xcplayground @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/ch14/chapter14.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch14/chapter14.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate index a985682..dfb49fd 100755 Binary files a/ch14/chapter14.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate and b/ch14/chapter14.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch14/chapter14.playground/timeline.xctimeline b/ch14/chapter14.playground/timeline.xctimeline deleted file mode 100644 index bf468af..0000000 --- a/ch14/chapter14.playground/timeline.xctimeline +++ /dev/null @@ -1,6 +0,0 @@ - - - - - diff --git a/ch15/chapter15.playground/Contents.swift b/ch15/chapter15.playground/Contents.swift new file mode 100644 index 0000000..694d377 --- /dev/null +++ b/ch15/chapter15.playground/Contents.swift @@ -0,0 +1,9 @@ + +import MetalKit +import PlaygroundSupport + +let frame = NSRect(x: 0, y: 0, width: 400, height: 400) +let delegate = MetalView() +let view = MTKView(frame: frame, device: delegate.device) +view.delegate = delegate +PlaygroundPage.current.liveView = view diff --git a/ch15/chapter15.playground/Resources/Shaders.metal b/ch15/chapter15.playground/Resources/Shaders.metal new file mode 100755 index 0000000..83af2b1 --- /dev/null +++ b/ch15/chapter15.playground/Resources/Shaders.metal @@ -0,0 +1,30 @@ + +#include + +using namespace metal; + +kernel void compute(texture2d output [[texture(0)]], + texture2d input [[texture(1)]], + constant float &timer [[buffer(0)]], + uint2 gid [[thread_position_in_grid]]) +{ + int width = input.get_width(); + int height = input.get_height(); + float2 uv = float2(gid) / float2(width, height); + uv = uv * 2.0 - 1.0; + uv = uv * 2; + float radius = 1; + float distance = length(uv) - radius; + constexpr sampler textureSampler(coord::normalized, + address::repeat, + min_filter::linear, + mag_filter::linear, + mip_filter::linear ); + float3 norm = float3(uv, sqrt(1.0 - dot(uv, uv))); + float pi = 3.14; + float s = atan2( norm.z, norm.x ) / (2 * pi); + float t = asin( norm.y ) / (2 * pi); + t += 0.5; + float4 color = input.sample(textureSampler, float2(s + timer * 0.1, t)); + output.write(distance < 0 ? color : float4(0), gid); +} diff --git a/ch15/chapter15.playground/Resources/texture.jpg b/ch15/chapter15.playground/Resources/texture.jpg new file mode 100644 index 0000000..00075c9 Binary files /dev/null and b/ch15/chapter15.playground/Resources/texture.jpg differ diff --git a/ch15/chapter15.playground/Sources/MetalView.swift b/ch15/chapter15.playground/Sources/MetalView.swift new file mode 100755 index 0000000..a451e4d --- /dev/null +++ b/ch15/chapter15.playground/Sources/MetalView.swift @@ -0,0 +1,65 @@ + +import MetalKit + +public class MetalView: NSObject, MTKViewDelegate { + + public var device: MTLDevice! + var queue: MTLCommandQueue! = nil + var cps: MTLComputePipelineState! = nil + var timer: Float = 0 + var timerBuffer: MTLBuffer! + var texture: MTLTexture! + + override public init() { + super.init() + device = MTLCreateSystemDefaultDevice()! + queue = device!.makeCommandQueue() + setUpTexture() + registerShaders() + } + + func setUpTexture() { + let path = Bundle.main.path(forResource: "texture", ofType: "jpg") + let textureLoader = MTKTextureLoader(device: device!) + texture = try! textureLoader.newTexture(withContentsOf: URL(fileURLWithPath: path!), options: nil) + } + + func registerShaders() { + let path = Bundle.main.path(forResource: "Shaders", ofType: "metal") + do { + let input = try String(contentsOfFile: path!, encoding: String.Encoding.utf8) + let library = try device!.makeLibrary(source: input, options: nil) + let kernel = library.makeFunction(name: "compute")! + cps = try device!.makeComputePipelineState(function: kernel) + } catch let e { + Swift.print("\(e)") + } + timerBuffer = device!.makeBuffer(length: MemoryLayout.size, options: []) + } + + func update() { + timer += 0.01 + let bufferPointer = timerBuffer.contents() + memcpy(bufferPointer, &timer, MemoryLayout.size) + } + + public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} + + public func draw(in view: MTKView) { + if let drawable = view.currentDrawable { + let commandBuffer = queue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeComputeCommandEncoder() + commandEncoder.setComputePipelineState(cps) + commandEncoder.setTexture(drawable.texture, at: 0) + commandEncoder.setTexture(texture, at: 1) + commandEncoder.setBuffer(timerBuffer, offset: 0, at: 0) + update() + let threadGroupCount = MTLSizeMake(8, 8, 1) + let threadGroups = MTLSizeMake(drawable.texture.width / threadGroupCount.width, drawable.texture.height / threadGroupCount.height, 1) + commandEncoder.dispatchThreadgroups(threadGroups, threadsPerThreadgroup: threadGroupCount) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() + } + } +} diff --git a/ch15/chapter15.playground/contents.xcplayground b/ch15/chapter15.playground/contents.xcplayground new file mode 100644 index 0000000..06828af --- /dev/null +++ b/ch15/chapter15.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ch15/chapter15.playground/playground.xcworkspace/contents.xcworkspacedata b/ch15/chapter15.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100755 index 0000000..919434a --- /dev/null +++ b/ch15/chapter15.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ch15/chapter15.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch15/chapter15.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100755 index 0000000..e3db174 Binary files /dev/null and b/ch15/chapter15.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch09/chapter09.playground/timeline.xctimeline b/ch15/chapter15.playground/timeline.xctimeline similarity index 100% rename from ch09/chapter09.playground/timeline.xctimeline rename to ch15/chapter15.playground/timeline.xctimeline diff --git a/ch17/chapter17.playground/Contents.swift b/ch17/chapter17.playground/Contents.swift new file mode 100644 index 0000000..01fb50a --- /dev/null +++ b/ch17/chapter17.playground/Contents.swift @@ -0,0 +1,8 @@ + +import MetalKit +import PlaygroundSupport + +let view = MTKView(frame: NSRect(x: 0, y: 0, width: 300, height: 300)) +let renderer = Render(mtkView: view) +view.delegate = renderer +PlaygroundPage.current.liveView = view diff --git a/ch17/chapter17.playground/Resources/Shaders.metal b/ch17/chapter17.playground/Resources/Shaders.metal new file mode 100644 index 0000000..93a57ab --- /dev/null +++ b/ch17/chapter17.playground/Resources/Shaders.metal @@ -0,0 +1,24 @@ + +#include + +using namespace metal; + +struct Vertex { + float4 position [[position]]; + float4 color; +}; + +vertex Vertex vertex_transform(device Vertex *vertices [[buffer(0)]], + uint vertexId [[vertex_id]]) +{ + Vertex out; + out.position = vertices[vertexId].position; + out.color = vertices[vertexId].color; + return out; +} + +fragment half4 fragment_lighting(Vertex fragmentIn [[stage_in]]) +{ +// return half4(fragmentIn.color); + return half4(0.0, 1.0, 0.0, 1.0); +} diff --git a/ch17/chapter17.playground/Sources/Render.swift b/ch17/chapter17.playground/Sources/Render.swift new file mode 100644 index 0000000..afea1d9 --- /dev/null +++ b/ch17/chapter17.playground/Sources/Render.swift @@ -0,0 +1,73 @@ + +import MetalKit + +public class Render : NSObject, MTKViewDelegate { + + weak var view: MTKView! + let commandQueue: MTLCommandQueue + let renderPipelineState: MTLRenderPipelineState + let device: MTLDevice + var vertexBuffer: MTLBuffer + var indexBuffer: MTLBuffer + + struct Vertex { + var position: float4 + var color: float4 + } + + public init?(mtkView: MTKView) { + view = mtkView + view.clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1) + view.colorPixelFormat = .bgra8Unorm + device = MTLCreateSystemDefaultDevice()! + commandQueue = device.makeCommandQueue() + renderPipelineState = try! Render.buildRenderPipelineWithDevice(device: device, view: mtkView) + + var vertices = [Vertex]() + vertices.append(Vertex(position: float4(-0.5, -0.5, 0, 1), color: float4(1, 0, 0, 1))) + vertices.append(Vertex(position: float4( 0.5, -0.5, 0, 1), color: float4(0, 1, 0, 1))) + vertices.append(Vertex(position: float4( 0.0, 0.5, 0, 1), color: float4(0, 0, 1, 1))) + + var indices = [UInt16]() + indices.append(0) + indices.append(1) + indices.append(2) + + vertexBuffer = device.makeBuffer(bytes: vertices, length: MemoryLayout.stride * vertices.count, options: []) + indexBuffer = device.makeBuffer(bytes: indices, length: MemoryLayout.stride * indices.count, options: []) + + super.init() + view.delegate = self + view.device = device + } + + class func buildRenderPipelineWithDevice(device: MTLDevice, view: MTKView) throws -> MTLRenderPipelineState { + let path = Bundle.main.path(forResource: "Shaders", ofType: "metal")! + let input = try! String(contentsOfFile: path, encoding: String.Encoding.utf8) + let library = try! device.makeLibrary(source: input, options: nil) + let vertexFunction = library.makeFunction(name: "vertex_transform") + let fragmentFunction = library.makeFunction(name: "fragment_lighting") + let pipelineDescriptor = MTLRenderPipelineDescriptor() + pipelineDescriptor.sampleCount = view.sampleCount + pipelineDescriptor.vertexFunction = vertexFunction + pipelineDescriptor.fragmentFunction = fragmentFunction + pipelineDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm + return try device.makeRenderPipelineState(descriptor: pipelineDescriptor) + } + + public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} + + public func draw(in view: MTKView) { + let commandBuffer = commandQueue.makeCommandBuffer() + let renderPassDescriptor = view.currentRenderPassDescriptor! + let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) + renderEncoder.setVertexBuffer(vertexBuffer, offset:0, at:0) + renderEncoder.setRenderPipelineState(renderPipelineState) + renderEncoder.setTriangleFillMode(.lines) + renderEncoder.drawIndexedPrimitives(type: .triangle, indexCount: 3, indexType: .uint16, indexBuffer: indexBuffer,indexBufferOffset: 0) + renderEncoder.endEncoding() + commandBuffer.present(view.currentDrawable!) + commandBuffer.commit() + } +} + diff --git a/ch17/chapter17.playground/contents.xcplayground b/ch17/chapter17.playground/contents.xcplayground new file mode 100644 index 0000000..06828af --- /dev/null +++ b/ch17/chapter17.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ch17/chapter17.playground/playground.xcworkspace/contents.xcworkspacedata b/ch17/chapter17.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ch17/chapter17.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ch17/chapter17.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch17/chapter17.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..248130a Binary files /dev/null and b/ch17/chapter17.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch17/chapter17.playground/timeline.xctimeline b/ch17/chapter17.playground/timeline.xctimeline new file mode 100644 index 0000000..4e2f1f2 --- /dev/null +++ b/ch17/chapter17.playground/timeline.xctimeline @@ -0,0 +1,11 @@ + + + + + + + diff --git a/ch18/chapter18.playground/Contents.swift b/ch18/chapter18.playground/Contents.swift new file mode 100644 index 0000000..0027557 --- /dev/null +++ b/ch18/chapter18.playground/Contents.swift @@ -0,0 +1,45 @@ + + +let shader = +"#include \n" + + "using namespace metal;" + + "kernel void k(texture2d o[[texture(0)]]," + + " uint2 gid[[thread_position_in_grid]]) {" + + " int width = o.get_width();" + + " int height = o.get_height();" + + " float2 uv = float2(gid) / float2(width, height);" + + " float3 color = mix(float3(1.0, 0.6, 0.1), float3(0.5, 0.8, 1.0), sqrt(1 - uv.y));" + + " float2 q = uv - float2(0.67, 0.25);" + + " float r = 0.2 + 0.1 * cos(atan2(q.x, q.y) * 9.0 + 20.0 * q.x);" + + " color *= smoothstep(r, r + 0.01, length(q));" + + " r = 0.03 + 0.002 * cos(120.0 * q.y) + exp(-50.0 * (1.0 - uv.y));" + + " color *= 1.0 - (1.0 - smoothstep(r, r + 0.002, abs(q.x - 0.25 * sin(2.0 * q.y)))) * smoothstep(0.0, 0.1, q.y);" + + " o.write(float4(color, 1.0), gid);" + +"}" + +//"#include \n" + +// "using namespace metal;" + +// "kernel void k(texture2d o[[texture(0)]]," + +// " uint2 gid[[thread_position_in_grid]]) {" + +// " int width = o.get_width();" + +// " int height = o.get_height();" + +// " float2 uv = float2(gid) / float2(width, height);" + +// " float2 q = uv - float2(0.5);" + +// " float a = atan2(q.y, q.x) + 0.25;" + +// " float s = 0.5 + 0.5 * sin(3.0 * a);" + +// " float t = 0.15 + 0.5 * pow(s, 0.3) + 0.1 * pow(0.5 + 0.5 * cos(6.0 * a), 0.5);" + +// " float h = sqrt(dot(q, q)) / t;" + +// " float f = 0.0;" + +// " if(h < 0.4) f = 1.0;" + +// " float3 color = mix(float3(0.9), float3(0.5 * h, 0.5 + 0.5 * h, 0.0), f);" + +// " o.write(float4(color, 1.0), gid);" + +//"}" + +import MetalKit +import PlaygroundSupport + +let frame = CGRect(x: 0, y: 0, width: 300, height: 300) +let view = MTKView(frame: frame) +let delegate = MetalView(mtkView: view, shader: shader) +view.delegate = delegate +PlaygroundPage.current.liveView = view diff --git a/ch18/chapter18.playground/Sources/MetalView.swift b/ch18/chapter18.playground/Sources/MetalView.swift new file mode 100644 index 0000000..b8c4802 --- /dev/null +++ b/ch18/chapter18.playground/Sources/MetalView.swift @@ -0,0 +1,40 @@ + +import MetalKit + +public class MetalView: NSObject, MTKViewDelegate { + weak var view: MTKView! + let commandQueue: MTLCommandQueue + let device: MTLDevice + let cps: MTLComputePipelineState + + public init?(mtkView: MTKView, shader: String) { + view = mtkView + view.clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1) + view.colorPixelFormat = .bgra8Unorm + device = MTLCreateSystemDefaultDevice()! + commandQueue = device.makeCommandQueue() + let library = try! device.makeLibrary(source: shader, options: nil) + let function = library.makeFunction(name:"k")! + cps = try! device.makeComputePipelineState(function: function) + + super.init() + view.delegate = self + view.device = device + } + + public func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} + + public func draw(in view: MTKView) { + let drawable = view.currentDrawable! + let commandBuffer = commandQueue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeComputeCommandEncoder() + commandEncoder.setComputePipelineState(cps) + commandEncoder.setTexture(drawable.texture, at: 0) + let groups = MTLSize(width: Int(view.frame.width)/4, height: Int(view.frame.height)/4, depth: 1) + let threads = MTLSize(width: 8, height: 8,depth: 1) + commandEncoder.dispatchThreadgroups(groups,threadsPerThreadgroup: threads) + commandEncoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() + } +} diff --git a/ch18/chapter18.playground/contents.xcplayground b/ch18/chapter18.playground/contents.xcplayground new file mode 100644 index 0000000..a93d484 --- /dev/null +++ b/ch18/chapter18.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ch18/chapter18.playground/playground.xcworkspace/contents.xcworkspacedata b/ch18/chapter18.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ch18/chapter18.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ch18/chapter18.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch18/chapter18.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..07f813d Binary files /dev/null and b/ch18/chapter18.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch10/chapter10.playground/timeline.xctimeline b/ch18/chapter18.playground/timeline.xctimeline old mode 100755 new mode 100644 similarity index 100% rename from ch10/chapter10.playground/timeline.xctimeline rename to ch18/chapter18.playground/timeline.xctimeline