Swift에서 Metal을 사용하여 삼각형 그리기

13709 단어 MetalSwiftMaciOS
Metal, 음영처리기의 최소 샘플, 메모 사용

■ Step1: 초기화


초기 초기화 참조
・ iOs에서 Swift를 사용하여 Metal 초기화
https://qiita.com/sanoh/items/e54057286adf3d63407b
・ Mac에서 Swift를 사용하여 Metal 초기화
https://qiita.com/sanoh/items/39f26a9a8e519cc61f00

■ Setp2: 음영처리기 만들기


먼저 Shader.metal을 생성합니다.

Shader.metal
#include <metal_stdlib>
using namespace metal;

vertex float4 myVertexShader(const device packed_float3* vertex_array [[ buffer(0) ]],
                             unsigned int vid [[ vertex_id ]]) {
    return float4(vertex_array[vid], 1.0);
}

fragment half4 myFragmentShader() {
    return half4(1.0);
}

■Setp3:MetalRenderer.swift 편집


MetalRenderer.swift
import MetalKit

let maxBuffersInFlight = 3

class MetalRenderer: NSObject, MTKViewDelegate {
    let _device: MTLDevice
    let _command_queue: MTLCommandQueue
    let _in_flight_semaphore = DispatchSemaphore(value: maxBuffersInFlight)

    let _buffer_position : MTLBuffer!
    let _render_pipeline_state: MTLRenderPipelineState

    init?(metalKitView: MTKView) {
        let vertices_array:[Float] =
            [
                0.0, 1.0, 0.0,
                -1.0, -1.0, 0.0,
                1.0, -1.0, 0.0                
            ]
        _device = metalKitView.device!
        _command_queue = _device.makeCommandQueue()!
        metalKitView.colorPixelFormat = MTLPixelFormat.bgra8Unorm
        //三角形をバッファに登録
        let size = vertices_array.count * MemoryLayout<Float>.size
        _buffer_position = _device.makeBuffer(bytes: vertices_array, length: size)
        //シェーダーを登録
        guard let library = _device.makeDefaultLibrary() else { fatalError() }
        let descriptor = MTLRenderPipelineDescriptor()
        descriptor.vertexFunction=library.makeFunction(name: "myVertexShader")
        descriptor.fragmentFunction=library.makeFunction(name: "myFragmentShader")
        descriptor.colorAttachments[0].pixelFormat = metalKitView.colorPixelFormat
        _render_pipeline_state = try! _device.makeRenderPipelineState(descriptor: descriptor)

        super.init()
    }

    func draw(in view: MTKView) {
        _ = _in_flight_semaphore.wait(timeout: DispatchTime.distantFuture)

        if let command_buffer = _command_queue.makeCommandBuffer() {
            let semaphore = _in_flight_semaphore
            command_buffer.addCompletedHandler { (_ command_buffer)-> Swift.Void in
                semaphore.signal()
            }
            let render_pass_descriptor = view.currentRenderPassDescriptor
            render_pass_descriptor?.colorAttachments[0].loadAction=MTLLoadAction.clear
            render_pass_descriptor?.colorAttachments[0].storeAction=MTLStoreAction.store
            render_pass_descriptor?.colorAttachments[0].clearColor=MTLClearColorMake(1.0, 0.0, 0.0, 1.0)
            if let render_pass_descriptor = render_pass_descriptor {
                if let render_encoder = command_buffer.makeRenderCommandEncoder(descriptor: render_pass_descriptor) {
                    //三角形とシェーダーをキューに登録
                    render_encoder.setRenderPipelineState(_render_pipeline_state)
                    render_encoder.setVertexBuffer(_buffer_position, offset: 0, index: 0)
                    render_encoder.drawPrimitives(type: MTLPrimitiveType.triangle, vertexStart: 0, vertexCount: 3)

                    render_encoder.endEncoding()
                    if let drawable = view.currentDrawable {
                        command_buffer.present(drawable)
                    }
                }
            }
            command_buffer.commit()
        }
    }

    func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
    }
}

■ Setp4: 실행


iOs는 실제 컴퓨터에서 실행하십시오. Mac의 상황은 다음과 같습니다.

좋은 웹페이지 즐겨찾기