微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MTKView 透明度

如何解决MTKView 透明度

我无法让我的 MTKView 清除背景。我已将视图及其图层的 isOpaque 设置为 false,将背景颜色设置为清除,并尝试了在 google/stackoverflow 上找到的多种解决方案(大部分在下面的代码中,如 loadAction 和颜色附件的 clearColor),但没有任何效果

似乎忽略了所有背景颜色设置。设置 MTLRenderPassColorAttachmentDescriptor 的 loadAction 和 clearColor 没有任何作用。

我想在 MTKView 下绘制我的常规 UIView。我错过了什么?

            // initialization
            let Metal = MTKView(frame: self.view.bounds)
            Metal.device = MTLCreateSystemDefaultDevice()
            self.renderer = try! MetalRenderer(mtkView: Metal)
            Metal.delegate = self.renderer
            self.view.addSubview(Metal);
import Foundation
import MetalKit
import simd

public enum MetalError: Error {
    case mtkViewError
    case renderError
}

internal class MetalRenderer: NSObject,MTKViewDelegate {
    private let commandQueue: MTLCommandQueue;
    private let pipelinestate: MTLRenderPipelinestate
    private var viewportSize: SIMD2<UInt32> = SIMD2(x: 10,y: 10);
    private weak var mtkView: MTKView?
        

    
    init(mtkView: MTKView) throws {

        guard let device = mtkView.device else { 
            print("device not found error")
            throw MetalError.mtkViewError 
        }
        self.mtkView = mtkView

        // Load all the shader files with a .Metal file extension in the project.
        guard let defaultLibrary = device.makeDefaultLibrary() else {
            print("Could not find library")
            throw MetalError.mtkViewError
        }
        let vertexFunction = defaultLibrary.makeFunction(name: "vertexShader")
        let fragmentFunction = defaultLibrary.makeFunction(name: "fragmentShader")

        mtkView.layer.isOpaque = false;
        mtkView.layer.backgroundColor = UIColor.clear.cgColor
        mtkView.isOpaque = false;
        mtkView.backgroundColor = .clear

        let pipelinestateDescriptor = MTLRenderPipelineDescriptor();
        pipelinestateDescriptor.label = "Pipeline";
        pipelinestateDescriptor.vertexFunction = vertexFunction;
        pipelinestateDescriptor.fragmentFunction = fragmentFunction;
        pipelinestateDescriptor.isAlphaToCoverageEnabled = true
        pipelinestateDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm;
        pipelinestateDescriptor.colorAttachments[0].isBlendingEnabled = true;
        pipelinestateDescriptor.colorAttachments[0].destinationRGBBlendFactor = .oneMinusSourceAlpha;
        pipelinestateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = .oneMinusSourceAlpha;

        pipelinestate = try! device.makeRenderPipelinestate(descriptor: pipelinestateDescriptor);
        
        guard let queue = device.makeCommandQueue() else { 
            print("make command queue error")
            throw MetalError.mtkViewError 
        }
        commandQueue = queue
    }


    func mtkView(_ view: MTKView,drawableSizeWillChange size: CGSize) {
        viewportSize.x = UInt32(size.width)
        viewportSize.y = UInt32(size.height)
    }

    func draw(in view: MTKView) {

        let vertices: [Vertex] = [
            Vertex(position: SIMD3<Float>(x: 250.0,y: -250.0,z: 0)),Vertex(position: SIMD3<Float>(x: -250.0,Vertex(position: SIMD3<Float>(x: 0.0,y: 250.0,]
        
        guard let commandBuffer = commandQueue.makeCommandBuffer() else { 
            print("Couldn't create command buffer")
            return 
        }
        // Create a new command buffer for each render pass to the current drawable.
        commandBuffer.label = "MyCommand";

        // Obtain a renderPassDescriptor generated from the view's drawable textures.
        guard let renderPassDescriptor = view.currentRenderPassDescriptor else {
            print("Couldn't create render pass descriptor")
            return
        }
        
        guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
            print("Couldn't create render encoder")
            return
        }

        renderPassDescriptor.colorAttachments[0].loadAction = .clear
        renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0,0.0,0.5)

        renderEncoder.label = "MyRenderEncoder";
        // Set the region of the drawable to draw into.
        renderEncoder.setViewport(MTLViewport(originX: 0.0,originY: 0.0,width: Double(viewportSize.x),height: Double(viewportSize.y),znear: 0.0,zfar: 1.0))
        renderEncoder.setRenderPipelinestate(pipelinestate)

        // Pass in the parameter data.
        renderEncoder.setVertexBytes(vertices,length: MemoryLayout<Vertex>.size * vertices.count,index: Int(VertexInputIndexVertices.rawValue))
        renderEncoder.setVertexBytes(&viewportSize,length: MemoryLayout<SIMD2<UInt32>>.size,index: Int(VertexInputIndexViewportSize.rawValue))
        renderEncoder.drawPrimitives(type: MTLPrimitiveType.triangle,vertexStart: 0,vertexCount: 3)
        renderEncoder.endEncoding()

        // Schedule a present once the framebuffer is complete using the current drawable.
        guard let drawable = view.currentDrawable else {
            print("Couldn't get current drawable")
            return
        }

        commandBuffer.present(drawable)

        // Finalize rendering here & push the command buffer to the GPU.
        commandBuffer.commit()
    }
}

解决方法

感谢 Frank,答案是设置视图本身的 clearColor 属性,我错过了。我还删除了 MTLRenderPipelineDescriptor 中的大部分调整,现在谁的代码是:

    let pipelineStateDescriptor = MTLRenderPipelineDescriptor();
    pipelineStateDescriptor.label = "Pipeline";
    pipelineStateDescriptor.vertexFunction = vertexFunction;
    pipelineStateDescriptor.fragmentFunction = fragmentFunction;
    pipelineStateDescriptor.colorAttachments[0].pixelFormat = 
    mtkView.colorPixelFormat;

也无需从 currentRenderPassDescriptor 更改 MTLRenderPassDescriptor。

EDIT: 还要确保将 MTKView 的 isOpaque 属性也设置为 false。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?