MFCでOpenGL

ダイアログベースでプロジェクトを作成

リソースエディタで、ピクチャーコントロールを貼り付け。

DDX変数を作成します。

PictureControlは、CStaticの変数として作成することになります。
もしくは、CStaticの拡張クラスとして新しくCOpenGLControlというようなクラスを作ってもいいかも。
ちゃんとDoDataExchangeでダイアログ上のIDと関連付けられてるか確認すること。

DDX_Control(pDX, IDC_OPENGL, mOpenGLControl);

こんな風に

CDC変数を加える

CDC* m_pDCという変数をダイアログのメンバに加える

HGLRC変数を加える

この変数の「アクセス」は "private", 「変数の種類」は "HGLRC" とします. 「変数名」は "m_GLRC" ということにします. 最後に「完了」をクリックします.

BOOL SetUpPixelFormat(HDC hdc)という関数を作る

BOOL COpenGLControl::SetUpPixelFormat(HDC hdc)
{
 
    PIXELFORMATDESCRIPTOR pfd = {
        sizeof(PIXELFORMATDESCRIPTOR),  // PFD のサイズ
        1,                              // バージョン
        PFD_DRAW_TO_WINDOW |            // ウィンドウに描画する
        PFD_SUPPORT_OPENGL |            // OpenGL を使う
        PFD_DOUBLEBUFFER,               // ダブルバッファリングする
        PFD_TYPE_RGBA,                  // RGBA モード
        24,                             // カラーバッファは 24 ビット
        0, 0, 0, 0, 0, 0,               //  (各チャンネルのビット数は指定しない) 
        0, 0,                           // アルファバッファは使わない
        0, 0, 0, 0, 0,                  // アキュムレーションバッファは使わない
        32,                             // デプスバッファは 32 ビット
        0,                              // ステンシルバッファは使わない
        0,                              // 補助バッファは使わない
        PFD_MAIN_PLANE,                 // メインレイヤー
        0,                              //  (予約) 
        0, 0, 0                         // レイヤーマスクは無視する
    };
 
    int pf = ChoosePixelFormat(hdc, &pfd);
 
    if (pf != 0) return SetPixelFormat(hdc, pf, &pfd);
 
    return FALSE;
}

OnInitDialogにOpenGLの初期化処理を書く

void COpenGLControl::OnInitDialog(void)
{
    m_pDC = new CClientDC(this);
    m_pDC->m_hDC = GetDC()->GetSafeHdc();
    if (SetUpPixelFormat(m_pDC->m_hDC) != FALSE) {
        m_GLRC = wglCreateContext(m_pDC->m_hDC);
        wglMakeCurrent(m_pDC->m_hDC, m_GLRC);
 
        CRect rc;
        GetClientRect(&rc);
        reshape(rc.Width(),rc.Height());
        init();
 
    }
}

OnPaintにdiplay関数でかくような内容を書く

// ダイアログに最小化ボタンを追加する場合、アイコンを描画するための
//  下のコードが必要です。ドキュメント/ビュー モデルを使う MFC アプリケーションの場合、
//  これは、Framework によって自動的に設定されます。
 
void CPermittivityAnalyzerDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // 描画のデバイス コンテキスト
 
        SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
 
        // クライアントの四角形領域内の中央
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;
 
        // アイコンの描画
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialogEx::OnPaint();
          // OpenGL による描画
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    // ここでシーンを描く
 
    SwapBuffers(m_pDC->m_hDC);
    }
}

注意(今まで使えたけどMFCにして以来使うと実行時エラーになる関数)

  • glBitmapString…文字は別の方法で描こう
  • glutPostRedisplay();….OnPaint()と書き換えてしまってok
  • glutSwapBuffers()…winGDI.hのSwapBuffers(HDC)を使おう。
サポートサイト Wikidot.com mfcopengl