OpenGL

VC++(MFC)とOpenGL

MFCとOpenGLの親和性は高い。逆にMFCとDirectXの親和性は低く、現在のバージョンにおいて、MFC+DirectXの組み合わせは難しい。理由としては、そもそもDirectX自体がMFCを前提としなくなったこと。SampleからMFCtex(MFC+DirectXのサンプル)が消えている。MFCtexがあるバージョンは、DirectX9(2003)のようだが、探した限りではMicrosoft上には見当たらなかった(仮にあったとしてもVC++6のものとなる。VC++2005では、そのままコンパイルできない)。

OpenGLのインストール

1.GLUTのダウンロード

下記サイトから"glut-3.7.6-bin.zip"をダウンロードし、適当なフォルダに解凍する。
http://www.xmission.com/~nate/glut.html

2.ファイルのコピー

解凍したファイルを下記ディレクトリに移動する。フォルダ名は環境によって若干異なる。.hは、GLフォルダを作りその中に入れること。
glut.h → C:\Program Files\Microsoft Visual Studio\VC98\Include\GL
.lib → C:\Program Files\Microsoft Visual Studio\VC98\Lib
.dll → C:\WINDOWS\SYSTEM32

MFC(ダイアログベース)+OpenGL

プロジェクト名をhogeとすると、

1.ヘッダファイルの記述

クラスChogeDlgに以下includeを追加
\#include <GL/glaux.h>

2.メンバ変数の追加

クラスChogeDlgに以下変数を追加する
CDC* m_pDC;
HGLRC m_GLRC;

3.メンバ関数の追加

int ChogeDlg::SetDCPixelFormat(HDC hdc)
{
static PIXELFORMATDESCRIPTOR pfd = {
	sizeof (PIXELFORMATDESCRIPTOR),	// Size of this structure
	1,				// Version number
	PFD_DRAW_TO_WINDOW |		// Flags
	PFD_SUPPORT_OPENGL |
	PFD_DOUBLEBUFFER,
	PFD_TYPE_RGBA,			// RGBA pixel values
	24,				// 24-bit color
	0, 0, 0, 0, 0, 0,		// Don't care about these
	0, 0,				// No alpha buffer
	0, 0, 0, 0, 0,			// No accumulation buffer
	32,				// 32-bit depth buffer
	0,				// No stencil buffer
	0,				// No auxiliary buffers
	PFD_MAIN_PLANE,			// Layer type
	0,				// Reserved (must be 0)
	0, 0, 0				// No layer masks
};

int nPixelFormat;
nPixelFormat = ChoosePixelFormat (hdc, &pfd);

if (SetPixelFormat(hdc, nPixelFormat, &pfd) == FALSE){
// SetPixelFormat error
return FALSE ;
}
if (DescribePixelFormat(hdc, nPixelFormat,
	 sizeof(PIXELFORMATDESCRIPTOR),&pfd) == 0) {
// DescribePixelFormat error
return FALSE ;
}
if (pfd.dwFlags & PFD_NEED_PALETTE) {
// Need palete !
}
return TRUE ;
}

void ChogeDlg::InitGL()
{
       m_pDC = new CClientDC(this);            // Get device context
      SetDCPixelFormat(m_pDC->m_hDC);         // Set OpenGL pixel format
       m_GLRC = wglCreateContext (m_pDC->m_hDC);       // Create rendering context
      wglMakeCurrent (m_pDC->m_hDC, m_GLRC);  // Current context set
       glClearColor(0.0f, 0.0f, 0.5f, 1.0f);
}

void ChogeDlg::DrawGL()
{
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;
}
BOOL ChogeDlg::OnInitDialog() の return TRUE; の上に InitGL(); を追加する.

ClassView@ChogeDlg→メッセージ で WM_DESTROY をダブルクリックし, OnDestroy を呼ぶ.
void ChogeDlg::OnDestroy()
{
       CView::OnDestroy();
       // TODO: この位置にメッセージ ハンドラ用のコードを追加してください
       wglMakeCurrent(NULL, NULL);     // free current context
       wglDeleteContext(m_GLRC);       // Delete rendering context
       delete m_pDC;           // Release device context
}

OnPaint に以下の文を追加.
void COpenGLTest2Dlg::OnPaint()
{
       if (IsIconic())
       {
               CPaintDC dc(this); // 描画用のデバイス コンテキスト
               SendMessage(WM_ICONERASEBKGND, (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
       {
               CDialog::OnPaint();
               DrawGL();                       //これを追加
               SwapBuffers(m_pDC->m_hDC);      //これを追加
       }
}

Pictureコントロール上に描画するには、
ダイアログにピクチャボックスを設置する.(大きさは適当)
ID→ID_PICT に書き換え,クラスウィザードで ID_PICT の変数を追加する.
コントロールID タイプ メンバ
IDC_PICT CStatic m_Pict

InitGL() に一文を追加する.
void COpenGLTest2Dlg::InitGL()
{
       m_pDC = new CClientDC(this);         
       m_pDC->m_hDC = m_Pict.GetDC()->GetSafeHdc();  //これを追加
       SetDCPixelFormat(m_pDC->m_hDC);        
       m_GLRC = wglCreateContext (m_pDC->m_hDC);     
       wglMakeCurrent (m_pDC->m_hDC, m_GLRC); 
       glClearColor(0.0f, 0.0f, 0.5f, 1.0f);
}
最終更新:2011年03月22日 15:10