added chapter 17
This commit is contained in:
parent
6efead4328
commit
6bf17dbe56
|
|
@ -33,6 +33,16 @@
|
||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup 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 = {
|
29C87D341C56E93A005F4615 = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
|
@ -54,9 +64,7 @@
|
||||||
children = (
|
children = (
|
||||||
29C87D511C56E9DE005F4615 /* MetalView.swift */,
|
29C87D511C56E9DE005F4615 /* MetalView.swift */,
|
||||||
29C87D4F1C56E9C2005F4615 /* Shaders.metal */,
|
29C87D4F1C56E9C2005F4615 /* Shaders.metal */,
|
||||||
29C87D461C56E93B005F4615 /* Main.storyboard */,
|
293936291D96FDD500008B3A /* Supporting files */,
|
||||||
29C87D491C56E93B005F4615 /* Info.plist */,
|
|
||||||
29C87D401C56E93A005F4615 /* AppDelegate.swift */,
|
|
||||||
);
|
);
|
||||||
path = chapter04;
|
path = chapter04;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -50,6 +50,8 @@
|
||||||
ignoresPersistentStateOnLaunch = "NO"
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
debugDocumentVersioning = "YES"
|
debugDocumentVersioning = "YES"
|
||||||
debugServiceExtension = "internal"
|
debugServiceExtension = "internal"
|
||||||
|
enableGPUFrameCaptureMode = "3"
|
||||||
|
enableGPUValidationMode = "1"
|
||||||
allowLocationSimulation = "YES">
|
allowLocationSimulation = "YES">
|
||||||
<BuildableProductRunnable
|
<BuildableProductRunnable
|
||||||
runnableDebuggingMode = "0">
|
runnableDebuggingMode = "0">
|
||||||
|
|
|
||||||
|
|
@ -27,36 +27,32 @@ class MetalView: MTKView {
|
||||||
|
|
||||||
func createBuffer() {
|
func createBuffer() {
|
||||||
device = MTLCreateSystemDefaultDevice()!
|
device = MTLCreateSystemDefaultDevice()!
|
||||||
commandQueue = device!.newCommandQueue()
|
commandQueue = device!.makeCommandQueue()
|
||||||
let vertexData = [Vertex(position: [-1.0, -1.0, 0.0, 1.0], color: [1, 0, 0, 1]),
|
let vertexData = [Vertex(position: [-0.5, -0.5, 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.5, -0.5, 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(position: [ 0.0, 0.5, 0.0, 1.0], color: [0, 0, 1, 1])]
|
||||||
vertexBuffer = device!.newBuffer(withBytes: vertexData, length: sizeof(Vertex.self) * 3, options:[])
|
vertexBuffer = device!.makeBuffer(bytes: vertexData, length: MemoryLayout<Vertex>.size * 3, options:[])
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerShaders() {
|
func registerShaders() {
|
||||||
let library = device!.newDefaultLibrary()!
|
let library = device!.newDefaultLibrary()!
|
||||||
let vertex_func = library.newFunction(withName: "vertex_func")
|
let vertex_func = library.makeFunction(name: "vertex_func")
|
||||||
let frag_func = library.newFunction(withName: "fragment_func")
|
let frag_func = library.makeFunction(name: "fragment_func")
|
||||||
let rpld = MTLRenderPipelineDescriptor()
|
let rpld = MTLRenderPipelineDescriptor()
|
||||||
rpld.vertexFunction = vertex_func
|
rpld.vertexFunction = vertex_func
|
||||||
rpld.fragmentFunction = frag_func
|
rpld.fragmentFunction = frag_func
|
||||||
rpld.colorAttachments[0].pixelFormat = .bgra8Unorm
|
rpld.colorAttachments[0].pixelFormat = .bgra8Unorm
|
||||||
do {
|
rps = try! device!.makeRenderPipelineState(descriptor: rpld)
|
||||||
try rps = device!.newRenderPipelineState(with: rpld)
|
|
||||||
} catch let error {
|
|
||||||
self.print("\(error)")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func draw(_ dirtyRect: NSRect) {
|
override func draw(_ dirtyRect: NSRect) {
|
||||||
if let drawable = currentDrawable, let rpd = currentRenderPassDescriptor {
|
if let drawable = currentDrawable, let rpd = currentRenderPassDescriptor {
|
||||||
rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0)
|
rpd.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1.0)
|
||||||
let commandBuffer = commandQueue!.commandBuffer()
|
let commandBuffer = commandQueue!.makeCommandBuffer()
|
||||||
let commandEncoder = commandBuffer.renderCommandEncoder(with: rpd)
|
let commandEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: rpd)
|
||||||
commandEncoder.setRenderPipelineState(rps!)
|
commandEncoder.setRenderPipelineState(rps!)
|
||||||
commandEncoder.setVertexBuffer(vertexBuffer, offset: 0, at: 0)
|
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()
|
commandEncoder.endEncoding()
|
||||||
commandBuffer.present(drawable)
|
commandBuffer.present(drawable)
|
||||||
commandBuffer.commit()
|
commandBuffer.commit()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -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>
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Timeline
|
||||||
|
version = "3.0">
|
||||||
|
<TimelineItems>
|
||||||
|
<LoggerValueHistoryTimelineItem
|
||||||
|
documentLocation = "#CharacterRangeLen=0&CharacterRangeLoc=42&EndingColumnNumber=5&EndingLineNumber=3&StartingColumnNumber=1&StartingLineNumber=3&Timestamp=491380952.018528"
|
||||||
|
selectedRepresentationIndex = "0"
|
||||||
|
shouldTrackSuperviewWidth = "NO">
|
||||||
|
</LoggerValueHistoryTimelineItem>
|
||||||
|
</TimelineItems>
|
||||||
|
</Timeline>
|
||||||
Loading…
Reference in New Issue