Extract Terrain into its own class
This commit is contained in:
parent
ee2431d9c4
commit
5fa89d1e47
3 changed files with 89 additions and 62 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue