diff --git a/README.md b/README.md index c6d03ea..4104d77 100644 --- a/README.md +++ b/README.md @@ -13,4 +13,5 @@ Repository to accompany the following blog posts: - [Using MetalKit part 9](http://mhorga.org/2016/04/18/using-metalkit-part-9.html) - [Using MetalKit part 10](http://mhorga.org/2016/05/02/using-metalkit-part-10.html) - [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) \ No newline at end of file +- [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) \ No newline at end of file diff --git a/ch13/chapter13.playground/Contents.swift b/ch13/chapter13.playground/Contents.swift new file mode 100644 index 0000000..366d424 --- /dev/null +++ b/ch13/chapter13.playground/Contents.swift @@ -0,0 +1,8 @@ + +import Cocoa +import XCPlayground + +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 diff --git a/ch13/chapter13.playground/Resources/Shaders.metal b/ch13/chapter13.playground/Resources/Shaders.metal new file mode 100755 index 0000000..f06002f --- /dev/null +++ b/ch13/chapter13.playground/Resources/Shaders.metal @@ -0,0 +1,30 @@ + +#include + +using namespace metal; + +kernel void compute(texture2d output [[texture(0)]], + constant float &timer [[buffer(1)]], + constant float2 &mouse [[buffer(2)]], + uint2 gid [[thread_position_in_grid]]) +{ + int width = output.get_width(); + int height = output.get_height(); + float2 uv = float2(gid) / float2(width, height); + uv = uv * 2.0 - 1.0; + float radius = 0.5; + float distance = length(uv) - radius; +// output.write(distance < 0 ? float4(1) : float4(0), gid); + + float planet = float(sqrt(radius * radius - uv.x * uv.x - uv.y * uv.y)); +// planet /= radius; +// output.write(distance < 0 ? float4(planet) : float4(0), gid); + + float3 normal = normalize(float3(uv.x, uv.y, planet)); +// output.write(distance < 0 ? float4(float3(normal), 1) : float4(0), gid); + + float3 source = normalize(float3(cos(timer), sin(timer), 1)); +// float3 source = normalize(float3(-1, 0, 1)); + float light = dot(normal, source); + output.write(distance < 0 ? float4(float3(light), 1) : float4(0), gid); +} diff --git a/ch13/chapter13.playground/Sources/MetalView.swift b/ch13/chapter13.playground/Sources/MetalView.swift new file mode 100755 index 0000000..37c8100 --- /dev/null +++ b/ch13/chapter13.playground/Sources/MetalView.swift @@ -0,0 +1,71 @@ + +import MetalKit + +public class MetalView: MTKView, NSWindowDelegate { + + var queue: MTLCommandQueue! = nil + 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) + } + + 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 commandBuffer = queue.commandBuffer() + let commandEncoder = commandBuffer.computeCommandEncoder() + commandEncoder.setComputePipelineState(cps) + commandEncoder.setTexture(drawable.texture, atIndex: 0) + commandEncoder.setBuffer(mouseBuffer, offset: 0, atIndex: 2) + commandEncoder.setBuffer(timerBuffer, offset: 0, atIndex: 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.commit() + } + + } + + func update() { + timer += 0.01 + var bufferPointer = timerBuffer.contents() + memcpy(bufferPointer, &timer, sizeof(Float)) + bufferPointer = mouseBuffer.contents() + memcpy(bufferPointer, &pos, sizeof(NSPoint)) + } + + 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 kernel = library.newFunctionWithName("compute")! + cps = try device!.newComputePipelineStateWithFunction(kernel) + } catch let e { + Swift.print("\(e)") + } + timerBuffer = device!.newBufferWithLength(sizeof(Float), options: []) + mouseBuffer = device!.newBufferWithLength(sizeof(NSPoint), options: []) + } +} diff --git a/ch13/chapter13.playground/contents.xcplayground b/ch13/chapter13.playground/contents.xcplayground new file mode 100644 index 0000000..06828af --- /dev/null +++ b/ch13/chapter13.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ch13/chapter13.playground/playground.xcworkspace/contents.xcworkspacedata b/ch13/chapter13.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100755 index 0000000..919434a --- /dev/null +++ b/ch13/chapter13.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ch13/chapter13.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate b/ch13/chapter13.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100755 index 0000000..ac9ca7b Binary files /dev/null and b/ch13/chapter13.playground/playground.xcworkspace/xcuserdata/marius.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/ch13/chapter13.playground/timeline.xctimeline b/ch13/chapter13.playground/timeline.xctimeline new file mode 100644 index 0000000..bf468af --- /dev/null +++ b/ch13/chapter13.playground/timeline.xctimeline @@ -0,0 +1,6 @@ + + + + +