采用多采样的金属离屏绘图

时间:2016-04-21 15:07:44

标签: ios objective-c swift metal

如何将基元渲染到屏幕外纹理中,而不是直接渲染到屏幕上?

我有一组三角形和相应的颜色,我只想绘制它们的方式与屏幕相同,但是在屏幕外纹理中,我可以保存到文件中。

有人能告诉我一个代码示例吗?

1 个答案:

答案 0 :(得分:5)

好的,我自己也意识到了。这段代码完成了这项工作,唯一的例外是它绘制了太大的三角形,但这是Vertex函数的另一个主题。

这是我的代码:

    let fragmentProgram = defaultLibrary.newFunctionWithName("image_fragmentT")
    let vertexProgram = defaultLibrary.newFunctionWithName("image_vertexT")


    struct VertexT {
        var x, y, z, w : Float
        var r, g, b, a : Float
    }

    let vertexDescriptor = MTLVertexDescriptor()
    vertexDescriptor.attributes[0].offset = 0
    vertexDescriptor.attributes[0].format = .Float4
    vertexDescriptor.attributes[0].bufferIndex = 0

    vertexDescriptor.attributes[1].offset = 0
    vertexDescriptor.attributes[1].format = .Float4
    vertexDescriptor.attributes[1].bufferIndex = 0

    vertexDescriptor.layouts[0].stepFunction = .PerVertex
    vertexDescriptor.layouts[0].stride = sizeof(VertexT)

    let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
    pipelineStateDescriptor.vertexDescriptor = vertexDescriptor
    pipelineStateDescriptor.vertexFunction = vertexProgram
    pipelineStateDescriptor.fragmentFunction = fragmentProgram
    pipelineStateDescriptor.colorAttachments[0].pixelFormat = .RGBA8Unorm;
    pipelineStateDescriptor.colorAttachments[0].blendingEnabled = true
    pipelineStateDescriptor.sampleCount = 4
    pipelineStateDescriptor.colorAttachments[0].rgbBlendOperation =    MTLBlendOperation.Add
    pipelineStateDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperation.Add
    pipelineStateDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactor.SourceAlpha
    pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactor.SourceAlpha
    pipelineStateDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactor.OneMinusSourceAlpha
    pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactor.OneMinusSourceAlpha


    let sampleDesc = MTLTextureDescriptor()
    sampleDesc.textureType = MTLTextureType.Type2DMultisample
    sampleDesc.width = inTexture.width
    sampleDesc.height = inTexture.height
    sampleDesc.sampleCount = 4
    sampleDesc.pixelFormat = .RGBA8Unorm
    sampleDesc.storageMode = .Private
    sampleDesc.usage = .RenderTarget

    let sampletex = device.device.newTextureWithDescriptor(sampleDesc)
    let renderPassDescriptor = MTLRenderPassDescriptor()

    renderPassDescriptor.colorAttachments[0].texture = sampletex
    renderPassDescriptor.colorAttachments[0].resolveTexture = outTexture
    renderPassDescriptor.colorAttachments[0].loadAction = .Clear
    renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
    renderPassDescriptor.colorAttachments[0].storeAction = .MultisampleResolve

    let renderCB = commandQueue.commandBuffer()

    let renderCommandEncoder = renderCB.renderCommandEncoderWithDescriptor(renderPassDescriptor)
    let pipelineState = try! device.device.newRenderPipelineStateWithDescriptor(pipelineStateDescriptor)
    renderCommandEncoder.setRenderPipelineState(pipelineState)

    let vertexBuf = device.device.newBufferWithLength(triangles.count * 3 * sizeof(VertexT), options: .CPUCacheModeDefaultCache)

    var vBufPointer = [VertexT]()

    for i in 0..<triangles.count {

        // create buffer here
    }

    memcpy(vertexBuf.contents(), &vBufPointer, triangles.count * 3 * sizeof(VertexT))

    renderCommandEncoder.setVertexBuffer(vertexBuf, offset: 0, atIndex: 0)
    renderCommandEncoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: triangles.count * 3)
    renderCommandEncoder.endEncoding()
    renderCB.commit()
    renderCB.waitUntilCompleted()

您现在的图片位于outTexture变量。