diff --git a/Sources/UsdView/Hydra/Hydra+RenderEngine.swift b/Sources/UsdView/Hydra/Hydra+RenderEngine.swift index b5e22c4f0..fdb7c52cd 100644 --- a/Sources/UsdView/Hydra/Hydra+RenderEngine.swift +++ b/Sources/UsdView/Hydra/Hydra+RenderEngine.swift @@ -18,19 +18,32 @@ public enum Hydra public class RenderEngine { public var stage: UsdStageRefPtr - public var engine: UsdImagingGL.EngineSharedPtr + + private let hgi: Pixar.HgiMetalPtr + private let engine: UsdImagingGL.EngineSharedPtr public required init(stage: UsdStageRefPtr) { self.stage = stage - engine = UsdImagingGL.Engine.createEngine() + + hgi = HgiMetal.createHgi() + let driver = HdDriver(name: .renderDriver, driver: hgi.value) + + engine = UsdImagingGL.Engine.createEngine( + rootPath: stage.getPseudoRoot().getPath(), + excludedPaths: Sdf.PathVector(), + invisedPaths: Sdf.PathVector(), + sceneDelegateId: Sdf.Path.absoluteRootPath(), + driver: driver + ) } - public func render() + public func render(rgba: (Double, Double, Double, Double)) { var params = UsdImagingGL.RenderParams() + params.frame = Usd.TimeCode.Default() - params.clearColor = .init(0.1, 0.1, 0.1, 1.0) + params.clearColor = .init(Float(rgba.0), Float(rgba.1), Float(rgba.2), Float(rgba.3)) params.enableIdRender = false params.showGuides = false params.showRender = true diff --git a/Sources/UsdView/Hydra/Hydra+View.swift b/Sources/UsdView/Hydra/Hydra+View.swift index a7e0d5af1..b342b20b5 100644 --- a/Sources/UsdView/Hydra/Hydra+View.swift +++ b/Sources/UsdView/Hydra/Hydra+View.swift @@ -33,12 +33,12 @@ public extension Hydra public extension Hydra.Viewport { - init(engine: Hydra.RenderEngine) + init(engine: Hydra.RenderEngine, rgba: (Double, Double, Double, Double)) { #if canImport(Metal) && !os(visionOS) let device = MTLCreateSystemDefaultDevice()! let renderer = Hydra.MTLRenderer(device: device)! - self.init(hydra: engine, device: device, renderer: renderer) + self.init(hydra: engine, device: device, renderer: renderer, rgba: rgba) #endif // canImport(Metal) && !os(visionOS) } } diff --git a/Sources/UsdView/Hydra/MTL/Hydra+MTLRenderer.swift b/Sources/UsdView/Hydra/MTL/Hydra+MTLRenderer.swift index b41ff1195..98fbcdffb 100644 --- a/Sources/UsdView/Hydra/MTL/Hydra+MTLRenderer.swift +++ b/Sources/UsdView/Hydra/MTL/Hydra+MTLRenderer.swift @@ -21,17 +21,17 @@ import PixarUSD class MTLRenderer: NSObject, MTKViewDelegate { private let device: MTLDevice - private let commandQueue: MTLCommandQueue + //private let commandQueue: MTLCommandQueue private var pipelineState: MTLRenderPipelineState? init?(device: MTLDevice) { self.device = device - guard let commandQueue = device.makeCommandQueue() - else { return nil } + // guard let commandQueue = device.makeCommandQueue() + // else { return nil } - self.commandQueue = commandQueue + // self.commandQueue = commandQueue super.init() setupPipeline() @@ -56,16 +56,21 @@ import PixarUSD public func draw(in view: MTKView) { - guard - let drawable = view.currentDrawable, - let renderPassDescriptor = view.currentRenderPassDescriptor, - let pipelineState - else { return } + guard let drawable = view.currentDrawable else { return } + let renderPassDescriptor = view.currentRenderPassDescriptor + + let commandQueue = view.device?.makeCommandQueue() + let commandBuffer = commandQueue?.makeCommandBuffer() - let commandBuffer = commandQueue.makeCommandBuffer() - let renderEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: renderPassDescriptor) + var renderEncoder: (any MTLRenderCommandEncoder)? = nil + if let renderPassDescriptor { + renderEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: renderPassDescriptor) + } + + if let pipelineState { + renderEncoder?.setRenderPipelineState(pipelineState) + } - renderEncoder?.setRenderPipelineState(pipelineState) renderEncoder?.setViewport( MTLViewport( originX: 0.0, diff --git a/Sources/UsdView/Hydra/MTL/Hydra+MTLView.swift b/Sources/UsdView/Hydra/MTL/Hydra+MTLView.swift index 5d0f4b9fb..22a6bccb7 100644 --- a/Sources/UsdView/Hydra/MTL/Hydra+MTLView.swift +++ b/Sources/UsdView/Hydra/MTL/Hydra+MTLView.swift @@ -38,11 +38,14 @@ import PixarUSD private let device: MTLDevice! private let renderer: MTLRenderer! - public init(hydra: Hydra.RenderEngine, device: MTLDevice, renderer: MTLRenderer) + var rgba: (Double, Double, Double, Double) + + public init(hydra: Hydra.RenderEngine, device: MTLDevice, renderer: MTLRenderer, rgba: (Double, Double, Double, Double)) { self.hydra = hydra self.device = device self.renderer = renderer + self.rgba = rgba } public func makeCoordinator() -> Coordinator @@ -55,6 +58,7 @@ import PixarUSD let metalView = context.coordinator.metalView metalView.device = device metalView.delegate = renderer + metalView.clearColor = MTLClearColorMake(rgba.0, rgba.1, rgba.2, rgba.3) metalView.apply(context.environment) context.coordinator.setNeedsDisplayTrigger = context.environment.setNeedsDisplayTrigger @@ -62,15 +66,12 @@ import PixarUSD return metalView } - public func updateNSView(_: MTKView, context: Context) + public func updateNSView(_ view: MTKView, context: Context) { - context.coordinator.metalView.apply(context.environment) - context.coordinator.setNeedsDisplayTrigger = context.environment.setNeedsDisplayTrigger - - renderer.draw(in: context.coordinator.metalView) - hydra.render() + view.clearColor = MTLClearColorMake(rgba.0, rgba.1, rgba.2, rgba.3) - print("UPDATE VIEW") + renderer.draw(in: view) + hydra.render(rgba: rgba) } public class Coordinator diff --git a/Sources/UsdView/UsdView.swift b/Sources/UsdView/UsdView.swift index bc09a15bc..061e28c6f 100644 --- a/Sources/UsdView/UsdView.swift +++ b/Sources/UsdView/UsdView.swift @@ -15,6 +15,7 @@ import PixarUSD #if canImport(SwiftUI) import SwiftUI + public protocol PixarApp: App {} #else @@ -38,6 +39,10 @@ struct UsdView: PixarApp /// the hydra rendering engine. let engine: Hydra.RenderEngine + /// give it a color spectrum... + @State var rgba = (0.1, 0.1, 0.1, 1.0) + @State var hue = 0.0 + public init() { // register all usd plugins & resources. @@ -59,8 +64,14 @@ struct UsdView: PixarApp { VStack { - Hydra.Viewport(engine: engine) - .frame(maxWidth: .infinity, maxHeight: .infinity) + Hydra.Viewport(engine: engine, rgba: rgba) + .ignoresSafeArea() + } + .onAppear + { + #if canImport(SwiftUI) + startColorAnimation() + #endif // canImport(SwiftUI) } } } diff --git a/Sources/UsdView/Utils/ShadingUtils.swift b/Sources/UsdView/Utils/ShadingUtils.swift index 9827f59e2..c02c4b847 100644 --- a/Sources/UsdView/Utils/ShadingUtils.swift +++ b/Sources/UsdView/Utils/ShadingUtils.swift @@ -62,3 +62,34 @@ public func matDef(_ stage: UsdStageRefPtr, color: ShadeColor = ShadeColor.white return material } + +#if canImport(SwiftUI) + import SwiftUI + + extension UsdView + { + func startColorAnimation() + { + Timer.scheduledTimer(withTimeInterval: 0.03, repeats: true) + { _ in + hue += 0.01 + if hue > 1.0 { hue = 0.0 } + rgba = hueToRGBA(hue: hue) + } + } + + func hueToRGBA(hue: Double) -> (Double, Double, Double, Double) + { + let color = Color(hue: hue, saturation: 1.0, brightness: 1.0) + var red: Double = 0, green: Double = 0, blue: Double = 0, alpha: Double = 0 + if let components = color.cgColor?.components, components.count >= 3 + { + red = components[0] + green = components[1] + blue = components[2] + alpha = Double(color.cgColor?.alpha ?? 1.0) + } + return (red, green, blue, alpha) + } + } +#endif // canImport(SwiftUI)