2016-06-15 2 views
2

Ich habe 2 Objekte, eines ist mit Textur, das andere ist ohne Textur. Ich benutze 2 Shader und verwende 2 Render-Pipelines, um die 2 Objekte zu zeichnen. die 2 Objekte sind gut gezeichnet ... aber wenn das zweite Objekt gezeichnet wird ... überlappt es das erste Objekt, so dass nur das zweite Objekt auf dem Bildschirm ist ... weiß nicht wo es schief geht ... Vielleicht wegen der Pipeline wird im letzten Teil der draw() -Funktion nicht richtig verwendet. das Modell richtig zuerst zieht, aber wenn der Himmel ist drew, das Modell verschwunden ... Bitte helfen Sie mir ,,, Dank Hier ist mein Code:Metal Render mit 2 Pipelines, das zweite Objekt überlappen das erste Objekt

class PanoViewController: GameViewController { 
    //sky 
    var depthStencilState: MTLDepthStencilState! = nil 
    var vertexBufferSky: MTLBuffer! = nil 
    var uniformBufferSky: MTLBuffer! = nil 
    var depthTextureSky: MTLTexture! = nil 
    var diffuseTextureSky: MTLTexture! = nil 
    var samplerStateSky: MTLSamplerState! = nil 
    //model 
    var depthStencilStateModel: MTLDepthStencilState! = nil 
    var vertexBufferModel: MTLBuffer! = nil 
    var normalBufferModel: MTLBuffer! = nil 
    var colorBufferModel: MTLBuffer! = nil 
    var uniformBufferModel: MTLBuffer! = nil 

    override func buildPipeline() { 
     //Model 
     let library = device!.newDefaultLibrary()! 
     //pipeline descriptor 
//  buildPipelinForSky(library) 
//  buildPipelineForModel(library) 
     //pipeline 
     do { 
      pipelineSky = try device!.newRenderPipelineStateWithDescriptor(buildPipelinForSky(library)) 
      pipelineModel = try device!.newRenderPipelineStateWithDescriptor(buildPipelineForModel(library)) 

     } catch { 
      print("error with device.newRenderPipelineStateWithDescriptor") 
     } 

     let depthStencilDescriptor = MTLDepthStencilDescriptor() 
     depthStencilDescriptor.depthCompareFunction = .Less 
     depthStencilDescriptor.depthWriteEnabled = true 
     depthStencilState = device!.newDepthStencilStateWithDescriptor(depthStencilDescriptor) 
     commandQueue = device!.newCommandQueue() 

    } 

    func buildPipelineForModel(library: MTLLibrary) -> MTLRenderPipelineDescriptor { 
     let pipeLineDesc = 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(library: MTLLibrary) -> MTLRenderPipelineDescriptor{ 
     let pipeLineDesc = 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.colorAttachments[0].pixelFormat = .BGRA8Unorm 
     pipeLineDesc.depthAttachmentPixelFormat = .Depth32Float 

     let samplerDescriptorSky = MTLSamplerDescriptor() 
     samplerDescriptorSky.minFilter = .Nearest 
     samplerDescriptorSky.magFilter = .Linear 
     samplerStateSky = device!.newSamplerStateWithDescriptor(samplerDescriptorSky) 

     return pipeLineDesc 

    } 

    override func buildResources() { 
     //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) 

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

      //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)) 

      //command buffer 
      let commandBuffer = commandQueue.commandBuffer() 
      commandBuffer.addCompletedHandler{ [weak self] commandBuffer in 
       if let strongSelf = self { 
        dispatch_semaphore_signal(strongSelf.inflightSemaphore) 
       } 
       return 
      } 

      //model 
     var passDescriptor = MTLRenderPassDescriptor() 
     passDescriptor = passDescrForModel(drawable,passDescriptor: passDescriptor) 
     var commandEncoder = commandBuffer.renderCommandEncoderWithDescriptor(passDescriptor) 
     commandEncoder.pushDebugGroup("model pass") 
     commandEncoder.label = "model buffer" 
     pointCloudDraw(commandEncoder) 
     commandEncoder.endEncoding() 
     commandEncoder.popDebugGroup() 

     passDescriptor = passDescrForSky(drawable,passDescriptor: passDescriptor) 
     commandEncoder = commandBuffer.renderCommandEncoderWithDescriptor(passDescriptor) 
     commandEncoder.pushDebugGroup("sky pass") 
     commandEncoder.label = "sky buffer" 
     skyDraw(commandEncoder) 
     commandEncoder.popDebugGroup() 
     commandEncoder.endEncoding() 

     commandBuffer.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 
     commandBuffer.commit() 
     } 
    } 

    func passDescrForModel(drawable: CAMetalDrawable, passDescriptor:MTLRenderPassDescriptor) -> 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(drawable: CAMetalDrawable, passDescriptor:MTLRenderPassDescriptor) -> 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.setRenderPipelineState(pipelineModel) 
     commandencodeModel.setDepthStencilState(depthStencilState) 
     commandencodeModel.setFrontFacingWinding(.CounterClockwise) 
     commandencodeModel.setCullMode(.Back) 
     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.setRenderPipelineState(pipelineSky) 
     commandencodeSky.setDepthStencilState(depthStencilState) 
     commandencodeSky.setFrontFacingWinding(.CounterClockwise) 
     commandencodeSky.setCullMode(.Back) 
     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) 

    } 
}  

Antwort

0

Ändern der passDescrForSky Funktion passDescriptor.colorAttachments[0].loadAction = .Load Dann werden die zwei Objekte alles erscheint ... Etwas passiert mit der Position ... die erste muss angepasst werden ...

Verwandte Themen