added chapter 17

This commit is contained in:
Marius Horga 2016-09-24 23:34:59 +03:00
parent 6efead4328
commit 6bf17dbe56
11 changed files with 151 additions and 18 deletions

View File

@ -33,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 = "<group>";
};
29C87D341C56E93A005F4615 = {
isa = PBXGroup;
children = (
@ -54,9 +64,7 @@
children = (
29C87D511C56E9DE005F4615 /* MetalView.swift */,
29C87D4F1C56E9C2005F4615 /* Shaders.metal */,
29C87D461C56E93B005F4615 /* Main.storyboard */,
29C87D491C56E93B005F4615 /* Info.plist */,
29C87D401C56E93A005F4615 /* AppDelegate.swift */,
293936291D96FDD500008B3A /* Supporting files */,
);
path = chapter04;
sourceTree = "<group>";

View File

@ -50,6 +50,8 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUFrameCaptureMode = "3"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">

View File

@ -27,36 +27,32 @@ class MetalView: MTKView {
func createBuffer() {
device = MTLCreateSystemDefaultDevice()!
commandQueue = device!.newCommandQueue()
let vertexData = [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])]
vertexBuffer = device!.newBuffer(withBytes: vertexData, length: sizeof(Vertex.self) * 3, options:[])
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<Vertex>.size * 3, options:[])
}
func registerShaders() {
let library = device!.newDefaultLibrary()!
let vertex_func = library.newFunction(withName: "vertex_func")
let frag_func = library.newFunction(withName: "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!.newRenderPipelineState(with: rpld)
} catch let error {
self.print("\(error)")
}
rps = try! device!.makeRenderPipelineState(descriptor: rpld)
}
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 commandBuffer = commandQueue!.commandBuffer()
let commandEncoder = commandBuffer.renderCommandEncoder(with: rpd)
let commandBuffer = commandQueue!.makeCommandBuffer()
let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: rpd)
commandEncoder.setRenderPipelineState(rps!)
commandEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0)
commandEncoder.drawPrimitives(.triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1)
commandEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1)
commandEncoder.endEncoding()
commandBuffer.present(drawable)
commandBuffer.commit()

View File

@ -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

View File

@ -0,0 +1,24 @@
#include <metal_stdlib>
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);
}

View File

@ -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<Vertex>.stride * vertices.count, options: [])
indexBuffer = device.makeBuffer(bytes: indices, length: MemoryLayout<UInt16>.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()
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='osx'>
<timeline fileName='timeline.xctimeline'/>
</playground>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
<LoggerValueHistoryTimelineItem
documentLocation = "#CharacterRangeLen=0&amp;CharacterRangeLoc=42&amp;EndingColumnNumber=5&amp;EndingLineNumber=3&amp;StartingColumnNumber=1&amp;StartingLineNumber=3&amp;Timestamp=491380952.018528"
selectedRepresentationIndex = "0"
shouldTrackSuperviewWidth = "NO">
</LoggerValueHistoryTimelineItem>
</TimelineItems>
</Timeline>