swift+metal로 3D 그리기

14130 단어 iOSMetalSwift
역사를 갱신하다
2017년 11월 20일 참조 소스 코드 추가

swift+metal로 3D 그리기


개시하다


swift+metal로 3D 액션 게임을 제작했습니다.
"MENTINAZE"라는 안경을 만들어 싸우는 게임!무료 용량도 20MB 정도인데 한번 해보세요!부탁합니다https://t.co/Re6VZHj4lZ-등성@안경환생공개(@fuziki333)pic.twitter.com/4Tycuy6p3t

처음 그리기 전에는 어렵기 때문에 obj 파일을 불러와 그리기 전에 모두 공개되었습니다

앞으로 Metal을 사용하실 분들에게 참고가 된다면 정말 기쁘겠습니다.br/>
소스 코드 여기서 ↓

2017년 11월 15일.

https://github.com/fuziki/metalTest


및 Word


주로 MetalEz가 Metal의 API를 호출하고 World가 카메라와 전투기를 관리한다p>

MetalEz 클래스


MetalEz 그리기 전에 MetalEzClass Delegat의 업데이트를 호출합니다br/>
다음은 piperlinestate를 순서대로 설정하고 MetalEzClassDelegat의draw를 호출합니다br/>
RenderType에 따라 설정된 파이프라인 식별br/>
ViewController에서 객체를 생성하고 MetalEzClass Delegate 자체 수신을 설정합니다.p>


GameViewController.swift

        mtlEz = MetalEz()
        mtlEz.delegate = self
        mtlEz.setupMetal(mtkView: self.view as! MTKView!)



MetalEz.swift

protocol MetalEzClassDelegate {
    func update()
    func draw(type: MetalEzRenderingEngine.RendererType)
}


공개 코드에는 3D 대상을 그리는 두 가지 파이프라인이 있습니다br/>
하나는 그림자(왼쪽 입방체), 다른 하나는 그림자(오른쪽 전투기)br/>
각각, RenderType 및 meshnonlighting.



MetalEz.swift

enum RendererType: Int {
        case mesh
        case mesh_add
        case mesh_nonlighting
    }


월드 레벨


그릴 대상이나 카메라를 관리합니다.


Camera 클래스


카메라의 위치, 방향 및 위쪽 방향 설정br/>
MetalEz 클래스의 lookAt 방법을 사용하여 설정합니다.



World.swift

class Camera {
    weak var world: World!
    private var rot: Float = 0
    private var sgn: Float = 0.01
    init(world myworld: World) {
        world = myworld
    }
    func update() {
        rot += sgn
        if abs(rot) > 0.8 { sgn *= -1 }
        world.mtlEz.lookAt(from: float3(0, 1, -1), direction: normalize(float3(sin(rot), -0.5, 1)), up: float3(0, 1, 0))
    }
}


MeshDrawer


전투기 및 입방체는 MeshDrawer를 사용하여 제작br/>
업데이트를 호출할 때 모델 변환 매트릭스 설정br/>
draw 방법을 실행한 후 그립니다.



MeshDrawer.swift

extension MetalEz {
    class MeshDrawer {
        private var mesh: MTKMesh
        private var texture: MTLTexture
        private var frameUniformBuffer: MTLBuffer
        private weak var mtlEz: MetalEz!
        var hidden: Bool = false
        init(mtlEz m: MetalEz ,mesh v: MTKMesh, texture t: MTLTexture)         
        func set(modelMatrix: matrix_float4x4)
        func draw() 
    }
}



Realship.swift

class Realship {
    weak var world: World!
    private var drawer: MetalEz.MeshDrawer
    private var rot: Float = 0.0
    init(world myworld: World) {
        world = myworld
        let tex = world.mtlEz.loader.loadTexture(name: "shipDiffuse", type: "png")
        let mesh = world.mtlEz.loader.loadMesh(name: "realship")
        drawer = MetalEz.MeshDrawer(mtlEz: world.mtlEz ,mesh: mesh, texture: tex)
    }
    func update() {
        rot += 1
        var mat = matrix_identity_float4x4
        mat = matrix_multiply(mat, Utils.translation(float3(2, -1, 3)))
        mat = matrix_multiply(mat, Utils.rotation_y(radians: toRad(fromDeg: rot)))
        drawer.set(modelMatrix: mat)
    }
    func draw(type: MetalEzRenderingEngine.RendererType) {
        if type == .mesh_nonlighting {
            drawer.draw()
        }
    }
}


총결산


API를 단순히 호출한 것이기 때문에 (;ω・)

비록 안 되는 코드지만, 나는 누구에게나 도움이 될 것이라고 믿는다(웃음)

실제 발표된 게임에서도 같은 메커니즘을 사용했다br/>
이것은'백만니제생'안경으로 환생하여 전투를 하는 액션 게임이다br/>
공짜 용량도 20MB 정도인데 스위프트+메탈로 게임을 만들면 어떤 느낌일까? 궁금하면 m() 다운로드를 해보자.m

당장 꺼주세요!←


좋은 웹페이지 즐겨찾기