▽OpenGLの初期化

MFCベースのプログラムでOpenGLを使用するときのサンプルです。主に、OpenGL関係の初期化に的を絞ってあります。

サンプルプログラム
sk00a-04.lzh

OpenGLの初期化・終了に関する機能は、すべてskGLViewクラスにまとめてあります。

実際の表示を行うCSk00ViewクラスではskGLViewクラスを親クラスとして、必要な部分だけを書き換える事で最小限の手間でOpenGLを使用しています。

以下、skGLViewクラスからポイントを絞って解説。

○OpenGLの初期化

OpenGLの初期化に関する処理はウィンドウを作成する前のスタイル変更と、ウィンドウ作成後にレンダリングコンテキストを作成する処理の二つの処理からなっています。

A)ウィンドウのスタイルを変更

ウィンドウのスタイルにWS_CLIPCHILDRENとWS_CLIPSIBLINGSを指定します。

BOOL skGLView::PreCreateWindow(CREATESTRUCT& cs)
{
    cs.style    |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;

    return  CView::PreCreateWindow( cs );
}

親ウィンドウとOpenGLで使用するウィンドウでピクセルフォーマットが異なる場合があるのでこの指定が必要になります。この指定をしなかった場合、SetPixelFormat()が失敗する事があります。

B)レンダリングコンテキストの作成

ウィンドウの作成が終了したあと、レンダリングコンテキストを作成します。この処理はskGLView::OnGLCreate()の中で行っています。

まず、指定された情報に従ってピクセルフォーマットを選択します。ピクセルフォーマットの指定に必要な情報はskGLViewクラスのコンストラクタでm_pfdに格納されます。

ステンシルバッファを使用する場合など、ピクセルフォーマットに関する指定を変更したい場合は、skGLViewクラスの継承先のコンストラクタでm_pfdの値を変更しておきます。

必要ならパレットの準備も行います。ただ、冷静に考えるとパレットが必要な状況では、OpenGLの初期化は失敗と見なした方が良いかもしれません。

準備が終わったところで、wglCreateContext()関数を使ってレンダリングコンテキストを作成しておきます。これで、OpenGL関係の初期化はとりあえず終了です。

レンダリングコンテキストはスレッドに固有らしい。
マルチスレッドの開発をするときは要注意。

○OpenGLの終了処理

OpenGLの終了処理は、skGLView::OnGLDestroy()で行われます。

終了処理は、実際にはプログラミングで作成したレンダリングコンテキストを破棄するだけです。パレットを作成していた場合は、ついでにパレットも破棄しています。

○OpenGLの関数を使うときの準備

OpenGLの関数を利用するときにはレンダリングコンテキストをデバイスコンテキストに結びつける必要があります。また、OpenGLの使用が終了したときは、レンダリングコンテキストをはずしておきます。

これらの処理にはwglMakeCurrent()関数を使用しますが、skGLViewクラスでは、この処理を簡単にするために、skGLView::GLBegin()とskGLView::GLEnd()を用意してあります。

void            skGLView::GLBegin( CDC* dc )
{
    //      OpenGLを使用可能にする

    //      必要ならばパレットを設定

    if( m_pal != NULL ) {
        SelectPalette( dc->m_hDC,m_pal,FALSE );
        RealizePalette( dc->m_hDC );
    }

    //      レンダリングコンテキストを設定

    wglMakeCurrent( dc->m_hDC,m_rc );
}
void            skGLView::GLEnd( CDC* dc )
{
    //      OpenGLの使用を終了する

    //      レンダリングコンテキストをはずす

    wglMakeCurrent( dc->m_hDC,NULL );
}

skGLViewクラスを親クラスとして新しくビュークラスを作成した場合、通常はOpenGL関係の設定はGLSetState()で、OpenGLの描画はOnGLDraw()ですべて行います。

この場合、GLBegin()とGLEnd()の処理はskGLViewクラス側で自動的に行われるため、特に意識する必要はありませんが、それ以外の場所でOpenGL関係の関数を利用する場合は、その前後でGLBegin()とGLEnd()を自力で呼び出してください。

○その他

skGLViewクラスでは、glEnable()やglClearColor()などのOpenGL関係の設定を変更する処理はGLSetState()の中にまとめて記述します。

仮想関数にしてあるので、skGLViewクラスの子クラスでGLSetState()をオーバーライドしてください。

同様に表示に関する処理はOnGLDraw()で行うようになっています。こちらもオーバーライドして自由に使ってください。

そのほかの部分もそれなりに柔軟に仕上げてあるはずです。詳細は、ソースを直接読んでください。


[skLib] Presented by See.Ku [2005/1/10]