レンダリングコンテキストとは?

レンダリングコンテキストは,無視しても簡単なプログラムなら問題なく動作するため,ある意味始末に困るものです.特にGLUTを使うと,コンテキストに関するプログラミングをする必要がないため,初心者には,レンダリングコンテキストに依存するコードが必要となった場合に対処が難しくなるのである.
レンダリングコンテキストとは,いわば描画のためのOpenGLの状態である.コンテキストとは,直訳すると「文脈,前後関係,状況」という意味であり,OpenGLは,ステート(状態)駆動である.描画している線の太さ,印面消去のポリゴンの描画方向などびょうがに関わる種々の状態の設定を常に変化させながらプログラミングを行うものである.例えば,glEnable( GL_CULLING )等で,この命令以後は,カリングを行うように設定することになる.
複数のレンダリングコンテキストを扱うプログラムでは,現在コーディングしている部分が,どのコンテキストに向けて行っているかを常に把握しなければならない.つまり,複数のコンテキストを利用する場合,この把握がずれると,あらぬコンテキストに描画されたり,予期せぬ動作が発生することがあるのである.

概要

レンダリングコンテキストは,ピクセルフォーマットとOSのデバイスコンテキストから作成する.つまりOS毎でその処理方法,APIは異なる.
ただどんなOSでもピクセルフォーマットを使うという点では同じである.Windowsではウィンドウにあるデバイスコンテキストを取得し,それに対してピクセルフォーマットに適合するレンダリングコンテキストを作成する.基本的にひとつのデバイスコンテキストについてレンダリングコンテキストひとつを持つ.このレンダリングコンテキストには,ディスプレイリスト,テクスチャ,フォントなどの情報が格納される.
レンダリングコンテキストを複数持つアプリケーションをプログラミングする場合,あるレンダリングコンテキストで使用しているディスプレイリストやテクスチャを他のレンダリングコンテキストからコールしても使えません.元となる情報がそのレンダリングコンテキストに含まれていないからです.
しかしながら,ひとつのアプリケーションでひとつのレンダリングコンテキストしか扱わない場合は.コンテキスト間の処理をする必要がないので,これらを意識する必要がないわけです.マルチウィンドウなどのアプリケーションでは事情が異なります.ひとつのアプリケーション上でOpenGLのコンテキストが多数現れることがあるからです.

コンテキスト作成

glVertexなどの一連のOpenGLの命令には宛先がありません.つまりどのコンテキストに命令を出すか?という記述がないわけです.暗黙の了解で,現在カレント・レンダリングコンテキストとなっているコンテキストに,命令されます.そのため,コンテキストをちゃんと切り替えないと,思い通りにOpenGLが動かないという事態になるわけです.
まず,コンテキストの作り方ですが, Windowsであればこうなります.

//デバイスコンテキスト
if (!(hDC=GetDC(hWnd))){
MessageBox(hWnd,"Getting HDC Failed....","ERROR",MB_OK);
return NULL;
}
//ピクセルフォーマットの指定
if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){
MessageBox(hWnd,
"ChoosePixelFormat Failed....", "Error", MB_OK);
return NULL;
}
//ピクセルフォーマットの設定
if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){
MessageBox(hWnd,
"SetPixelFormat Failed....", "Error", MB_OK);
return NULL;
}
//OpenGLレンダリングコンテキストの作成
if (!(hRC=wglCreateContext(hDC))){
MessageBox(NULL,"Creating HGLRC Failed....","ERROR",MB_OK);
return NULL;
}
ReleaseDC(hWnd,hDC);

Windowsの場合,絵に描いたようにデバイスコンテキストとピクセルフォーマットからレンダリングコンテキストを作成しています.他のOSでもだいたい同じ?です.

設定方法

これを作成した後,このコンテキストをカレントコンテキストに設定します.カレントコンテキストとは,今から実行するOpenGLへの命令を受けとるレンダリングコンテキストのことです.これをちゃんと設定しないと他のコンテキストへOpenGLの命令が行ってしまうわけです.カレントコンテキストの設定はwglMakeCurrentや,CocoaのmakeCurrentContextメッセージなどで行います.


切り替えるタイミングについてですが,これは特にアニメーションさせる場合は再描画するとき,OpenGLの描画コードの直前がベストでしょう.同時に多くのウィンドウ上でOpenGLを表示させるとき,ひとつひとつのデバイスコンテキストが描画命令を受けます.このとき,OpenGLの描画コードが呼ばれる前にそのコンテキストがカレントコンテキストになっていないと,その直前に設定したカレントコンテキストの方へOpenGLの命令が行ってしまうからです.