Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

GLKitミニマム

テンプレートを三角形が回転するだけのコードに削ってみた。

import GLKit
import OpenGLES

func BUFFER_OFFSET(i: Int) -> UnsafePointer<Void> {
    let p: UnsafePointer<Void> = nil
    return p.advancedBy(i)
}

class GameViewController: GLKViewController {
    
    var rotation: Float = 0.0
    
    var vertexArray: GLuint = 0
    var vertexBuffer: GLuint = 0
    
    var context: EAGLContext? = nil
    var effect: GLKBaseEffect? = nil
    
    deinit {
        self.tearDownGL()
        
        if EAGLContext.currentContext() === self.context {
            EAGLContext.setCurrentContext(nil)
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.context = EAGLContext(API: .OpenGLES2)
        
        if !(self.context != nil) {
            print("Failed to create ES context")
        }
        
        let view = self.view as! GLKView
        view.context = self.context!
        view.drawableDepthFormat = .Format24
        
        self.setupGL()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        
        if self.isViewLoaded() && (self.view.window != nil) {
            self.view = nil
            
            self.tearDownGL()
            
            if EAGLContext.currentContext() === self.context {
                EAGLContext.setCurrentContext(nil)
            }
            self.context = nil
        }
    }
    
    func setupGL() {
        EAGLContext.setCurrentContext(self.context)
        
        self.effect = GLKBaseEffect()
        self.effect!.light0.enabled = GLboolean(GL_TRUE)
        self.effect!.light0.diffuseColor = GLKVector4Make(1.0, 0.4, 0.4, 1.0)
        
        glEnable(GLenum(GL_DEPTH_TEST))
        
        glGenVertexArraysOES(1, &vertexArray)
        glBindVertexArrayOES(vertexArray)
        
        
        glGenBuffers(1, &vertexBuffer)// 頂点バッファポインタ生成
        glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)// 有効化

        // バッファに転送
        glBufferData(GLenum(GL_ARRAY_BUFFER),
                     GLsizeiptr(sizeof(GLfloat) * gVertexData.count),
                     &gVertexData,
                     GLenum(GL_STATIC_DRAW))
        
        // 属性指定に頂点の位置を用いる事を指定
        glEnableVertexAttribArray(GLuint(GLKVertexAttrib.Position.rawValue))
        
        //
        glVertexAttribPointer(GLuint(GLKVertexAttrib.Position.rawValue),
                              3,// 1頂点あたりの要素の数 三次元なのでx,y,zの3
                              GLenum(GL_FLOAT),
                              GLboolean(GL_FALSE), // ノーマライズされているか
                              GLsizei(sizeof(GLfloat)*3), // 格納されているデータの間隔
                              BUFFER_OFFSET(0)) // データは並んでいる。
        
        glBindVertexArrayOES(0)
    }
    
    func tearDownGL() {
        EAGLContext.setCurrentContext(self.context)
        
        glDeleteBuffers(1, &vertexBuffer)
        glDeleteVertexArraysOES(1, &vertexArray)
        
        self.effect = nil
    }
    
    // MARK: - GLKView and GLKViewController delegate methods
    
    func update() {
        
        let aspect = fabsf(Float(self.view.bounds.size.width / self.view.bounds.size.height))
        let projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0), aspect, 0.1, 100.0)
        
        self.effect?.transform.projectionMatrix = projectionMatrix
        
        var baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0, 0.0, -4.0)
        baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, rotation, 0.0, 1.0, 0.0)
        
        // Compute the model view matrix for the object rendered with GLKit
        var modelViewMatrix = GLKMatrix4MakeTranslation(0.0, 0.0, -1.5)
        modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, rotation, 1.0, 1.0, 1.0)
        modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix)
        
        self.effect?.transform.modelviewMatrix = modelViewMatrix
        
        rotation += Float(self.timeSinceLastUpdate * 0.5)
    }
    
    override func glkView(view: GLKView, drawInRect rect: CGRect) {
        glClearColor(0.65, 0.65, 0.65, 1.0)
        glClear(GLbitfield(GL_COLOR_BUFFER_BIT) | GLbitfield(GL_DEPTH_BUFFER_BIT))
        
        glBindVertexArrayOES(vertexArray)
        
        // Render the object with GLKit
        self.effect?.prepareToDraw()
        
        glDrawArrays(GLenum(GL_TRIANGLES) , 0, Int32(gVertexData.count/3))
    }
}


var gVertexData: [GLfloat] = [
    -0.5, -0.0, 0.0,
    0.5,-0.5,0.0,
    -0.5,0.5,0.0
]