Extract Terrain into its own class

This commit is contained in:
Eryn Wells 2018-11-03 15:59:11 -04:00
parent ee2431d9c4
commit 5fa89d1e47
3 changed files with 89 additions and 62 deletions

View file

@ -42,7 +42,7 @@ class Renderer: NSObject, MTKViewDelegate {
var rotation: Float = 0
var mesh: MTKMesh
var terrain: Terrain
init?(metalKitView: MTKView) {
self.device = metalKitView.device!
@ -61,12 +61,12 @@ class Renderer: NSObject, MTKViewDelegate {
metalKitView.colorPixelFormat = MTLPixelFormat.bgra8Unorm_srgb
metalKitView.sampleCount = 1
let mtlVertexDescriptor = Renderer.buildMetalVertexDescriptor()
terrain = Terrain(dimensions: float2(8, 8), segments: uint2(20, 20), device: device)!
do {
pipelineState = try Renderer.buildRenderPipelineWithDevice(device: device,
metalKitView: metalKitView,
mtlVertexDescriptor: mtlVertexDescriptor)
mtlVertexDescriptor: terrain.vertexDescriptor)
} catch {
print("Unable to compile render pipeline state. Error info: \(error)")
return nil
@ -77,13 +77,6 @@ class Renderer: NSObject, MTKViewDelegate {
depthStateDesciptor.isDepthWriteEnabled = true
self.depthState = device.makeDepthStencilState(descriptor:depthStateDesciptor)!
do {
mesh = try Renderer.buildMesh(device: device, mtlVertexDescriptor: mtlVertexDescriptor)
} catch {
print("Unable to build MetalKit Mesh. Error info: \(error)")
return nil
}
do {
colorMap = try Renderer.loadTexture(device: device, textureName: "ColorMap")
} catch {
@ -95,31 +88,6 @@ class Renderer: NSObject, MTKViewDelegate {
}
class func buildMetalVertexDescriptor() -> MTLVertexDescriptor {
// Creete a Metal vertex descriptor specifying how vertices will by laid out for input into our render
// pipeline and how we'll layout our Model IO vertices
let mtlVertexDescriptor = MTLVertexDescriptor()
mtlVertexDescriptor.attributes[VertexAttribute.position.rawValue].format = MTLVertexFormat.float3
mtlVertexDescriptor.attributes[VertexAttribute.position.rawValue].offset = 0
mtlVertexDescriptor.attributes[VertexAttribute.position.rawValue].bufferIndex = BufferIndex.meshPositions.rawValue
mtlVertexDescriptor.attributes[VertexAttribute.texcoord.rawValue].format = MTLVertexFormat.float2
mtlVertexDescriptor.attributes[VertexAttribute.texcoord.rawValue].offset = 0
mtlVertexDescriptor.attributes[VertexAttribute.texcoord.rawValue].bufferIndex = BufferIndex.meshGenerics.rawValue
mtlVertexDescriptor.layouts[BufferIndex.meshPositions.rawValue].stride = 12
mtlVertexDescriptor.layouts[BufferIndex.meshPositions.rawValue].stepRate = 1
mtlVertexDescriptor.layouts[BufferIndex.meshPositions.rawValue].stepFunction = MTLVertexStepFunction.perVertex
mtlVertexDescriptor.layouts[BufferIndex.meshGenerics.rawValue].stride = 8
mtlVertexDescriptor.layouts[BufferIndex.meshGenerics.rawValue].stepRate = 1
mtlVertexDescriptor.layouts[BufferIndex.meshGenerics.rawValue].stepFunction = MTLVertexStepFunction.perVertex
return mtlVertexDescriptor
}
class func buildRenderPipelineWithDevice(device: MTLDevice,
metalKitView: MTKView,
mtlVertexDescriptor: MTLVertexDescriptor) throws -> MTLRenderPipelineState {
@ -144,30 +112,6 @@ class Renderer: NSObject, MTKViewDelegate {
return try device.makeRenderPipelineState(descriptor: pipelineDescriptor)
}
class func buildMesh(device: MTLDevice,
mtlVertexDescriptor: MTLVertexDescriptor) throws -> MTKMesh {
/// Create and condition mesh data to feed into a pipeline using the given vertex descriptor
let metalAllocator = MTKMeshBufferAllocator(device: device)
let plane = MDLMesh.newPlane(withDimensions: float2(6, 6),
segments: uint2(20, 20),
geometryType: .triangles,
allocator: metalAllocator)
let mdlVertexDescriptor = MTKModelIOVertexDescriptorFromMetal(mtlVertexDescriptor)
guard let attributes = mdlVertexDescriptor.attributes as? [MDLVertexAttribute] else {
throw RendererError.badVertexDescriptor
}
attributes[VertexAttribute.position.rawValue].name = MDLVertexAttributePosition
attributes[VertexAttribute.texcoord.rawValue].name = MDLVertexAttributeTextureCoordinate
plane.vertexDescriptor = mdlVertexDescriptor
return try MTKMesh(mesh:plane, device:device)
}
class func loadTexture(device: MTLDevice,
textureName: String) throws -> MTLTexture {
/// Load texture data with optimal parameters for sampling
@ -248,20 +192,20 @@ class Renderer: NSObject, MTKViewDelegate {
renderEncoder.setVertexBuffer(dynamicUniformBuffer, offset:uniformBufferOffset, index: BufferIndex.uniforms.rawValue)
renderEncoder.setFragmentBuffer(dynamicUniformBuffer, offset:uniformBufferOffset, index: BufferIndex.uniforms.rawValue)
for (index, element) in mesh.vertexDescriptor.layouts.enumerated() {
for (index, element) in terrain.mesh.vertexDescriptor.layouts.enumerated() {
guard let layout = element as? MDLVertexBufferLayout else {
return
}
if layout.stride != 0 {
let buffer = mesh.vertexBuffers[index]
let buffer = terrain.mesh.vertexBuffers[index]
renderEncoder.setVertexBuffer(buffer.buffer, offset:buffer.offset, index: index)
}
}
renderEncoder.setFragmentTexture(colorMap, index: TextureIndex.color.rawValue)
for submesh in mesh.submeshes {
for submesh in terrain.mesh.submeshes {
renderEncoder.drawIndexedPrimitives(type: submesh.primitiveType,
indexCount: submesh.indexCount,
indexType: submesh.indexType,