具有多采样功能的金属屏外工程图 [英] Metal off-screen drawing with Multi-Sampling

查看:122
本文介绍了具有多采样功能的金属屏外工程图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How do I render primitives into off screen texture, not directly into the screen?

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

I have a set of triangles and corresponding color, I just want to draw them the same way I do to screen, but into off screen texture, that I can save into a file.

有人可以给我看一下代码示例吗?

Can anybody show me a code sample of that?

推荐答案

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

Ok, I realized it myself. This code does the job, with only exception that it draw too huge triangles, but that is a different topic for Vertex function.

这是我的代码:

    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变量中.

You image now is in outTexture variable.

这篇关于具有多采样功能的金属屏外工程图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆