iPhoneキューブを動かす

タッチしたところにキューブを動かすようなiPhoneアプリのサンプルコードを描いてみます。

動かすとこんな感じです

サンプルコード

#import <GLKit/GLKit.h>

@interface ViewController : GLKViewController

@end

#import “ViewController.h”

static const GLfloat cubeVertices[] = {

    1.0, –1.0,  1.0,

    1.0, –1.0,  1.0,

    1.0,  1.0,  1.0,

    1.0,  1.0,  1.0,

    1.0, –1.0, –1.0,

    1.0, –1.0, –1.0,

    1.0,  1.0, –1.0,

    1.0,  1.0, –1.0,

};

static const GLushort cubeIndices[] = {

    0, 1, 2, 3, 7, 1, 5, 4, 7, 6, 2, 4, 0, 1

};

@interface ViewController () {

    GLuint v;

    GLuint index;

    GLfloat degree;

    CGPoint touche;

    CGPoint cubePosition;

}

@property (nonatomic, strong) GLKBaseEffect *baseEffect;

@property (nonatomic, strong) GLKView *gv;

@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.useConstantColor = YES;

    self.baseEffect.constantColor = GLKVector4Make(0.5f, 0.5f, 0.2f, 1.0f);

    glClearColor(0.2f, 0.5f, 0.6f, 1.0f);

    

    glGenBuffers(1, &v);

    glBindBuffer(GL_ARRAY_BUFFER, v);

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

    

    glGenBuffers(1, &index);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index);

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cubeIndices), cubeIndices, 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);

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

    self.baseEffect.transform.projectionMatrix = GLKMatrix4MakeScale(0.3, 0.3 * aspectRatio, 0.1);

    

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, v);

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

    glEnableVertexAttribArray(GLKVertexAttribPosition);

    

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index);

    glDrawElements(GL_TRIANGLE_STRIP, 14, GL_UNSIGNED_SHORT, 0);

    

    GLKMatrix4 modelViewMatrix = GLKMatrix4Identity;

    

    if (!CGPointEqualToPoint(touche, cubePosition)) {

        float dx = (touche.x160.0) – cubePosition.x;

        float dy = (touche.y264) – cubePosition.y;

        float u = hypot(dx, dy) * 10.0;

        

        cubePosition = CGPointMake(cubePosition.x + dx/u, cubePosition.y – dy/u);

        modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, cubePosition.x * 0.3, cubePosition.y * 0.3 * aspectRatio, 0);

    }

    

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

    self.baseEffect.transform.modelviewMatrix = modelViewMatrix;

    degree++;

}

– (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    touche = [[touches anyObject] locationInView:self.view];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

@end