Apple Metal2 Swift尝试

写在前面的话

我个人并不是iOS或者macOS的开发工程师,只是之前用GLES2.0做过一些项目,前段时间知道苹果公司已经决定弃用OpenGL和OpenCL。以前做图形相关的项目,只需要维护一套GLES的代码就可以支持Apple、Linux、Android以及市面几乎所有的嵌入式厂商。虽然GLES还没有完全被苹果彻底弃用,但是还是想学习一下这个新的图形底层API—Metal

学习前的准备

Apple目前推荐的官方开发语言是Swift,而且Metal也没有提供C++的API,不过网上有大神用C++封装了一层,可以参考一下。链接地址:https://github.com/naleksiev/mtlpp。不过还是决定试试使用Swift,代码中的各种?和!都是系统提示我的,所以肯定有不完善的地方。 另外手边没有iPhone,所以demo程序是运行在Mac上的。

正题

工程创建

用Xcode创建一个macOS的Cocoa App项目,项目名字可以随便填一个,我这面填的是MyCode。语言选择Swift。Team那个地方选择自己的账号。其他的根据需要填写。
PS:需要提前注册一个Apple ID,去Apple的开发者网站激活一下,不需要付费就可以在mac上调试自己的程序了。具体方法就不详细说明了。

想做什么

因为在GLES中FBO这个东西被用到的次数非常多,所以想看看这个东西在Metal中怎么实现。我是按照GLES的思路先渲染到一个中间Texture上,再渲染到屏幕。不过貌似Metal推荐的做法是使用Compute(就是替代原来OpenCL的东西)。

开始写代码

先实现Texture直接渲染到屏幕上
基本代码结构

Metal貌似支持渲染在MTKView和CAMetalLayer上,我采用MTKView,并且添加一个渲染类来实现真正的渲染工作。

在系统为我们创建好的ViewController.swift中的viewDidLoad函数中添加MTKView的初始化工作。这部分的实现非常简单就一个init函数就搞定了,感觉这部分相当于原来EGL的各种操作,只不过系统帮你实现了。然后我想添加一个渲染类来处理描画。

  • 创建TextureRender 类
    在构造函数将MTKView作为参数传进来,并加一个render函数用来描画。代码大概是下面的样子:
import Foundation
import MetalKit

class TextureRender {
    //MARK: Properties
    var _mtkView: MTKView!
    //MARK: Initialization
    init?( mtkView:MTKView ) {
        self._mtkView = mtkView
    }
    // MARK : render method
    func render() -> Void {
    }
  • ViewController中的实现
  1. 在ViewDidLoad函数中实例MTKView和TextureRender,并修改ViewController的View为MTKView
    override func viewDidLoad() {
        super.viewDidLoad()

        let mtkView = MTKView.init(frame: self.view.bounds)
        mtkView.delegate = self
        self.view = mtkView
        
        self._render = TextureRender(mtkView: mtkView)
        // Do any additional setup after loading the view.
    }

因为要设置mtkView的代理实例,所以要继承MTKViewDelegate以及实现代理方法。最后ViewController的代码如下:
(到目前为止,ViewController中所有工作以及完成了)

//
//  ViewController.swift
//  MyCode
//
//  Created by larry-kof on 2018/11/26.
//  Copyright © 2018 larry-kof. All rights reserved.
//

import Cocoa
import MetalKit

class ViewController: NSViewController, MTKViewDelegate {
    
    var _render:TextureRender!
    override func viewDidLoad() {
        super.viewDidLoad()

        let mtkView = MTKView.init(frame: self.view.bounds)
        mtkView.delegate = self
        self.view = mtkView
        
        self._render = TextureRender(mtkView: mtkView)
        // Do any additional setup after loading the view.
    }

    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }
    
    
    // MARK: delegate
    func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {

    }
    
    func draw(in view: MTKView) {
        self._render.render()
    }

}
TextureRender实现

根据GLES中的经验,下一步就要编译vertex shader和fragment shader生成glProgram。不过在metal中需要一个device就是选择一个硬件设备(GPU或者CPU),和OpenCL中的clGetDeviceIDs一样。所以在构造函数中获取device,同时记住mtkView的大小以后来设置描画Viewport的大小。

    init?( mtkView:MTKView ) {
        self._mtkView = mtkView
        
        self._mtkView.device = MTLCreateSystemDefaultDevice()
        self._portViewSize = self._m
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值