mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-03 13:11:33 +00:00
move indices to buffers
This commit is contained in:
@ -55,7 +55,9 @@ public class Renderer {
|
|||||||
private let passDescription = MTLRenderPassDescriptor()
|
private let passDescription = MTLRenderPassDescriptor()
|
||||||
private var pso: MTLRenderPipelineState
|
private var pso: MTLRenderPipelineState
|
||||||
private var depthStencilState: MTLDepthStencilState
|
private var depthStencilState: MTLDepthStencilState
|
||||||
|
|
||||||
private var depthTextures: [MTLTexture]
|
private var depthTextures: [MTLTexture]
|
||||||
|
private var _instances: [MTLBuffer?]
|
||||||
|
|
||||||
private var _encoder: MTLRenderCommandEncoder! = nil
|
private var _encoder: MTLRenderCommandEncoder! = nil
|
||||||
|
|
||||||
@ -113,6 +115,8 @@ public class Renderer {
|
|||||||
return depthStencilTexture
|
return depthStencilTexture
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self._instances = [MTLBuffer?](repeating: nil, count: numFramesInFlight)
|
||||||
|
|
||||||
let stencilDepthDescription = MTLDepthStencilDescriptor()
|
let stencilDepthDescription = MTLDepthStencilDescriptor()
|
||||||
stencilDepthDescription.depthCompareFunction = .less // OpenGL default
|
stencilDepthDescription.depthCompareFunction = .less // OpenGL default
|
||||||
stencilDepthDescription.isDepthWriteEnabled = true
|
stencilDepthDescription.isDepthWriteEnabled = true
|
||||||
@ -340,7 +344,6 @@ public class Renderer {
|
|||||||
|
|
||||||
func batch(instances: [Instance], camera: Camera) {
|
func batch(instances: [Instance], camera: Camera) {
|
||||||
assert(self._encoder != nil, "batch can't be called outside of a frame being rendered")
|
assert(self._encoder != nil, "batch can't be called outside of a frame being rendered")
|
||||||
assert(instances.count < 28)
|
|
||||||
|
|
||||||
var vertUniforms = VertexShaderUniforms(projView: camera.viewProjection)
|
var vertUniforms = VertexShaderUniforms(projView: camera.viewProjection)
|
||||||
var fragUniforms = FragmentShaderUniforms(
|
var fragUniforms = FragmentShaderUniforms(
|
||||||
@ -350,20 +353,42 @@ public class Renderer {
|
|||||||
diffuseColor: SIMD4(Color(rgba8888: 0xEFEFEF00).linear),
|
diffuseColor: SIMD4(Color(rgba8888: 0xEFEFEF00).linear),
|
||||||
specularColor: SIMD4(Color(rgba8888: 0x7F7F7F00).linear),
|
specularColor: SIMD4(Color(rgba8888: 0x7F7F7F00).linear),
|
||||||
specularIntensity: 50)
|
specularIntensity: 50)
|
||||||
let instances = instances.map { (instance: Instance) -> VertexShaderInstance in
|
|
||||||
|
let numInstances = instances.count
|
||||||
|
let instancesBytes = numInstances * MemoryLayout<VertexShaderInstance>.stride
|
||||||
|
|
||||||
|
// (Re)create instance buffer if needed
|
||||||
|
if self._instances[self.currentFrame] == nil || numInstances > self._instances[self.currentFrame]!.length {
|
||||||
|
guard let instanceBuffer = self.device.makeBuffer(
|
||||||
|
length: instancesBytes,
|
||||||
|
options: .storageModeManaged)
|
||||||
|
else {
|
||||||
|
fatalError("Failed to (re)create instance buffer")
|
||||||
|
}
|
||||||
|
self._instances[self.currentFrame] = instanceBuffer
|
||||||
|
}
|
||||||
|
let instanceBuffer = self._instances[self.currentFrame]!
|
||||||
|
|
||||||
|
// Convert & upload instance data to the GPU
|
||||||
|
//FIXME: currently will misbehave if batch is called more than once
|
||||||
|
instanceBuffer.contents().withMemoryRebound(to: VertexShaderInstance.self, capacity: numInstances) { data in
|
||||||
|
for i in 0..<numInstances {
|
||||||
|
let instance = instances[i]
|
||||||
let model =
|
let model =
|
||||||
.translate(instance.position) *
|
.translate(instance.position) *
|
||||||
matrix_float4x4(instance.rotation) *
|
matrix_float4x4(instance.rotation) *
|
||||||
.scale(instance.scale)
|
.scale(instance.scale)
|
||||||
return VertexShaderInstance(
|
data[i] = VertexShaderInstance(
|
||||||
model: model, normalModel: model.inverse.transpose,
|
model: model, normalModel: model.inverse.transpose,
|
||||||
color: SIMD4(Color<UInt8>(instance.color)))
|
color: SIMD4(Color<UInt8>(instance.color)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
instanceBuffer.didModifyRange(0..<instancesBytes)
|
||||||
|
|
||||||
// Ideal as long as our uniforms total 4 KB or less
|
self._encoder.setVertexBuffer(instanceBuffer,
|
||||||
self._encoder.setVertexBytes(instances,
|
offset: 0,
|
||||||
length: instances.count * MemoryLayout<VertexShaderInstance>.stride,
|
|
||||||
index: VertexShaderInputIdx.instance.rawValue)
|
index: VertexShaderInputIdx.instance.rawValue)
|
||||||
|
// Ideal as long as our uniforms total 4 KB or less
|
||||||
self._encoder.setVertexBytes(&vertUniforms,
|
self._encoder.setVertexBytes(&vertUniforms,
|
||||||
length: MemoryLayout<VertexShaderUniforms>.stride,
|
length: MemoryLayout<VertexShaderUniforms>.stride,
|
||||||
index: VertexShaderInputIdx.uniforms.rawValue)
|
index: VertexShaderInputIdx.uniforms.rawValue)
|
||||||
@ -377,7 +402,7 @@ public class Renderer {
|
|||||||
indexType: .uint16,
|
indexType: .uint16,
|
||||||
indexBuffer: idxBuffer,
|
indexBuffer: idxBuffer,
|
||||||
indexBufferOffset: 0,
|
indexBufferOffset: 0,
|
||||||
instanceCount: instances.count)
|
instanceCount: numInstances)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user