From bf9e4680eb466bcb7c9cb1bef567252bb1f2bb7d Mon Sep 17 00:00:00 2001 From: Runt <qingingrunt2010@qq.com> Date: Fri, 27 Jun 2025 05:32:55 +0000 Subject: [PATCH] 1 --- LiveProject/tool/MetalRenderer.swift | 78 +++++++++----------------------------- 1 files changed, 19 insertions(+), 59 deletions(-) diff --git a/LiveProject/tool/MetalRenderer.swift b/LiveProject/tool/MetalRenderer.swift index 3e88871..791dfc8 100644 --- a/LiveProject/tool/MetalRenderer.swift +++ b/LiveProject/tool/MetalRenderer.swift @@ -4,75 +4,35 @@ // 渲染工具 // Created by 倪路朋 on 6/26/25. // +import CoreVideo import Metal import MetalKit -class Renderer: NSObject, MTKViewDelegate { - static var shared: Renderer? +class MetalRenderer: NSObject, MTKViewDelegate { + var device: MTLDevice! + var commandQueue: MTLCommandQueue! - private var device: MTLDevice! - private var commandQueue: MTLCommandQueue! - private var pipelineState: MTLRenderPipelineState! - private var texture: MTLTexture? - private var textureDescriptor: MTLTextureDescriptor! - private var currentData: [UInt8]? - private var textureWidth = 0 - private var textureHeight = 0 - - weak var mtkView: MTKView? { - didSet { - guard let view = mtkView else { return } - device = view.device - commandQueue = device.makeCommandQueue() - - let library = device.makeDefaultLibrary() - let pipelineDesc = MTLRenderPipelineDescriptor() - pipelineDesc.vertexFunction = library?.makeFunction(name: "vertexShader") - pipelineDesc.fragmentFunction = library?.makeFunction(name: "fragmentShader") - pipelineDesc.colorAttachments[0].pixelFormat = view.colorPixelFormat - - pipelineState = try? device.makeRenderPipelineState(descriptor: pipelineDesc) - - Renderer.shared = self - } + func setup(view: MTKView) { + self.device = view.device + self.commandQueue = device.makeCommandQueue() + // 初始化 texture、pipeline 等 } - func updateFrame(data: [UInt8], width: Int, height: Int) { - currentData = data - textureWidth = width - textureHeight = height + // ✅ 必须实现的方法 1:窗口大小改变时调用 + func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) { + // 可以留空或更新视图缩放、渲染区域等 } + // ✅ 必须实现的方法 2:每一帧绘制时调用 func draw(in view: MTKView) { guard let drawable = view.currentDrawable, - let descriptor = view.currentRenderPassDescriptor, - let data = currentData else { return } + let descriptor = view.currentRenderPassDescriptor else { return } - if texture == nil || texture?.width != textureWidth || texture?.height != textureHeight { - textureDescriptor = MTLTextureDescriptor.texture2DDescriptor( - pixelFormat: .rgba8Unorm, - width: textureWidth, - height: textureHeight, - mipmapped: false - ) - textureDescriptor.usage = [.shaderRead, .shaderWrite] - texture = device.makeTexture(descriptor: textureDescriptor) - } - - let region = MTLRegionMake2D(0, 0, textureWidth, textureHeight) - data.withUnsafeBytes { ptr in - texture?.replace(region: region, mipmapLevel: 0, withBytes: ptr.baseAddress!, bytesPerRow: textureWidth * 4) - } - - let commandBuffer = commandQueue.makeCommandBuffer() - let encoder = commandBuffer?.makeRenderCommandEncoder(descriptor: descriptor) - encoder?.setRenderPipelineState(pipelineState) - encoder?.setFragmentTexture(texture, index: 0) - encoder?.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4) - encoder?.endEncoding() - commandBuffer?.present(drawable) - commandBuffer?.commit() + let commandBuffer = commandQueue.makeCommandBuffer()! + let encoder = commandBuffer.makeRenderCommandEncoder(descriptor: descriptor)! + // 渲染逻辑,如绘制纹理 + encoder.endEncoding() + commandBuffer.present(drawable) + commandBuffer.commit() } - - func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {} } -- Gitblit v1.9.1