mirror of
https://github.com/GayPizzaSpecifications/voxelotl-engine.git
synced 2025-08-02 13:00:53 +00:00
model batch untz untz untz
This commit is contained in:
parent
54ed81b15d
commit
34ec6f71eb
@ -1,5 +1,4 @@
|
||||
|
||||
public struct Material {
|
||||
public struct Material: Hashable {
|
||||
public var ambient: Color<Float>
|
||||
public var diffuse: Color<Float>
|
||||
public var specular: Color<Float>
|
||||
|
@ -5,35 +5,67 @@ public struct ModelBatch {
|
||||
private var _active = false
|
||||
private var _cam: Camera!
|
||||
private var _env: Environment!
|
||||
private var _prev: ModelInstance!
|
||||
private var _instances: [Instance]
|
||||
|
||||
internal init(_ renderer: Renderer) {
|
||||
self._renderer = renderer
|
||||
self._instances = Array()
|
||||
}
|
||||
|
||||
//TODO: Sort, Blend
|
||||
mutating func begin(camera: Camera, environment: Environment) {
|
||||
public mutating func begin(camera: Camera, environment: Environment) {
|
||||
self._active = true
|
||||
self._cam = camera
|
||||
self._env = environment
|
||||
self._prev = nil
|
||||
}
|
||||
|
||||
mutating func end() {
|
||||
private mutating func flush() {
|
||||
assert(self._instances.count > 0)
|
||||
if self._instances.count == 1 {
|
||||
let instance = self._instances.first!
|
||||
self._renderer.draw(
|
||||
model: instance.world,
|
||||
color: instance.color,
|
||||
mesh: self._prev.mesh,
|
||||
material: self._prev.material,
|
||||
environment: self._env,
|
||||
camera: self._cam)
|
||||
} else {
|
||||
self._renderer.batch(
|
||||
instances: self._instances,
|
||||
mesh: self._prev.mesh,
|
||||
material: self._prev.material,
|
||||
environment: self._env,
|
||||
camera: self._cam)
|
||||
}
|
||||
self._instances.removeAll(keepingCapacity: true)
|
||||
self._prev = nil
|
||||
}
|
||||
|
||||
public mutating func end() {
|
||||
if !self._instances.isEmpty {
|
||||
self.flush()
|
||||
}
|
||||
self._cam = nil
|
||||
self._env = nil
|
||||
self._active = false
|
||||
}
|
||||
|
||||
mutating func draw(_ model: ModelInstance, position: SIMD3<Float>, color: Color<Float> = .white
|
||||
public mutating func draw(_ model: ModelInstance, position: SIMD3<Float>, color: Color<Float> = .white
|
||||
) {
|
||||
self.draw(model, world: .translate(position), color: color)
|
||||
}
|
||||
|
||||
mutating func draw(_ model: ModelInstance,
|
||||
public mutating func draw(_ model: ModelInstance,
|
||||
position: SIMD3<Float>, scale: Float, rotation: simd_quatf,
|
||||
color: Color<Float> = .white
|
||||
) {
|
||||
self.draw(model, position: position, scale: .init(repeating: scale), rotation: rotation, color: color)
|
||||
}
|
||||
|
||||
mutating func draw(_ model: ModelInstance,
|
||||
public mutating func draw(_ model: ModelInstance,
|
||||
position: SIMD3<Float>, scale: SIMD3<Float>, rotation: simd_quatf,
|
||||
color: Color<Float> = .white
|
||||
) {
|
||||
@ -44,30 +76,33 @@ public struct ModelBatch {
|
||||
self.draw(model, world: world, color: color)
|
||||
}
|
||||
|
||||
mutating func draw(_ model: ModelInstance, world: simd_float4x4, color: Color<Float> = .white) {
|
||||
public mutating func draw(_ model: ModelInstance, world: simd_float4x4, color: Color<Float> = .white) {
|
||||
assert(self._active)
|
||||
self._renderer.draw(
|
||||
model: world,
|
||||
color: color.linear,
|
||||
mesh: model.mesh,
|
||||
material: model.material,
|
||||
environment: self._env,
|
||||
camera: self._cam)
|
||||
if self._prev == nil {
|
||||
self._prev = model
|
||||
} else if model != self._prev {
|
||||
self.flush()
|
||||
self._prev = model
|
||||
}
|
||||
|
||||
self._instances.append(.init(
|
||||
world: world,
|
||||
color: color.linear))
|
||||
}
|
||||
|
||||
internal struct Instance {
|
||||
let model: simd_float4x4
|
||||
let world: simd_float4x4
|
||||
let color: Color<Float>
|
||||
|
||||
init(model: simd_float4x4, color: Color<Float> = .white) {
|
||||
self.model = model
|
||||
init(world: simd_float4x4, color: Color<Float> = .white) {
|
||||
self.world = world
|
||||
self.color = color
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: delet
|
||||
public struct ModelInstance {
|
||||
public struct ModelInstance: Hashable {
|
||||
let mesh: RendererMesh
|
||||
let material: Material
|
||||
}
|
||||
|
@ -452,8 +452,8 @@ public class Renderer {
|
||||
for i in 0..<numInstances {
|
||||
let instance = instances[i]
|
||||
data[i] = VertexShaderInstance(
|
||||
model: instance.model,
|
||||
normalModel: instance.model.inverse.transpose,
|
||||
model: instance.world,
|
||||
normalModel: instance.world.inverse.transpose,
|
||||
color: SIMD4(instance.color))
|
||||
}
|
||||
}
|
||||
@ -487,10 +487,21 @@ public class Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
public struct RendererMesh {
|
||||
fileprivate let _vertBuf: MTLBuffer
|
||||
fileprivate let _idxBuf: MTLBuffer
|
||||
public struct RendererMesh: Hashable {
|
||||
fileprivate let _vertBuf: MTLBuffer, _idxBuf: MTLBuffer
|
||||
public let numIndices: Int
|
||||
|
||||
public static func == (lhs: Self, rhs: Self) -> Bool {
|
||||
lhs._vertBuf.gpuAddress == rhs._vertBuf.gpuAddress && lhs._vertBuf.length == rhs._vertBuf.length &&
|
||||
lhs._vertBuf.gpuAddress == rhs._vertBuf.gpuAddress && lhs._vertBuf.length == rhs._vertBuf.length &&
|
||||
lhs.numIndices == rhs.numIndices
|
||||
}
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(self._vertBuf.hash)
|
||||
hasher.combine(self._idxBuf.hash)
|
||||
hasher.combine(self.numIndices)
|
||||
}
|
||||
}
|
||||
|
||||
extension MTLClearColor {
|
||||
|
Loading…
Reference in New Issue
Block a user