OpenGL ES2.0 を使って板を回転させる方法のメモ

ポイント

 表示ギザギザ対策で、drawableMultisampleを設定

板をx軸周りに回転させるサンプルコード

#import “ViewController.h”

@interface ViewController (){

    GLuint vertexBufferID;

}

@property (strong, nonatomic) GLKBaseEffect *baseEffect;

@property (nonatomic) GLfloat angleDegrees;

@end

typedef struct {

    GLKVector3 positionCoords;

    GLKVector3 normalCoords;

} SceneVertex;

static const SceneVertex vertices[] =

{

    //x     y      z              nx     ny     nz

    {{1.0f, –1.0f, –0.1f},        {1.0f,  0.0f,  0.0f}},

    {{1.0f,  1.0f, –0.1f},         {1.0f,  0.0f,  0.0f}},

    {{1.0f, –1.0f,  0.1f},         {1.0f,  0.0f,  0.0f}},

    {{1.0f, –1.0f,  0.1f},         {1.0f,  0.0f,  0.0f}},

    {{1.0f,  1.0f,  0.1f},         {1.0f,  0.0f,  0.0f}},

    {{1.0f,  1.0f, –0.1f},         {1.0f,  0.0f,  0.0f}},

    

    {{1.0f,  1.0f, –0.1f},         {0.0f,  1.0f,  0.0f}},

    {{-1.0f,  1.0f, –0.1f},        {0.0f,  1.0f,  0.0f}},

    {{1.0f,  1.0f,  0.1f},         {0.0f,  1.0f,  0.0f}},

    {{1.0f,  1.0f,  0.1f},         {0.0f,  1.0f,  0.0f}},

    {{-1.0f,  1.0f, –0.1f},        {0.0f,  1.0f,  0.0f}},

    {{-1.0f,  1.0f,  0.1f},        {0.0f,  1.0f,  0.0f}},

    

    {{-1.0f,  1.0f, –0.1f},        {-1.0f,  0.0f,  0.0f}},

    {{-1.0f, –1.0f, –0.1f},        {-1.0f,  0.0f,  0.0f}},

    {{-1.0f,  1.0f,  0.1f},        {-1.0f,  0.0f,  0.0f}},

    {{-1.0f,  1.0f,  0.1f},        {-1.0f,  0.0f,  0.0f}},

    {{-1.0f, –1.0f, –0.1f},        {-1.0f,  0.0f,  0.0f}},

    {{-1.0f, –1.0f,  0.1f},        {-1.0f,  0.0f,  0.0f}},

    

    {{-1.0f, –1.0f, –0.1f},        {0.0f, –1.0f,  0.0f}},

    {{1.0f, –1.0f, –0.1f},         {0.0f, –1.0f,  0.0f}},

    {{-1.0f, –1.0f,  0.1f},        {0.0f, –1.0f,  0.0f}},

    {{-1.0f, –1.0f,  0.1f},        {0.0f, –1.0f,  0.0f}},

    {{1.0f, –1.0f, –0.1f},         {0.0f, –1.0f,  0.0f}},

    {{1.0f, –1.0f,  0.1f},         {0.0f, –1.0f,  0.0f}},

    

    {{1.0f,  1.0f,  0.1f},         {0.0f,  0.0f,  1.0f}},

    {{-1.0f,  1.0f,  0.1f},        {0.0f,  0.0f,  1.0f}},

    {{1.0f, –1.0f,  0.1f},         {0.0f,  0.0f,  1.0f}},

    {{1.0f, –1.0f,  0.1f},         {0.0f,  0.0f,  1.0f}},

    {{-1.0f,  1.0f,  0.1f},        {0.0f,  0.0f,  1.0f}},

    {{-1.0f, –1.0f,  0.1f},        {0.0f,  0.0f,  1.0f}},

    

    {{1.0f, –1.0f, –0.1f},         {0.0f,  0.0f, –1.0f}},

    {{-1.0f, –1.0f, –0.1f},        {0.0f,  0.0f, –1.0f}},

    {{1.0f,  1.0f, –0.1f},         {0.0f,  0.0f, –1.0f}},

    {{1.0f,  1.0f, –0.1f},         {0.0f,  0.0f, –1.0f}},

    {{-1.0f, –1.0f, –0.1f},        {0.0f,  0.0f, –1.0f}},

    {{-1.0f,  1.0f, –0.1f},        {0.0f,  0.0f, –1.0f}}

};

@implementation ViewController

@synthesize baseEffect;

@synthesize angleDegrees;

– (void)viewDidLoad

{

    [super viewDidLoad];

        

    self.angleDegrees = 1.0f;

    

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

    v.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    [EAGLContext setCurrentContext:v.context];

    v.drawableDepthFormat = GLKViewDrawableDepthFormat24;

    

    // opengl es2のギザギザ対策

    // antialiasで滑らかに。

    v.drawableMultisample = GLKViewDrawableMultisample4X;

    // ライトセッティング

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

    self.baseEffect.light0.enabled = GL_TRUE;

    self.baseEffect.light0.diffuseColor = GLKVector4Make(0.6f, 0.6f, 0.65f, 1.0f);

    

    // 板データの読み込み

    glGenBuffers(1, &vertexBufferID);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);

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

    

    glEnable(GL_DEPTH_TEST);

    

    // 座標データの設定

    glEnableVertexAttribArray(GLKVertexAttribPosition);

    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL + offsetof(SceneVertex, positionCoords));

    

    // Normal Vector の設定

    glEnableVertexAttribArray(GLKVertexAttribNormal);

    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL + offsetof(SceneVertex, normalCoords));

    

    

    // 付録のスイッチ

    [self setUpSwitch];

}

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

{

    // 背景色

    glClearColor(0.0f, 1.0f, 1.0f, 1.0f);

    

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    

    [self.baseEffect prepareToDraw];

    

    glDrawArrays(GL_TRIANGLES, 0, 36);

}

– (void)update

{

    // 画面と連動して呼び出される

    

    // 投影

    float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);

    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(50.0f), aspect, 0.1f, 100.0f);

    self.baseEffect.transform.projectionMatrix = projectionMatrix;

    

    // モデルの回転 x

    GLKMatrix4 modelMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, –7.0f);

    modelMatrix = GLKMatrix4Rotate(modelMatrix, self.angleDegrees, 1.0f, 0.0f, 0.0f);

    self.baseEffect.transform.modelviewMatrix = modelMatrix;

    

    // 回転角を微増

    self.angleDegrees += self.timeSinceLastUpdate * 1.0f;

}

// 付録

// ギザギザ有無 切り替え

– (void)setUpSwitch

{

    // Anti-Aliasingのスイッチを作る

    UISwitch *sw = [[UISwitch alloc] initWithFrame:CGRectMake(120, 15, 50, 30)];

    sw.on = YES;

    [sw addTarget:self action:@selector(changeDrawableMultisample) forControlEvents:UIControlEventValueChanged];

    [self.view addSubview:sw];

    

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 120, 30)];

    label.backgroundColor = [UIColor clearColor];

    label.textColor = [UIColor grayColor];

    label.text = @”Anti-Aliasing”;

    [self.view addSubview:label];

}

– (void)changeDrawableMultisample

{

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

    if(v.drawableMultisample == GLKViewDrawableMultisample4X) {

        v.drawableMultisample = GLKViewDrawableMultisampleNone;

    } else {

        v.drawableMultisample = GLKViewDrawableMultisample4X;

    }

}

– (void)clear

{

    // 後処理

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

    [EAGLContext setCurrentContext:view.context];

    if (0 != vertexBufferID) {

        glDeleteBuffers(1, &vertexBufferID);

        vertexBufferID = 0;

    }

    

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

    [EAGLContext setCurrentContext:nil];

}

– (void)didReceiveMemoryWarning

{

    [super didReceiveMemoryWarning];

    [self clear];

}

@end