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