iPhone GLkit 穴の開いた箱

上と下が穴になっている、ぺらっぺらの箱をOpenGL ESで描画するiPhoneアプリを書いてみる。


動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。

サンプルコード

// ————————-

// ViewController.h

// ————————-

#import <GLKit/GLKit.h>

@interface ViewController : GLKViewController

@end

// ————————-

// ViewController.m

// ————————-

#import “ViewController.h”

typedef struct

{

    float Position[3];

    float Color[4];

} Vertex;

const Vertex vertices[] = {

    {{0.0, 0.0, 0.0}, {1,1,0,1}},

    {{1.0, 0.0, 0.0}, {1,0,1,1}},

    {{0.0, 0.0, 0.5}, {1,1,0,1}},

    {{1.0, 0.0, 0.5}, {0,1,1,1}},

    

    {{0.0, 1.0, 0.0}, {1,1,0,1}},

    {{1.0, 1.0, 0.0}, {1,1,0,1}},

    {{0.0, 1.0, 0.5}, {1,1,1,1}},

    {{1.0, 1.0, 0.5}, {1,1,0,1}},

};

const GLubyte indices[] = {

    0,1,2, 1,3,2,

    1,5,3, 5,7,3,

    7,5,4, 6,7,4,

    6,2,0, 6,0,4,

    

};

@interface ViewController () {

    GLuint vertex;

    GLuint index;

    int degree;

}

@property (nonatomic, strong) GLKBaseEffect *baseEffect;

@property (nonatomic, strong) GLKView *gv;

@end

@implementation ViewController

@synthesize baseEffect, gv;

– (void)loadView

{

    self.view = [[GLKView alloc] initWithFrame:CGRectMake(0, 0, 320, 568) context:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]];

}

– (void)viewDidLoad

{

    [super viewDidLoad];

    

    gv = (GLKView *)self.view;

    gv.drawableDepthFormat = GLKViewDrawableDepthFormat16;

    [EAGLContext setCurrentContext:gv.context];

    

    self.baseEffect = [[GLKBaseEffect alloc] init];

    self.baseEffect.colorMaterialEnabled = GL_TRUE;

    

    glClearColor(.5f, .5f, 1.0f, 1.0f);

    

    glGenBuffers(1, &vertex);

    glBindBuffer(GL_ARRAY_BUFFER, vertex);

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    

    glGenBuffers(1, &index);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index);

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    

    glBindBuffer(GL_ARRAY_BUFFER, vertex);

    glEnableVertexAttribArray(GLKVertexAttribPosition);

    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), NULL+0);

    

    glEnableVertexAttribArray(GLKVertexAttribColor);

    glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), NULL + offsetof(Vertex, Color));

    

    glEnable(GL_DEPTH_TEST);

    glEnable(GL_BLEND);

//    glEnable(GL_CULL_FACE);

}

– (void)glkView:(GLKView *)view drawInRect:(CGRect)rect

{

    [self.baseEffect prepareToDraw];

    

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    

    const GLfloat aspectRatio = (GLfloat)gv.drawableWidth / (GLfloat)gv.drawableHeight;

    self.baseEffect.transform.projectionMatrix = GLKMatrix4MakeScale(0.6f, 0.6 * aspectRatio, 0.6f);

    

    glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_BYTE, 0);

    GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;

    modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(degree), 1, 0, 1);

    self.baseEffect.transform.modelviewMatrix = modelViewMatrix;

    

    degree++;

}

– (void)dealloc

{

    GLKView *view = (GLKView *)self.view;

    [EAGLContext setCurrentContext:view.context];

    

    if (0 != vertex) {

        glDeleteBuffers(1, &vertex);

    }

    

    if (0 != index) {

        glDeleteBuffers(1, &index);

    }

    

    view.context = nil;

    [EAGLContext setCurrentContext:nil];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end