2016-04-21 89 views
5

如何將基元渲染成離屏紋理,而不是直接進入屏幕?多重取樣金屬離屏繪圖

我有一套三角形和相應的顏色,我只想繪製它們,就像我做屏幕一樣,但是進入屏幕外的紋理,我可以保存到一個文件中。

任何人都可以告訴我一個代碼示例嗎?

+1

你有什麼嘗試?在Metal中,所有渲染都是通過紋理完成的;唯一的區別是您是否繪製到包含在繪製中的貼圖中,然後將其呈現給屏幕,或者是您自己管理的紋理。如果要繪製到後者,只需創建一個適當大小和格式的「MTLTexture」,並將其設置爲渲染通道描述符的第一個顏色附件的紋理。然後,您可以使用getBytes API獲取圖像數據並將其寫出。 – warrenm

+0

看看我的代碼,我已經更新了這個問題 – s1ddok

+0

我想我的問題是我的座標是錯誤的,也許我應該設置視口或者自定義投影...... – s1ddok

回答

4

好的,我自己意識到了。此代碼完成這項工作,只是它繪製了太大的三角形,但對於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變量。

+1

我巧合地今天有這個相同的問題,但仍然有奇怪的問題。我認爲解決我自己的問題的方法是使用.MultisampleResolve,但outTexture描述符的設置是什麼? –