2013/09/27
Mac OS X で OpenGL の描画 (Xcode5/retina)
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.mm を作成。
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) で動かしていたプログラム↓も移植できました。

参考にさせていただきました。
・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 <Cocoa/Cocoa.h> @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) で動かしていたプログラム↓も移植できました。
