金属渲染有2个管道,第二个对象与第一个对象重叠

时间:2016-06-15 21:34:49

标签: metal

我有2个物体,一个是纹理,另一个是没有纹理。我使用2个着色器,我使用2个渲染管道来绘制2个对象。 2对象绘制得很好......但是当绘制第二个对象时...它与第一个对象重叠,所以屏幕上只有第二个对象...不知道哪里出错...也许是因为在draw()函数的最后部分,管道未正确使用。该模型首先正确绘制,但当天空画出时,模型消失了......请帮帮我,,,谢谢 这是我的代码:

    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)

    }
}    

1 个答案:

答案 0 :(得分:0)

更改passDescrForSky函数concatenatedMessage 然后两个对象都显示出来......位置发生了一些事情......第一个需要调整......