Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- override func buildPipeline() {
- //Model
- let library = device!.newDefaultLibrary()!
- let pipelineDescriptor = MTLRenderPipelineDescriptor()
- buildPipelinForSky(pipelineDescriptor, library: library)
- buildPipelineForModel(pipelineDescriptor, library: library)
- do {
- pipelineSky = try device!.newRenderPipelineStateWithDescriptor(pipelineDescriptor)
- } catch {
- print("error with device.newRenderPipelineStateWithDescriptor")
- }
- let depthStencilDescriptor = MTLDepthStencilDescriptor()
- depthStencilDescriptor.depthCompareFunction = .Less
- depthStencilDescriptor.depthWriteEnabled = true
- depthStencilState = device!.newDepthStencilStateWithDescriptor(depthStencilDescriptor)
- commandQueue = device!.newCommandQueue()
- }
- func buildPipelineForModel(pipeLineDesc:MTLRenderPipelineDescriptor, library: MTLLibrary) -> MTLRenderPipelineDescriptor {
- let vertexFunctionModel = library.newFunctionWithName("vertex_ply")
- let fragmentFunctionModel = library.newFunctionWithName("fragment_ply")
- let vertexDescriptorModel = MTLVertexDescriptor()
- vertexDescriptorModel.attributes[0].offset = 0
- vertexDescriptorModel.attributes[0].format = .Float4
- vertexDescriptorModel.attributes[0].bufferIndex = 0
- vertexDescriptorModel.layouts[0].stepFunction = .PerVertex
- vertexDescriptorModel.layouts[0].stride = sizeof(Float) * 4
- pipeLineDesc.vertexFunction = vertexFunctionModel
- pipeLineDesc.vertexDescriptor = vertexDescriptorModel
- pipeLineDesc.fragmentFunction = fragmentFunctionModel
- pipeLineDesc.colorAttachments[0].pixelFormat = .BGRA8Unorm
- return pipeLineDesc
- }
- func buildPipelinForSky(pipeLineDesc:MTLRenderPipelineDescriptor, library: MTLLibrary ) -> MTLRenderPipelineDescriptor{
- let vertexFunctionSky = library.newFunctionWithName("vertex_sky")
- let fragmentFunctionSky = library.newFunctionWithName("fragment_sky")
- let vertexDescriptorSky = MTLVertexDescriptor()
- vertexDescriptorSky.attributes[0].offset = 0
- vertexDescriptorSky.attributes[0].format = .Float4
- vertexDescriptorSky.attributes[0].bufferIndex = 0
- vertexDescriptorSky.attributes[1].offset = sizeof(Float32) * 4
- vertexDescriptorSky.attributes[1].format = .Float4
- vertexDescriptorSky.attributes[1].bufferIndex = 0
- vertexDescriptorSky.attributes[2].offset = sizeof(Float32) * 8
- vertexDescriptorSky.attributes[2].format = .Float2
- vertexDescriptorSky.attributes[2].bufferIndex = 0
- vertexDescriptorSky.layouts[0].stepFunction = .PerVertex
- vertexDescriptorSky.layouts[0].stride = sizeof(Vertex)
- pipeLineDesc.vertexFunction = vertexFunctionSky
- pipeLineDesc.vertexDescriptor = vertexDescriptorSky
- pipeLineDesc.fragmentFunction = fragmentFunctionSky
- pipeLineDesc.depthAttachmentPixelFormat = .Depth32Float
- let samplerDescriptorSky = MTLSamplerDescriptor()
- samplerDescriptorSky.minFilter = .Nearest
- samplerDescriptorSky.magFilter = .Linear
- samplerStateSky = device!.newSamplerStateWithDescriptor(samplerDescriptorSky)
- return pipeLineDesc
- }
- override func buildResources() {
- // (vertexBuffer, indexBuffer) = SphereGenerator.sphereWithRadius(1, stacks: 30, slices: 30, device: device!)
- //Model
- (vertexBufferModel,normalBufferModel,colorBufferModel) = PointCloud.model(device!)
- uniformBufferModel = device!.newBufferWithLength(sizeof(M4f) * 2, options: .OptionCPUCacheModeDefault)
- //Sky
- vertexBufferSky = SkySphere.sphere(device!)
- uniformBufferSky = device!.newBufferWithLength(sizeof(M4f) * 2, options: .OptionCPUCacheModeDefault)
- diffuseTextureSky = self.textureForImage(UIImage(named: "bluemarble")!, device: device!)
- }
- override func resize() {
- //Model
- super.resize()
- //Sky
- let layerSizeSky = metalLayer.drawableSize
- let depthTextureDescriptorSky = MTLTextureDescriptor.texture2DDescriptorWithPixelFormat(.Depth32Float,
- width: Int(layerSizeSky.width),
- height: Int(layerSizeSky.height),
- mipmapped: false)
- depthTextureSky = device!.newTextureWithDescriptor(depthTextureDescriptorSky)
- }
- override func draw() {
- dispatch_semaphore_wait(inflightSemaphore, DISPATCH_TIME_FOREVER)
- //Sky
- if let drawable = metalLayer.nextDrawable()
- {
- var modelMatrixTransSky = M4f()
- var modelMatrixRotSky = M4f()
- var modelMatrixScaleSky = M4f()
- modelMatrixTransSky = translate(0, y: 0, z: 0)
- modelMatrixRotSky = rotate(90, r: V3f(1,0,0)) * modelMatrixRotSky
- modelMatrixScaleSky = scaling(10, y: 10, z: 10)
- let modelMatrixSky = modelMatrixTransSky * modelMatrixRotSky * modelMatrixScaleSky
- var viewMatrixSky = M4f()
- viewMatrixSky = myCamera.setLookAt(viewMatrixSky)
- let modelViewMatrixSky = viewMatrixSky * modelMatrixSky
- let aspect = Float32(metalLayer.drawableSize.width) / Float32(metalLayer.drawableSize.height)
- let kFOVY:Float = 85.0
- let projectionMatrix = perspective_fov(kFOVY, aspect: aspect, near: 0.1, far: 180.0)
- let matricesSky = [projectionMatrix, modelViewMatrixSky]
- memcpy(uniformBufferSky.contents(), matricesSky, Int(sizeof(M4f) * 2))
- let commandBufferSky = commandQueue.commandBuffer()
- commandBufferSky.addCompletedHandler{ [weak self] commandBufferSky in
- if let strongSelf = self {
- dispatch_semaphore_signal(strongSelf.inflightSemaphore)
- }
- return
- }
- //Model
- var modelMatrixTransModel = M4f()
- var modelMatrixRotModel = M4f()
- var modelMatrixScaleModel = M4f()
- modelMatrixTransModel = translate(0, y: 0, z: 0)
- modelMatrixRotModel = rotate(0, r: V3f(1,0,0))
- modelMatrixScaleModel = scaling(10, y: 10, z: 10)
- let modelMatrixModel = modelMatrixTransModel * modelMatrixRotModel * modelMatrixScaleModel
- var viewMatrixModel = M4f()
- viewMatrixModel = myCamera.setLookAt(viewMatrixModel)
- let modelViewMatrixModel = viewMatrixModel * modelMatrixModel
- let matricesModel = [projectionMatrix, modelViewMatrixModel]
- memcpy(uniformBufferModel.contents(), matricesModel, Int(sizeof(M4f) * 2))
- //Sky
- let passDescriptor = MTLRenderPassDescriptor()
- passDescrForSky(passDescriptor, drawable: drawable)
- passDescrForModel(passDescriptor, drawable: drawable)
- //Sky
- let commandEncoderSky = commandBufferSky.renderCommandEncoderWithDescriptor(passDescriptor)
- commandEncoderSky.setRenderPipelineState(pipelineSky)
- commandEncoderSky.setDepthStencilState(depthStencilState)
- commandEncoderSky.setFrontFacingWinding(.CounterClockwise)
- commandEncoderSky.setCullMode(.Back)
- pointCloudDraw(commandEncoderSky)
- skyDraw(commandEncoderSky)
- commandEncoderSky.endEncoding()
- commandBufferSky.presentDrawable(drawable)
- // bufferIndex matches the current semaphore controled frame index to ensure writing occurs at the correct region in the vertex buffer
- bufferIndex = (bufferIndex + 1) % MaxBuffers
- commandBufferSky.commit()
- }
- }
- func passDescrForModel(passDescriptor: MTLRenderPassDescriptor, drawable: CAMetalDrawable) -> MTLRenderPassDescriptor{
- passDescriptor.colorAttachments[0].texture = drawable.texture
- passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1)
- passDescriptor.colorAttachments[0].loadAction = .Clear
- passDescriptor.colorAttachments[0].storeAction = .Store
- return passDescriptor
- }
- func passDescrForSky(passDescriptor: MTLRenderPassDescriptor, drawable: CAMetalDrawable) -> MTLRenderPassDescriptor{
- passDescriptor.colorAttachments[0].texture = drawable.texture
- passDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.5, 0.5, 0.5, 1)
- passDescriptor.colorAttachments[0].loadAction = .Clear
- passDescriptor.colorAttachments[0].storeAction = .Store
- passDescriptor.depthAttachment.texture = depthTextureSky
- passDescriptor.depthAttachment.clearDepth = 1
- passDescriptor.depthAttachment.loadAction = .Clear
- passDescriptor.depthAttachment.storeAction = .DontCare
- return passDescriptor
- }
- func pointCloudDraw(commandencodeModel: MTLRenderCommandEncoder) {
- commandencodeModel.setVertexBuffer(vertexBufferModel, offset:0, atIndex:0)
- commandencodeModel.setVertexBuffer(normalBufferModel, offset:0, atIndex:1)
- commandencodeModel.setVertexBuffer(colorBufferModel, offset:0, atIndex:2)
- commandencodeModel.setVertexBuffer(uniformBufferModel, offset:0, atIndex:3)
- commandencodeModel.setFragmentBuffer(uniformBufferModel, offset: 0, atIndex: 0)
- commandencodeModel.drawPrimitives(.Point, vertexStart: 0, vertexCount: vertextCountModel)
- }
- func skyDraw(commandencodeSky: MTLRenderCommandEncoder) {
- commandencodeSky.setVertexBuffer(vertexBufferSky, offset:0, atIndex:0)
- commandencodeSky.setVertexBuffer(uniformBufferSky, offset:0, atIndex:1)
- commandencodeSky.setFragmentTexture(diffuseTextureSky, atIndex: 0)
- commandencodeSky.setFragmentSamplerState(samplerStateSky, atIndex: 0)
- commandencodeSky.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: vertexCountSky)
- }
Add Comment
Please, Sign In to add comment