Help us understand the problem. What is going on with this article?

# SwiftでMetalを使用して三角形の色を変更しよう

More than 1 year has passed since last update.

Metalを使用して、シェーダーを使って、三角形の色を後から変更する覚書
「SwiftでMetalを使用して三角形を描画しよう」を参照
https://qiita.com/sanoh/items/98df8d580edaa99c32c9

## ■Step1：シェーダー変更

```#ifndef ShaderType_h

#ifdef __METAL_VERSION__
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#define NSInteger metal::int32_t
#else
#import <Foundation/Foundation.h>
#endif

#include <simd/simd.h>

typedef NS_ENUM(NSInteger, BufferIndex)
{
BufferIndexPositions = 0,
BufferIndexUniforms  = 1
};

typedef struct
{
float   color[3];
} Uniforms;

```

```#include <metal_stdlib>

using namespace metal;

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

fragment half4 myFragmentShader(constant Uniforms & uniforms [[ buffer(BufferIndexUniforms) ]]) {
return half4(uniforms.color[0],  uniforms.color[1], uniforms.color[2] , 1.0);
}
```

## ■Step2:MetalRenderer.swiftを編集します。

MetalRenderer.swift
```import Metal
import MetalKit
import simd

let alignedUniformsSize = (MemoryLayout<Uniforms>.size & ~0xFF) + 0x100
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

let _dynamic_uniform_buffer:MTLBuffer
var _uniform_buffer_index = 0

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.colorAttachments[0].pixelFormat = metalKitView.colorPixelFormat
_render_pipeline_state = try! _device.makeRenderPipelineState(descriptor: descriptor)

let uniform_buffer_size = alignedUniformsSize * maxBuffersInFlight
_dynamic_uniform_buffer = _device.makeBuffer(length: uniform_buffer_size, options:[MTLResourceOptions.storageModeShared])!

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].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 {
_uniform_buffer_index = (_uniform_buffer_index + 1) % maxBuffersInFlight
let uniform_buffer_offset = alignedUniformsSize * _uniform_buffer_index
let uniforms = UnsafeMutableRawPointer(_dynamic_uniform_buffer.contents() + uniform_buffer_offset).bindMemory(to:Uniforms.self, capacity:1)
uniforms[0].color.0 = 0.0   //  R   色指定
uniforms[0].color.1 = 0.0   //  G
uniforms[0].color.2 = 1.0   //  B

if let render_encoder = command_buffer.makeRenderCommandEncoder(descriptor: render_pass_descriptor) {

render_encoder.setFragmentBuffer(_dynamic_uniform_buffer, offset:uniform_buffer_offset, index: BufferIndex.uniforms.rawValue)

render_encoder.setRenderPipelineState(_render_pipeline_state)
render_encoder.setVertexBuffer(_buffer_position, offset: 0, index: BufferIndex.positions.rawValue)
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) {
}
}
```

## ■Setp3：ヘッダーファイルをSwiftから参照できるようにする。

Swiftからは直接ヘッダーファイルを参照できないので、設定します。

## ■Setp4：実行

iOsは実機で実行してくださいMacの場合は以下のようになります。

Why do not you register as a user and use Qiita more conveniently?
1. We will deliver articles that match you
By following users and tags, you can catch up information on technical fields that you are interested in as a whole
2. you can read useful information later efficiently
By "stocking" the articles you like, you can search right away