Get marching squares rendering a grid!

This commit is contained in:
Eryn Wells 2018-10-14 12:16:43 -07:00
parent b2f19dffbf
commit 8dc11d89d5

View file

@ -11,13 +11,14 @@ import Metal
class MarchingSquares { class MarchingSquares {
private var field: Field private var field: Field
private var sampleGridSize: Size private var sampleGridSize = Size(16)
/// Samples of the field's current state. /// Samples of the field's current state.
private(set) var samples: MTLTexture? private(set) var samples: MTLTexture?
/// Indexes of geometry to render. /// Indexes of geometry to render.
private(set) var indexes: MTLTexture? private(set) var indexes: MTLTexture?
private var lastGridCount: Int = 0
private(set) var gridGeometry: MTLBuffer? private(set) var gridGeometry: MTLBuffer?
private var xSamples: Int { private var xSamples: Int {
@ -28,83 +29,73 @@ class MarchingSquares {
return Int(field.size.y / sampleGridSize.y) return Int(field.size.y / sampleGridSize.y)
} }
private var xGridlinesCount: Int { var samplesCount: Int {
let xSamples = Int(field.size.x / sampleGridSize.x) return xSamples * ySamples
return xSamples - 1
}
private var yGridlinesCount: Int {
let ySamples = Int(field.size.y / sampleGridSize.y)
return ySamples - 1
}
var gridVertexCount: Int {
return xGridlinesCount * 2 + yGridlinesCount * 2
} }
init(field: Field) { init(field: Field) {
self.field = field self.field = field
sampleGridSize = Size(16)
} }
func setupMetal(withDevice device: MTLDevice) { func setupMetal(withDevice device: MTLDevice) {
guard xSamples > 1 && ySamples > 1 else { // let samplesDesc = MTLTextureDescriptor()
return // samplesDesc.textureType = .type2D
} // samplesDesc.width = xSamples
// samplesDesc.height = ySamples
let samplesDesc = MTLTextureDescriptor() // samplesDesc.pixelFormat = .r32Float
samplesDesc.textureType = .type2D // samples = device.makeTexture(descriptor: samplesDesc)
samplesDesc.width = xSamples //
samplesDesc.height = ySamples // let indexesDesc = MTLTextureDescriptor()
samplesDesc.pixelFormat = .r32Float // indexesDesc.textureType = .type2D
samples = device.makeTexture(descriptor: samplesDesc) // indexesDesc.width = xSamples - 1
// indexesDesc.height = ySamples - 1
let indexesDesc = MTLTextureDescriptor() // indexesDesc.pixelFormat = .a8Unorm
indexesDesc.textureType = .type2D // indexes = device.makeTexture(descriptor: indexesDesc)
indexesDesc.width = xSamples - 1
indexesDesc.height = ySamples - 1
indexesDesc.pixelFormat = .a8Unorm
indexes = device.makeTexture(descriptor: indexesDesc)
let gridGeometryLength = MemoryLayout<Vertex>.stride * gridVertexCount
gridGeometry = device.makeBuffer(length: gridGeometryLength, options: .storageModeShared)
populateGridGeometryBuffer()
} }
func fieldDidResize() { func fieldDidResize() {
guard let gridGeometry = gridGeometry else { guard let gridGeometry = gridGeometry else {
return return
} }
let gridGeometryLength = MemoryLayout<Vertex>.stride * gridVertexCount createGridGeometryBuffer(withDevice: gridGeometry.device)
self.gridGeometry = gridGeometry.device.makeBuffer(length: gridGeometryLength, options: .storageModeShared) populateGrid(withDevice: gridGeometry.device)
populateGridGeometryBuffer()
} }
private func populateGridGeometryBuffer() { func populateGrid(withDevice device: MTLDevice) {
guard let gridGeometry = gridGeometry else { guard lastGridCount != samplesCount else {
return return
} }
print("Rebuilding gridlines") print("Populating grid with (\(xSamples), \(ySamples)) samples")
var vertices = [Vertex]() let gridSizeX = Float(sampleGridSize.x)
let gridSizeY = Float(sampleGridSize.y)
let fieldSizeX = Float(field.size.x) var grid = [Rect]()
let fieldSizeY = Float(field.size.y) grid.reserveCapacity(samplesCount)
for x in 1..<xSamples { for y in 0..<ySamples {
let xCoord = Float(x * Int(sampleGridSize.x)) for x in 0..<xSamples {
vertices.append(Vertex(position: Float2(xCoord, 0), textureCoordinate: Float2())) let transform = Matrix4x4.translation(dx: Float(x) * gridSizeX, dy: Float(y) * gridSizeY, dz: 0.0) * Matrix4x4.scale(x: gridSizeX, y: gridSizeY, z: 1)
vertices.append(Vertex(position: Float2(xCoord, fieldSizeY), textureCoordinate: Float2())) let rect = Rect(transform: transform, color: Float4(1.0))
grid.append(rect)
}
} }
for y in 1..<ySamples { if let buffer = device.makeBuffer(length: MemoryLayout<Rect>.stride * samplesCount, options: .storageModeShared) {
let yCoord = Float(y * Int(sampleGridSize.y)) memcpy(buffer.contents(), grid, MemoryLayout<Rect>.stride * grid.count)
vertices.append(Vertex(position: Float2(0, yCoord), textureCoordinate: Float2())) gridGeometry = buffer
vertices.append(Vertex(position: Float2(fieldSizeX, yCoord), textureCoordinate: Float2())) } else {
fatalError("Couldn't create buffer for grid rects")
} }
memcpy(gridGeometry.contents(), vertices, MemoryLayout<Vertex>.stride * vertices.count) lastGridCount = samplesCount
}
private func createGridGeometryBuffer(withDevice device: MTLDevice) {
// Allocate a buffer with enough space for the rect vertex data, and all the rect instances we need to render.
// [rect] [rect] ...
} }
func sampleField() { func sampleField() {