diff --git a/MetaballsKit/MarchingSquares.swift b/MetaballsKit/MarchingSquares.swift index 81092ba..5be37f6 100644 --- a/MetaballsKit/MarchingSquares.swift +++ b/MetaballsKit/MarchingSquares.swift @@ -11,13 +11,14 @@ import Metal class MarchingSquares { private var field: Field - private var sampleGridSize: Size + private var sampleGridSize = Size(16) /// Samples of the field's current state. private(set) var samples: MTLTexture? /// Indexes of geometry to render. private(set) var indexes: MTLTexture? + private var lastGridCount: Int = 0 private(set) var gridGeometry: MTLBuffer? private var xSamples: Int { @@ -28,83 +29,73 @@ class MarchingSquares { return Int(field.size.y / sampleGridSize.y) } - private var xGridlinesCount: Int { - let xSamples = Int(field.size.x / sampleGridSize.x) - 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 + var samplesCount: Int { + return xSamples * ySamples } init(field: Field) { self.field = field - sampleGridSize = Size(16) } func setupMetal(withDevice device: MTLDevice) { - guard xSamples > 1 && ySamples > 1 else { - return - } - - let samplesDesc = MTLTextureDescriptor() - samplesDesc.textureType = .type2D - samplesDesc.width = xSamples - samplesDesc.height = ySamples - samplesDesc.pixelFormat = .r32Float - samples = device.makeTexture(descriptor: samplesDesc) - - let indexesDesc = MTLTextureDescriptor() - indexesDesc.textureType = .type2D - indexesDesc.width = xSamples - 1 - indexesDesc.height = ySamples - 1 - indexesDesc.pixelFormat = .a8Unorm - indexes = device.makeTexture(descriptor: indexesDesc) - - let gridGeometryLength = MemoryLayout.stride * gridVertexCount - gridGeometry = device.makeBuffer(length: gridGeometryLength, options: .storageModeShared) - populateGridGeometryBuffer() +// let samplesDesc = MTLTextureDescriptor() +// samplesDesc.textureType = .type2D +// samplesDesc.width = xSamples +// samplesDesc.height = ySamples +// samplesDesc.pixelFormat = .r32Float +// samples = device.makeTexture(descriptor: samplesDesc) +// +// let indexesDesc = MTLTextureDescriptor() +// indexesDesc.textureType = .type2D +// indexesDesc.width = xSamples - 1 +// indexesDesc.height = ySamples - 1 +// indexesDesc.pixelFormat = .a8Unorm +// indexes = device.makeTexture(descriptor: indexesDesc) } func fieldDidResize() { guard let gridGeometry = gridGeometry else { return } - let gridGeometryLength = MemoryLayout.stride * gridVertexCount - self.gridGeometry = gridGeometry.device.makeBuffer(length: gridGeometryLength, options: .storageModeShared) - populateGridGeometryBuffer() + createGridGeometryBuffer(withDevice: gridGeometry.device) + populateGrid(withDevice: gridGeometry.device) } - private func populateGridGeometryBuffer() { - guard let gridGeometry = gridGeometry else { + func populateGrid(withDevice device: MTLDevice) { + guard lastGridCount != samplesCount else { 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) - let fieldSizeY = Float(field.size.y) + var grid = [Rect]() + grid.reserveCapacity(samplesCount) - for x in 1...stride * samplesCount, options: .storageModeShared) { + memcpy(buffer.contents(), grid, MemoryLayout.stride * grid.count) + gridGeometry = buffer + } else { + fatalError("Couldn't create buffer for grid rects") } - memcpy(gridGeometry.contents(), vertices, MemoryLayout.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() {