GLKitを使って円盤を表示するiPhoneアプリを書いてみます。モデルデータは、Photoshopの3Dを使ってobjファイルをエクスポート、「obj2opengl.pl」をターミナルで実行してplate.hというファイルを作成しました。
動作イメージ
XcodeからiOS6 iPhone Simulatorで動かすとこんな感じになります。
サンプルコード
// ————————-
// ViewController.h
// ————————-
#import <GLKit/GLKit.h>
@interface ViewController : GLKViewController
@end
// ————————-
// ViewController.m
// ————————-
#import “ViewController.h”
#import “plate.h”
@interface ViewController () {
GLuint v;
GLuint nv;
BOOL toss;
float angle;
float height;
}
@property (strong, nonatomic) GLKBaseEffect *baseEffect;
@property (strong, nonatomic) 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;
gv.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:gv.context];
self.baseEffect = [[GLKBaseEffect alloc] init];
self.baseEffect.light0.enabled = GL_TRUE;
self.baseEffect.light0.diffuseColor = GLKVector4Make(0.9f,0.9f,0.4f,1.0f);
self.baseEffect.light0.position = GLKVector4Make(-0.8f,-0.8f,-3.0f,0.8f);
self.baseEffect.light0.ambientColor = GLKVector4Make(0.7f, 0.7f, 0.7f, 1.0f);
glClearColor(.4f, .4f, .6f, 1.0f);
glGenBuffers(1, &v);
glBindBuffer(GL_ARRAY_BUFFER, v);
glBufferData(GL_ARRAY_BUFFER, sizeof(plateVerts), plateVerts, GL_STATIC_DRAW);
glGenBuffers(1, &nv);
glBindBuffer(GL_ARRAY_BUFFER, nv);
glBufferData(GL_ARRAY_BUFFER, sizeof(plateNormals), plateNormals, GL_STATIC_DRAW);
glEnable(GL_DEPTH_TEST);
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeRotation(0.4, 1, 0, 0);
}
– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
toss = !toss;
}
– (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
[self.baseEffect prepareToDraw];
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, v);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL + 0);
glBindBuffer(GL_ARRAY_BUFFER, nv);
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 3* sizeof(GLfloat), NULL + 0);
const GLfloat aspectRatio = (GLfloat)view.drawableWidth / (GLfloat)view.drawableHeight;
self.baseEffect.transform.projectionMatrix = GLKMatrix4MakeScale(0.5f, 0.5 * aspectRatio, 0.5f);
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeRotation(0.4, 1, 0, 0);
// coin toss
if (toss) {
GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;
if (height < 3) {
height += 0.05;
angle += 15;
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, 0, height, 0);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix,GLKMathDegreesToRadians(angle), 1.0f, 0.0f, 0.0f);
} else {
toss = NO;
height = 0;
}
self.baseEffect.transform.modelviewMatrix = modelViewMatrix;
}
glDrawArrays(GL_TRIANGLES, 0, plateNumVerts);
}
– (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end