Skip to content

Commit

Permalink
Ensure proper metal drawable presentation.
Browse files Browse the repository at this point in the history
Signed-off-by: furby™ <devs@wabi.foundation>
  • Loading branch information
furby-tm committed Dec 28, 2024
1 parent aeeb9d4 commit 65608bf
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 28 deletions.
21 changes: 17 additions & 4 deletions Sources/UsdView/Hydra/Hydra+RenderEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions Sources/UsdView/Hydra/Hydra+View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
29 changes: 17 additions & 12 deletions Sources/UsdView/Hydra/MTL/Hydra+MTLRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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,
Expand Down
17 changes: 9 additions & 8 deletions Sources/UsdView/Hydra/MTL/Hydra+MTLView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -55,22 +58,20 @@ 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

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
Expand Down
15 changes: 13 additions & 2 deletions Sources/UsdView/UsdView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import PixarUSD

#if canImport(SwiftUI)
import SwiftUI

public protocol PixarApp: App
{}
#else
Expand All @@ -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.
Expand All @@ -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)
}
}
}
Expand Down
31 changes: 31 additions & 0 deletions Sources/UsdView/Utils/ShadingUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 65608bf

Please sign in to comment.