UIViewControllerでGLKViewを使ってみた

# 概要

XCode 6.3.1でUIViewControllerからGLKViewを使って3D描画してみたのでサンプルコードをメモしておく。
サンプルコードはOpenGL Gameテンプレートを簡単にしてGLKitだけ使うようにした感じ。
関連記事：[Xcode - OpenGL Gameテンプレートを3Dプログラミング未経験者が読む - Qiita](http://qiita.com/mechamogera/items/57793435553f0815063d)

![iOS Simulator Screen Shot 2015.05.08 16.27.16.png](https://qiita-image-store.s3.amazonaws.com/0/16768/a9df0a31-99f4-9db2-f6de-2ba1f6f345b8.png)

AutoLayout使ってないので表示はいびつ。

# 書いたコード
### storyboard

![storyboard_glkview.png](https://qiita-image-store.s3.amazonaws.com/0/16768/51f3e7c9-7bdd-cbfa-350c-5d99dc4b1426.png)

### MyViewController.h

```objc
#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>

@interface MyViewController : UIViewController <GLKViewDelegate>
@property (weak, nonatomic) IBOutlet GLKView *myGLKView;
@end
```

### MyViewController.m

```objc
#import "MyViewController.h"
#import <OpenGLES/ES2/glext.h>

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

GLfloat gMyVertexData2[18] =
{
    0.5f, 0.0f, 0.0f,       0.0f, 0.0f, 1.0f,
    0.0f, 0.5f, 0.0f,       0.0f, 0.0f, 1.0f,
    0.0f, -0.5f, 0.0f,      0.0f, 0.0f, 1.0f
};

@interface MyViewController ()
{
    float _rotation;
    
    GLuint _myVertexArray;
    GLuint _myVertexBuffer;
}
@property (strong, nonatomic) GLKBaseEffect *effect;

@end

@implementation MyViewController

- (void)viewDidLoad 
{
    [super viewDidLoad];
    
    EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    self.myGLKView.context = context;
    self.myGLKView.delegate = self;
    [self.myGLKView setEnableSetNeedsDisplay:YES];
    [self.view addSubview:self.myGLKView];
    
    [EAGLContext setCurrentContext:context];
    
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawFrame)];
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
  
    [self setupGL];
}

- (void)setupGL
{
    self.effect = [[GLKBaseEffect alloc] init];
    self.effect.light0.enabled = GL_TRUE;
    self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
    
    glGenVertexArraysOES(1, &_myVertexArray);
    glBindVertexArrayOES(_myVertexArray);
    
    glGenBuffers(1, &_myVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _myVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(gMyVertexData2), gMyVertexData2, GL_STATIC_DRAW);
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
    
    glBindVertexArrayOES(0);
}

- (void)drawFrame
{
    float aspect = fabs(self.view.bounds.size.width / self.view.bounds.size.height);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
    
    self.effect.transform.projectionMatrix = projectionMatrix;
    
    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
    modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
    
    self.effect.transform.modelviewMatrix = modelViewMatrix;
    
    _rotation += 0.2 * 0.5f;
    
    [self.myGLKView setNeedsDisplay];
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(1, 0, 0, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glBindVertexArrayOES(0);
    glBindVertexArrayOES(_myVertexArray);
    
    [self.effect prepareToDraw];
    
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

@end
```

# 参照サイト

* [XCode IPhone / IPad Development - Adding a GLKView to a UIViewController](http://www.guyford.co.uk/showpage.php?id=274&page=XCode_IPhone_/_IPad_Development_-_Adding_a_GLKView_to_a_UIViewController)