OpenGLプログラム 雛形の作り方 (Win32 MFC)

since 2001/05/08
last modified 2001/05/08

CCube0Dlgクラス設定編


ヘッダーファイル"Cube0Dlg.h"編

  1. 記述"CCube0Dlg(CWnd* pParent = NULL);"の下に以下の記述を追加する。

       void Idle();
       void Init();
       void Draw();
     
       CClientDC* m_pDC;
       HGLRC m_hRC;
    
       double anglex, angley, anglez;
       double camerax, cameray, cameraz;
       
  2. [MFC ClassWizard]を開き、[メッセージマップ]タグの[クラス名(N)]コンボボックスに "CCube0Dlg"を設定、[メッセージ(G)]リストボックスに"PreCreateWindow"を設定し、 [関数の追加(A)ボタン]を押下し、メンバ関数"PreCreateWindow()"を追加する。

  3. [MFC ClassWizard]を開き、[メッセージマップ]タグの[クラス名(N)]コンボボックスに "CCube0Dlg"を設定、[メッセージ(G)]リストボックスに"PostNcDestroy"を設定し、 [関数の追加(A)ボタン]を押下し、メンバ関数"PostNcDestroy()"を追加する。

  4. [MFC ClassWizard]を開き、[メッセージマップ]タグの[クラス名(N)]コンボボックスに "CCube0Dlg"を設定、[メッセージ(G)]リストボックスに"WM_SIZE"を設定し、 [関数の追加(A)ボタン]を押下し、メンバ関数"OnSize()"を追加する。

  5. [MFC ClassWizard]を開き、[メッセージマップ]タグの[クラス名(N)]コンボボックスに "CCube0Dlg"を設定、[メッセージ(G)]リストボックスに"WM_CLOSE"を設定し、 [関数の追加(A)ボタン]を押下し、メンバ関数"OnClose()"を追加する。

  6. [MFC ClassWizard]を開き、[メッセージマップ]タグの[クラス名(N)]コンボボックスに "CCube0Dlg"を設定、[メッセージ(G)]リストボックスに"WM_DESTROY"を設定し、 [関数の追加(A)ボタン]を押下し、メンバ関数"OnDestroy()"を追加する。

ソースファイル"Cube0Dlg.cpp"編
  1. コンストラクタ"CCube0Dlg::CCube0Dlg(CWnd* pParent /*=NULL*/) : CDialog(CCube0Dlg::IDD, pParent)"の最後に以下のように記述を追加する。

       m_pDC = NULL;
       anglex = 0.0; angley = 0.0; anglez = 150;
       camerax = 0.0; cameray = 0.0; cameraz = -10.0;
       

  2. 関数"BOOL CCube0Dlg::OnInitDialog()"の記述"// TODO: 特別な..."の下に "Init();"と追加する。

  3. 関数"BOOL CCube0Dlg::PreCreateWindow(CREATESTRUCT& cs)"を以下のように書きかえる。

      BOOL CCube0Dlg::PreCreateWindow(CREATESTRUCT& cs) 
      {
         cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
         return CDialog::PreCreateWindow(cs);
      }
      

  4. 関数"void CCube0Dlg::PostNcDestroy()"を以下のように書きかえる。

      void CCube0Dlg::PostNcDestroy() 
      {
         wglMakeCurrent(0, 0);
         wglDeleteContext(m_hRC);	
         CDialog::PostNcDestroy();
         delete this;
      }
      

  5. 関数"void CCube0Dlg::OnSize(UINT nType, int cx, int cy)"を以下のように書きかえる。

      void CCube0Dlg::OnSize(UINT nType, int cx, int cy) 
      {
         CDialog::OnSize(nType, cx, cy);
         if (cx && cy) glViewport(0, 0, cx, cy);
      }
      

  6. 関数"void CCube0Dlg::OnClose()"を以下のように書きかえる。

      void CCube0Dlg::OnClose() 
      {
         CDialog::OnClose();
         DestroyWindow();
      }
      

  7. 関数"void CCube0Dlg::OnDestroy()"を以下のように書きかえる。

      void CCube0Dlg::OnDestroy() 
      {
         CDialog::OnDestroy();
         if (m_pDC) delete m_pDC;	
      }
      

  8. 関数"void CCube0Dlg::Idle()"を追加する。

      void CCube0Dlg::Idle() 
      {
         if (GetAsyncKeyState(VK_LEFT)) anglex -= 2.0;
         if (GetAsyncKeyState(VK_RIGHT)) anglex += 2.0;
         if (GetAsyncKeyState(VK_UP)) anglez -= 2.0;
         if (GetAsyncKeyState(VK_DOWN)) anglez += 2.0;
         if (GetAsyncKeyState(VK_NEXT)) cameraz -= 0.5;
         if (GetAsyncKeyState(VK_PRIOR)) cameraz += 0.5;
    
         Draw();
         Sleep(10);
      }
      

  9. 関数"void CCube0Dlg::Init()"を追加する。

      void CCube0Dlg::Init() 
      {
         // CTopAppのOnIdle用にビューへのポインタを設定
         ((CCube0App*)AfxGetApp())->pView = this;
    
         if (m_hRC) {
            wglMakeCurrent(0, 0);
            wglDeleteContext(m_hRC);
            m_hRC = NULL;
          }
    
         if (m_pDC) delete m_pDC;   
         m_pDC = new CClientDC(this);
    
         static PIXELFORMATDESCRIPTOR pfd = {
            sizeof (PIXELFORMATDESCRIPTOR), // strcut size 
            1,                              // Version number
            PFD_DRAW_TO_WINDOW |    // Flags, draw to a window,
            PFD_SUPPORT_OPENGL | // use OpenGL
            PFD_DOUBLEBUFFER, // use OpenGL
            PFD_TYPE_RGBA,          // RGBA pixel values
            24,                     // 24-bit color
            0, 0, 0,                // RGB bits & shift sizes.
            0, 0, 0,                // Don't care about them
            0, 0,                   // No alpha buffer info
            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,                      // No layer mask
            0,                      // No visible mask
            0                       // No damage mask
         };
    
         int nMyPixelFormatID;
         nMyPixelFormatID = ChoosePixelFormat( m_pDC->GetSafeHdc(), &pfd );
    
         SetPixelFormat( m_pDC->GetSafeHdc(), nMyPixelFormatID, &pfd );
    
         m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
         if (!m_hRC) {
            AfxMessageBox("OpenGLの初期化に失敗しました");
            exit(1);
         }
         wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
         glClearColor(1.0f, 1.0f, 1.0f, 1.0f) ;
    	
         // ビュー設定
         glMatrixMode(GL_PROJECTION);
         glLoadIdentity();
         gluPerspective(40, 1, 0.1, 200);
    
         /// Zバッファー(デプス・バッファー)の有効化
         glEnable(GL_DEPTH_TEST);
         glDepthFunc(GL_LEQUAL);
    
         //// 光源の有効化と色をセット
         //// 光源は、たいていLIGHT0 からLIGHT7まで使えます
         //// 使う光源は、glEnableで有効化してやります
         glEnable(GL_LIGHTING) ;   // Enable lighting
         glEnable(GL_LIGHT0) ;     // Light0 ON
      }
      

  10. 関数"void CCube0Dlg::Draw()"を追加する。

      void CCube0Dlg::Draw() 
      {
         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;
    
         // カメラセット
         glMatrixMode(GL_MODELVIEW);
         glLoadIdentity();
         glTranslated(camerax, cameray, cameraz);
         glRotated(anglez, 1, 0, 0);
         glRotated(anglex, 0, 0, 1);
    
         // オプジェクトセット
         glBegin(GL_QUADS);
    	
            /// Z軸に垂直な面
    	glMaterialfv(GL_FRONT,GL_AMBIENT,red);
    	glNormal3f(0,0,1);
    	glVertex3f(-1,-1,1);
    	glVertex3f( 1,-1,1);
    	glVertex3f( 1, 1,1);
    	glVertex3f(-1, 1,1);
    
    	glNormal3f(0,0,-1);
    	glVertex3f(-1,-1,-1);
    	glVertex3f( 1,-1,-1);
    	glVertex3f( 1, 1,-1);
    	glVertex3f(-1, 1,-1);
    
    	/// X軸に垂直な面
    	glMaterialfv(GL_FRONT,GL_AMBIENT,green);
    	glNormal3f(1,0,0);
    	glVertex3f(1,-1, 1);
    	glVertex3f(1, 1, 1);
    	glVertex3f(1, 1,-1);
    	glVertex3f(1,-1,-1);
    
    	glNormal3f(-1,0,0);
    	glVertex3f(-1,-1, 1);
    	glVertex3f(-1, 1, 1);
    	glVertex3f(-1, 1,-1);
    	glVertex3f(-1,-1,-1);
    
    	/// Y軸に垂直な面
    	glMaterialfv(GL_FRONT,GL_AMBIENT,blue);
    	glNormal3f(0,1,0);
    	glVertex3f(-1, 1, 1);
    	glVertex3f( 1, 1, 1);
    	glVertex3f( 1, 1,-1);
    	glVertex3f(-1, 1,-1);
    
    	glNormal3f(0,-1,0);
    	glVertex3f(-1,-1, 1);
    	glVertex3f( 1,-1, 1);
    	glVertex3f( 1,-1,-1);
    	glVertex3f(-1,-1,-1);
    
    	glEnd();	
         glFinish();
    
         SwapBuffers(m_pDC->GetSafeHdc());
      }
      


[前のPageに戻る]