Metal入门一 三角形

判断设备是否支持metal

guard  let device = MTLCreateSystemDefaultDevice() else {
        label.text = "Your GPU does not support Metal!"
        return
    }
label.text = "Your system has the following GPU(s):\n" + "\(device.name)\n"

创建 MTKView 的子类MetalView

Storyboard 或者 xib 上找个View 集成于 MetalView 或者 拖一个 MTKView 继承 MetalView

/// 缓存区的命令串行队列
    var commandQueue: MTLCommandQueue?
    
    /// 渲染管道
    var rps: MTLRenderPipelineState?
    /// 矩阵
    var verters: [Float] = [
               0,  0.1, 0,
            -0.5, -0.5, 0,
            0.5,  -0.5, 0
        ]
    /// 定点缓存数据
    var vertexBuffer: MTLBuffer?
required init(coder: NSCoder) {
        super.init(coder: coder)
        
        self.clearColor = MTLClearColor.init(red: 0.22, green: 1, blue: 0.4, alpha: 1)
        render()
    }

func render() {
        // 给 device 赋值
        device = MTLCreateSystemDefaultDevice()!
        
        // 1. 创建顶点缓存区
        self.vertexBuffer = device!.makeBuffer(bytes: verters,
                                                      length: verters.count * MemoryLayout<Float>.size, options: [])
        
        //2.1 makeDefaultLibrary:加载项目中所有.metal文件,当然也可以使用其他API来指定metal文件
        let library = device!.makeDefaultLibrary()!
        // 2.2 从库中加载顶点函数、片元函数  着色器语言和原理
        let vertex_func = library.makeFunction(name: "vertex_shader")
        let frag_func = library.makeFunction(name: "fragment_shader")
        let rpld = MTLRenderPipelineDescriptor()
        rpld.label = "test"
        //3.2 可编程函数,用于处理渲染过程中每个顶点、片元
        rpld.vertexFunction = vertex_func
        rpld.fragmentFunction = frag_func

//        rpld.colorAttachments[0].pixelFormat = MTLPixelFormat.bgra8Unorm
        
//        view.colorPixelFormat
        //3.3 确定渲染管线中颜色附着点0的颜色组件;使用当前view颜色组件
        rpld.colorAttachments[0].pixelFormat = self.colorPixelFormat
        
        /// 这个暂时使用无效 invalid 如果xib 里面有值则会闪退,此处目前一定要为 invalid
        self.depthStencilPixelFormat = MTLPixelFormat.invalid
        
        do {
            try rps = device!.makeRenderPipelineState(descriptor: rpld)
        } catch let error {
//            self.printView("\(error)")
            print("\(error)")
        }
        
        commandQueue = device!.makeCommandQueue()
    }

override func draw(_ rect: CGRect) {
        //6. 用于保存渲染过程中的一组结果,渲染命令编码器描述符
        if let drawable = currentDrawable, let rpd = currentRenderPassDescriptor {
            rpd.colorAttachments[0].clearColor = MTLClearColorMake(0, 0.5, 0.5, 1.0)
            //5. 为每一次渲染创建一个新的命令缓冲区
            let commandBuffer = commandQueue!.makeCommandBuffer()
            //  创建渲染命令编码器,通过它来进行渲染的配置
            let commandEncoder = commandBuffer?.makeRenderCommandEncoder(descriptor: rpd)
            // 设置当前渲染管道状态对象
            commandEncoder?.setRenderPipelineState(rps!)
            //10. 载入顶点数据
            //通过VertexInputIndexVertices将数据传递到顶点函数的对应buffer中
            commandEncoder?.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
            /// 绘制
            commandEncoder?.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 3, instanceCount: 1)
            //            结束编码
            commandEncoder?.endEncoding()
            //            锁定缓存区, 等待缓冲区处理完成后绘制
            commandBuffer?.present(drawable)
            //            将命令缓存区提交给GPU
            commandBuffer?.commit()
        }
    }

创建metal 文件 MyVertex.metal

#include <metal_stdlib>
using namespace metal;

vertex float4 vertex_shader(const device packed_float3 * vertices[[buffer(0)]], uint vertexId[[vertex_id]]){
    return float4(vertices[vertexId], 1);
}


fragment half4 fragment_shader() {
    return half4(1,1,0.5,1); //红色
}

模拟器不支持 请跑mac 应用

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值