So, there are a number of Metal tutorials. Apple has zero of them updated to Swift 3. And zero of them updated to the version of Metal that is available in Swift 3.
So third parties are the only place to go. But... none of the third party tutorials do anything even remotely similarly.
I am at the point where I am trying to refactor a working HelloTriangle example. I am trying to follow along with code that is no longer valid (swift 2 or 1) and DID NOT WORK. Why am I following along with that code? because the code that does work, doesn't take it any further. So, learning is fractured, just be aware of that.
I am making a class that draws a triangle this is so simple, and yet it doesn't draw anything, and there is no indication why.
the view delegate, which works is this:
/*code from elsewhere that defines the buffers.
let floatPos : [Float] = [-1.0, -1.0, 0.0, 1.0,
1.0, -1.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0]
let colors : [Float] = [1,0,0,1,0,1,0,1,0,0,1,1]
posBuffer = view.device?.makeBuffer(bytes: floatPos, length: floatPos.count * MemoryLayout<Float>.stride, options: .storageModeShared)
colorBuffer = view.device?.makeBuffer(bytes: colors, length: colors.count * MemoryLayout<Float>.stride , options: .storageModeShared)
*/
func draw(in view: MTKView){
if let drawable = view.currentDrawable{
if let passDescriptor = view.currentRenderPassDescriptor{
let cmndQueue = view.device?.makeCommandQueue()
let cmdBuff = cmndQueue?.makeCommandBuffer()
let cmdEncoder = cmdBuff?.makeRenderCommandEncoder(descriptor: passDescriptor)
cmdEncoder?.setRenderPipelineState(renderPipelineState!)
cmdEncoder?.setVertexBuffer(posBuffer, offset: 0, at: 0)
cmdEncoder?.setVertexBuffer(colorBuffer, offset: 0, at: 1)
cmdEncoder?.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1)
cmdEncoder?.endEncoding()
cmdBuff?.present(drawable)
cmdBuff?.commit()
}
}
}
refactoring that triangle into a class, suggests that the triangle class needs to be passed the : command Queue, pipelineState, drawable, and clear color, so that it can make it's own command encoder and command buffer.
to me, in the vaccuum of no information, it seems to be an overweight need. But I tried it. And it doesn't render anything, instead it ***** out for a variety of reasons, which are related to the lack of a tutorial that works with swift 3 and refactors the code.
next I tried, just passing an already built command encoder, running only this code in my triangle class's draw func:
cmdEncoder.setVertexBuffer(vertexBuff, offset: 0, at: 0)
cmdEncoder.setVertexBuffer(colorBuff, offset: 0, at: 1)
cmdEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: vertCount, instanceCount: vertCount/3)
you can assume that the two vertex buffers are exactly the same code, as before.
we don't get sigbarts, but we also do not get any triangles.
so next i tried to synthesize a version of the tutorial's approach, while making adjustments to make it work in swift 3 and with the approach from another tutorial:
func draw(_ commandQueue : MTLCommandQueue, _ drawable: MTLDrawable , _ renderPassDescriptor : MTLRenderPassDescriptor, _ renderPipelineState : MTLRenderPipelineState?){
let commandBuffer = commandQueue.makeCommandBuffer()
let cmdEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)
cmdEncoder.setRenderPipelineState(renderPipelineState!)
if vertCount > 0{
cmdEncoder.setVertexBuffer(vertexBuff, offset: 0, at: 0)
cmdEncoder.setVertexBuffer(colorBuff, offset: 0, at: 1)
cmdEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: vertCount, instanceCount: vertCount/3)
}
cmdEncoder.endEncoding()
commandBuffer.present(drawable)
commandBuffer.commit()
}
}
I added a check to make sure we were getting vertex data (if vertCount >0)
again: no triangles are drawn. no errors thrown. No tutorial that explains any of this in plain english.
I get it, we need to encapsulate and transport render commands to the GPU. it's a bit of a miracle and it's awesome. What i don't get is : why the exact same code, restructured slightly, does not work. I'm sure I am misunderstanding something. I just need help figuring out what that is.