OpenGL の描画までの手順は、サンプル GL3_Text と下記のページを
参考にさせていただきました。
・white wheelsのメモ: Cocoaサンプル – OpenGLで描画
・Mac Developer Library: GL3 Text
Xcode 上で UI とオブジェクトの対応付けを行っていくスタイルのようです。
GLK はありますが GLKView はなく NSOpenGLView が用いられています。
Xcode 5 で OS X 用のプロジェクト “Cocoa Application” を作成。
MainMenu.xib を選択して、GL3_Text を真似てシーンを作ってみます。
Window → View の下に Custom View をぶら下げます。
名称をとりあえず “GLView” に変更。

右サイドの Custom Class にも “GLView” と書き込んでおきます。

プロジェクトには OpenGL.framework を追加しておきます。
GLView.h を作成。
// GLView.h #import@interface GLView : NSOpenGLView @end
続いて GLView.mm を作成。
// GLView.mm
#import "GLView.h"
@interface GLView() {
NSTimer* mpTimer;
}
- (id)initWithFrame:(NSRect)frameRect;
- (void)reshape;
- (void)render;
@end
@implementation GLView
- (id)initWithFrame:(NSRect)frameRect
{
mpTimer= NULL;
static const NSOpenGLPixelFormatAttribute attr[]= {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFADepthSize, 24,
NSOpenGLPFAStencilSize, 8,
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
0
};
NSOpenGLPixelFormat* format= [[NSOpenGLPixelFormat alloc] initWithAttributes:attr];
self= [super initWithFrame:frameRect pixelFormat:format];
if( self ){
// (1) Retina 対応
[self setWantsBestResolutionOpenGLSurface:YES];
mpTimer= [NSTimer timerWithTimeInterval:1.0/60.0
target:self
selector:@selector(render)
userInfo:self
repeats:true];
if( mpTimer ){
[[NSRunLoop currentRunLoop] addTimer:mpTimer forMode:NSRunLoopCommonModes];
}
}
format= nil;
return self;
}
- (void)prepareOpenGL
{
[super prepareOpenGL];
GLint vsync= GL_TRUE;
[[self openGLContext] setValues:&vsync forParameter:NSOpenGLCPSwapInterval];
[[self openGLContext] makeCurrentContext];
// 〜 (2) OpenGL 初期化
}
- (void)update
{
[super update];
}
- (void)reshape
{
[super reshape];
NSRect brect= [self bounds];
// (1.1) Retina 対応
NSRect rrect= [self convertRectToBacking:brect];
float width= rrect.size.width;
float height= rrect.size.height;
// 〜 (3) screen サイズ設定など
}
- (void)drawRect:(NSRect)rect
{
}
- (void)render
{
[[self openGLContext] makeCurrentContext];
// 〜 (4) OpenGL の描画
[[self openGLContext] flushBuffer];
}
- (BOOL)isOpaque
{
return YES;
}
Buffer Object の作成や Shader のコンパイルは (2) で行います。
(4) が実際の描画です。 glClear() 〜 glDrawElements() など。
(3) は Window のリサイズに合わせて Viewport を再設定し、
必要に応じて Projection Matrix 等を作り直します。
Retina Display に対応するには (1) の
[self setWantsBestResolutionOpenGLSurface:YES]
を追加します。
この場合 OpenGL からは 4 倍の解像度に見えることになります。
resize 時もサイズ調整が必要で、(1.1) の
[self convertRectToBacking:brect] が変換を行っています。
同じように Mouse Event 等の座標を GL 座標に合わせるには
[self convertPointToBacking:pos] を使います。
当初 Window の Resize に GLView が追従してきませんでした。
設定を比べた結果、Use Autolayout を外すと View の Autosizing を
設定できるようになりました。

↓

wgl/egl のような初期設定がなく NSOpenGLView は非常に簡単でした。
ただし initWithFrame の Profile 指定にあるように OS X 10.8
では OpenGL 3.2 までしか対応していないようです。
NSOpenGLProfileVersion3_2Core は NSOpenGL.h で定義されています。
10.9 から OpenGL 4 対応になるらしいので、GL4 の新しい
機能を使うには OS のサポートを待つ必要があります。
以前 Nexus 7 (Ubuntu) で動かしていたプログラム↓も移植できました。
