【发布时间】:2016-02-10 11:52:15
【问题描述】:
我关注this tutorial,从 iOS 推断到 OS X,一切都编译得很好,除了我没有得到任何渲染(甚至是清晰的颜色)而没有任何错误。任何人都可以看看并告诉我我在这里做错了什么吗?我无法像教程中那样在 iOS 上进行测试,因为 iOS 模拟器还不支持 Metal。
我有一个金属渲染的自定义视图。 我没有添加子层(如教程中所示),因为该层是 nil。我想我需要以某种方式激活它,但我不知道该怎么做。
import Cocoa
import Metal
import QuartzCore
class MetalView: NSView {
var device: MTLDevice!
var pipelineState: MTLRenderPipelineState!
var commandQueue: MTLCommandQueue!
var renderPassDescriptor: MTLRenderPassDescriptor!
var vertexBuffer: MTLBuffer!
var drawable: CAMetalDrawable {
return (layer as! CAMetalLayer).nextDrawable()!
}
override func awakeFromNib() {
// Device
device = MTLCreateSystemDefaultDevice()
// Layer
let metalLayer = CAMetalLayer()
metalLayer.device = device
metalLayer.pixelFormat = .BGRA8Unorm
metalLayer.framebufferOnly = true
metalLayer.frame = frame
layer = metalLayer
// Pipeline State
let defaultLibrary = device.newDefaultLibrary()
let fragmentProgram = defaultLibrary!.newFunctionWithName("basic_fragment")
let vertexProgram = defaultLibrary!.newFunctionWithName("basic_vertex")
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
pipelineStateDescriptor.vertexFunction = vertexProgram
pipelineStateDescriptor.fragmentFunction = fragmentProgram
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .BGRA8Unorm
do
{
try pipelineState = device.newRenderPipelineStateWithDescriptor(pipelineStateDescriptor)
}
catch let error as NSError {
NSLog("Failed to create pipeline state, error \(error)")
}
// Command Queue
commandQueue = device.newCommandQueue()
// Render Pass Descriptor
renderPassDescriptor = MTLRenderPassDescriptor()
renderPassDescriptor.colorAttachments[0].texture = drawable.texture
renderPassDescriptor.colorAttachments[0].loadAction = .Clear
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(red: 0.75, green: 0.5, blue: 0.0, alpha: 1.0)
// Vertex Buffer
let vertexData:[Float] = [
0.0, 1.0, 0.0,
-1.0, -1.0, 0.0,
1.0, -1.0, 0.0
]
vertexBuffer = device.newBufferWithBytes(vertexData, length: vertexData.count * sizeofValue(vertexData[0]), options: MTLResourceOptions())
}
override func drawRect(dirtyRect: NSRect) {
let commandBuffer = commandQueue.commandBuffer()
let renderEncoder = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor)
renderEncoder.setRenderPipelineState(pipelineState)
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, atIndex: 0)
renderEncoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1)
renderEncoder.endEncoding()
commandBuffer.presentDrawable(drawable)
commandBuffer.commit()
}
}
我有以下着色器代码:
#include <metal_stdlib>
using namespace metal;
struct VertexIn
{
packed_float3 position;
};
vertex float4 basic_vertex(
const device VertexIn* vertex_array [[ buffer(0) ]],
unsigned int vertex_id [[ vertex_id ]])
{
return float4(vertex_array[vertex_id].position, 1.0);
}
fragment half4 basic_fragment()
{
return half4(1.0);
}
【问题讨论】:
-
对于
OS X,您可以将MetalView设为MTKView的子类,如果您查看我在mhorga.org 博客上的Metal教程,这实际上非常简单。 -
我确实做到了。我有一个 MTKView 的工作示例,我只是想尝试让它在没有它的情况下工作。不过,感谢您的链接!