iPhoneシリンダー3D

シリンダー(3Dモデル)を上下に動かすだけのシンプルなiPhoneアプリのサンプルコードを描いてみます。


使ったもの

cylinder.hシリンダーのモデル情報

動かすとこんな感じです

サンプルコード

#import “ViewController.h”

#import “cylinder.h”

@interface ViewController () {

    GLuint v;

    GLuint nv;

    float angle;

    float height;

}

@property (nonatomic, strong) GLKBaseEffect *baseEffect;

@property (nonatomic, strong) GLKView *gv;

@property int direction;

@property float distance;

@end

@implementation ViewController

– (void)loadView

{

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

}

– (void)viewDidLoad

{

    [super viewDidLoad];

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

    self.gv.drawableColorFormat = GLKViewDrawableDepthFormat16;

    [EAGLContext setCurrentContext:self.gv.context];

    

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

    self.baseEffect.light0.enabled = GL_TRUE;

    self.baseEffect.light0.diffuseColor = GLKVector4Make(0.5f,0.9f,0.4f,1.0f);

    self.baseEffect.light0.position = GLKVector4Make(-0.8f,-0.8f, 6.0f,0.8f);

    self.baseEffect.light0.ambientColor = GLKVector4Make(0.2f, 0.8f, 0.7f, 1.0f);

    

    glClearColor(.2f, .6f, .6f, 1.0f);

    

    glGenBuffers(1, &v);

    glBindBuffer(GL_ARRAY_BUFFER, v);

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

    

    glGenBuffers(1, &nv);

    glBindBuffer(GL_ARRAY_BUFFER, nv);

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

    

    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);

    

    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.3, 0.3 * aspectRatio, 0.1);

    GLKMatrix4 result = GLKMatrix4MakeRotation(-M_PI/3.0, 1, 0, 0);

    if (self.direction == 0) {

        // down

        result = GLKMatrix4Translate(result, 0, 0, self.distance);

        self.distance -= 0.1;

        if (self.distance < –5) {

            self.direction = 1;

        }

    } else {

        // up

        result = GLKMatrix4Translate(result, 0, 0, self.distance);

        self.distance += 0.1;

        if (self.distance > 5) {

            self.direction = 0;

        }

    }

    self.baseEffect.transform.modelviewMatrix = result;

    

    glDrawArrays(GL_TRIANGLES, 0, cylinderNumVerts);

}

@end