0001: //-----------------------------------------------------------------------------
0002: // File: GLApp.cpp
0003: //
0004: // Desc: Application class for the imagire's OprnGL samples framework library.
0005: //-----------------------------------------------------------------------------
0006: #define STRICT
0007: #include <windows.h>
0008: #include <tchar.h>
0009: #include <mmsystem.h>
0010: 
0011: #include "GLApp.h"
0012: //-----------------------------------------------------------------------------
0013: // Global access to the app (needed for the global WndProc())
0014: //-----------------------------------------------------------------------------
0015: static CD3DApplication* g_pD3DApp = NULL;
0016: 
0017: LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
0018: 
0019: //-----------------------------------------------------------------------------
0020: // Name: WndProc()
0021: // Desc: Static msg handler which passes messages to the application class.
0022: //-----------------------------------------------------------------------------
0023: LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
0024: {
0025:     return g_pD3DApp->MsgProc( hWnd, uMsg, wParam, lParam );
0026: }
0027: 
0028: //-------------------------------------------------------------
0029: // Name: CMyD3DApplication()
0030: // Desc: アプリケーションのコンストラクタ
0031: //-------------------------------------------------------------
0032: CD3DApplication::CD3DApplication()
0033: {
0034:     g_pD3DApp = this;
0035:     m_bGL = FALSE;
0036:     m_bDeviceObjectsInited = false;
0037:     m_bDeviceObjectsRestored = false;
0038: 
0039:     m_dwCreationWidth           = 300;
0040:     m_dwCreationHeight          = 300;
0041:     m_strWindowTitle            = TEXT( "My Application" );
0042: 
0043:     m_fTime = 0;
0044:     m_fElapsedTime = 0;
0045: }
0046: //-------------------------------------------------------------
0047: HRESULT CD3DApplication::Create( HINSTANCE hInst, int nCmdShow )
0048: {
0049:     // グローバル ストリングを初期化します
0050:     WNDCLASSEX wcex;
0051: 
0052:     wcex.cbSize = sizeof(WNDCLASSEX); 
0053:     wcex.style      = CS_HREDRAW | CS_VREDRAW;
0054:     wcex.lpfnWndProc    = (WNDPROC)WndProc;
0055:     wcex.cbClsExtra     = 0;
0056:     wcex.cbWndExtra     = 0;
0057:     wcex.hInstance      = hInst;
0058:     wcex.hIcon          = NULL;
0059:     wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
0060:     wcex.hbrBackground  = NULL;
0061:     wcex.lpszMenuName   = NULL;
0062:     wcex.lpszClassName  = "OpenGL Application";
0063:     wcex.hIconSm        = NULL;
0064:     RegisterClassEx( &wcex );
0065: 
0066:     // アプリケーションの初期化を行います:
0067:    m_hWnd = CreateWindow( wcex.lpszClassName, m_strWindowTitle, WS_OVERLAPPEDWINDOW,
0068:       CW_USEDEFAULT, 0, m_dwCreationWidth, m_dwCreationHeight, NULL, NULL, hInst, NULL);
0069:    if( !m_hWnd ) return FALSE;
0070: 
0071:     // Save window properties
0072:     m_dwWindowStyle = GetWindowLong( m_hWnd, GWL_STYLE );
0073:     GetWindowRect( m_hWnd, &m_rcWindowBounds );
0074:     GetClientRect( m_hWnd, &m_rcWindowClient );
0075: 
0076:     this->OneTimeSceneInit();
0077: 
0078:    if(FAILED(Initialize3DEnvironment())){
0079:         return FALSE;
0080:     }
0081:     m_bGL = TRUE;
0082: 
0083:     ShowWindow( m_hWnd, nCmdShow );
0084:     UpdateWindow( m_hWnd );
0085: 
0086:    return TRUE;
0087: }
0088: //OpenGLレンダリングコンテキストの作成
0089: //ピクセルフォーマットの設定
0090: HRESULT CD3DApplication::Initialize3DEnvironment()
0091: {
0092:     HGLRC hRC;
0093:     HDC hDC;
0094:     int pixelformat;
0095: 
0096:     static PIXELFORMATDESCRIPTOR pfd = {
0097:     sizeof(PIXELFORMATDESCRIPTOR),      //この構造体のサイズ
0098:     2,                                  //OpenGLバージョン
0099:     PFD_DRAW_TO_WINDOW |                //Windowスタイル
0100:         PFD_SUPPORT_OPENGL |            //OpenGL
0101:         PFD_DOUBLEBUFFER,               //ダブルバッファ使用可能
0102:     PFD_TYPE_RGBA,                      //RGBAカラー
0103:     24,                                 //色数
0104:     0, 0,                               //RGBAのビットとシフト設定      
0105:     0, 0,                               //G
0106:     0, 0,                               //B
0107:     0, 0,                               //A
0108:     0,                                  //アキュムレーションバッファ
0109:     0, 0, 0, 0,                         //RGBAアキュムレーションバッファ
0110:     16,                                 //Zバッファ 
0111:     0,                                  //ステンシルバッファ
0112:     0,                                  //使用しない
0113:     PFD_MAIN_PLANE,                     //レイヤータイプ
0114:     0,                                  //予約
0115:     0, 0, 0                             //レイヤーマスクの設定・未使用
0116:     };
0117: 
0118:     //デバイスコンテキスト
0119:     if (!(hDC=GetDC(m_hWnd))){
0120:         MessageBox(m_hWnd,"Getting HDC Failed....","ERROR",MB_OK);
0121:         return NULL;
0122:     }
0123:     //ピクセルフォーマットの指定
0124:     if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){
0125:         MessageBox(m_hWnd, "ChoosePixelFormat Failed....", "Error", MB_OK);
0126:         return NULL;
0127:     }
0128:     //ピクセルフォーマットの設定
0129:     if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE){
0130:         MessageBox(m_hWnd, "SetPixelFormat Failed....", "Error", MB_OK);
0131:         return NULL;
0132:     }
0133:     //OpenGLレンダリングコンテキストの作成
0134:     if (!(hRC=wglCreateContext(hDC))){
0135:         MessageBox(NULL,"Creating HGLRC Failed....","ERROR",MB_OK);
0136:         return NULL;
0137:     }
0138:     ReleaseDC(m_hWnd,hDC);
0139:     
0140:     if(NULL==hRC) return -1;
0141: 
0142:     //カレントコンテキスト
0143:     hDC = GetDC(m_hWnd);
0144:     wglMakeCurrent(hDC,hRC);
0145: 
0146: 
0147:     // Depth テストの初期設定
0148:     glDepthFunc(GL_LESS);
0149:     glEnable(GL_DEPTH_TEST);
0150: 
0151:     glEnable(GL_CULL_FACE);
0152:     glCullFace(GL_FRONT);
0153:     //クライアント領域の塗りつぶし色の設定
0154:     glClearColor( 0.0, 0.0, 0.0, 0.0 );
0155:     //デプスバッファクリア値の設定
0156:     glClearDepth( 1.0 );
0157: 
0158:     // アプリケーションのデバイスに依存したオブジェクトを初期化する
0159:     HRESULT hr = InitDeviceObjects();
0160:     if( FAILED(hr) )
0161:     {
0162:         DeleteDeviceObjects();
0163:     }
0164:     else
0165:     {
0166:         m_bDeviceObjectsInited = true;
0167:         hr = RestoreDeviceObjects();
0168:         if( FAILED(hr) )
0169:         {
0170:             InvalidateDeviceObjects();
0171:         }
0172:         else
0173:         {
0174:             m_bDeviceObjectsRestored = true;
0175:             return S_OK;
0176:         }
0177:     }
0178: 
0179: 
0180:     return S_OK;
0181: }
0182: //-----------------------------------------------------------------------------
0183: // Name: Reset3DEnvironment()
0184: // Desc:
0185: //-----------------------------------------------------------------------------
0186: HRESULT CD3DApplication::Reset3DEnvironment()
0187: {
0188:     HRESULT hr;
0189: 
0190:     // VRAM上のオブジェクトを開放する
0191:     if( m_bDeviceObjectsRestored )
0192:     {
0193:         m_bDeviceObjectsRestored = false;
0194:         InvalidateDeviceObjects();
0195:     }
0196: 
0197:     // アプリケーションのデバイスに依存したオブジェクトを初期化する
0198:     hr = RestoreDeviceObjects();
0199:     if( FAILED(hr) )
0200:     {
0201:         InvalidateDeviceObjects();
0202:         return hr;
0203:     }
0204: 
0205:     return S_OK;
0206: }
0207: //-------------------------------------------------------------
0208: //
0209: //
0210: //-------------------------------------------------------------
0211: void    CD3DApplication::Cleanup3DEnvironment()
0212: {
0213:     if( m_bGL )
0214:     {
0215:         if( m_bDeviceObjectsRestored )
0216:         {
0217:             m_bDeviceObjectsRestored = false;
0218:             InvalidateDeviceObjects();
0219:         }
0220:         if( m_bDeviceObjectsInited )
0221:         {
0222:             m_bDeviceObjectsInited = false;
0223:             DeleteDeviceObjects();
0224:         }
0225: 
0226:         //OpenGLレンダリングコンテキストと
0227:         //デバイスコンテキストを取得
0228:         HGLRC hRC = wglGetCurrentContext();
0229:         HDC hDC = wglGetCurrentDC();
0230: 
0231:         //カレントコンテキストを解放
0232:         wglMakeCurrent(NULL, NULL);
0233:         if(!hRC){
0234:             //OpenGLレンダリングコンテキストがない
0235:             MessageBox(m_hWnd,"Release HGLRC Failed....","ERROR",MB_OK);
0236:         }
0237:         if(hRC){
0238:             //解放
0239:             wglDeleteContext(hRC);
0240:         }
0241:         if(!hDC){
0242:             //デバイスコンテキストがない
0243:             MessageBox(m_hWnd,"Release HDC Failed....","ERROR",MB_OK);
0244:         }
0245:         if(hDC){
0246:             //解放
0247:             ReleaseDC(m_hWnd, hDC);
0248:         }
0249: 
0250:         m_bGL = FALSE;
0251:     }
0252: }
0253: //-------------------------------------------------------------
0254: INT CD3DApplication::Run()
0255: {
0256:     MSG msg;
0257: 
0258:     // メイン メッセージ ループ:
0259:     while( GetMessage(&msg, NULL, 0, 0) ) 
0260:     {
0261:         if( !TranslateAccelerator (msg.hwnd, NULL, &msg) ) 
0262:         {
0263:             TranslateMessage( &msg );
0264:             DispatchMessage( &msg );
0265: 
0266:             if( FAILED( Render3DEnvironment() ) )
0267:                 SendMessage( m_hWnd, WM_CLOSE, 0, 0 );
0268:         }
0269:     }
0270: 
0271:     return msg.wParam;
0272: }
0273: 
0274: 
0275: 
0276: 
0277: // Name: Render3DEnvironment()
0278: // Desc: Draws the scene.
0279: //-----------------------------------------------------------------------------
0280: HRESULT CD3DApplication::Render3DEnvironment()
0281: {
0282:     HRESULT hr;
0283: 
0284:     // 時間を計測
0285:     FLOAT time = 0.001f*(FLOAT)timeGetTime();
0286:     m_fElapsedTime = (FLOAT)(time-m_fTime);
0287:     m_fTime = time;
0288: 
0289:     // アイドル関数をまわす
0290:     if( FAILED( hr = FrameMove() ) )
0291:         return hr;
0292: 
0293:     // 描画関数をまわす
0294:     if( FAILED( hr = Render() ) )
0295:         return hr;
0296: 
0297: //    UpdateStats();
0298: 
0299:     //ダブルバッファ
0300:     HDC hDC = wglGetCurrentDC();
0301:     SwapBuffers(hDC);
0302: 
0303:     return S_OK;
0304: }
0305: 
0306: 
0307: 
0308: 
0309: //
0310: //  関数: WndProc(HWND, unsigned, WORD, LONG)
0311: //
0312: //  用途: メイン ウィンドウのメッセージを処理します。
0313: //
0314: //  WM_COMMAND  - アプリケーション メニューの処理
0315: //  WM_PAINT    - メイン ウィンドウの描画
0316: //  WM_DESTROY  - 終了メッセージの通知とリターン
0317: //
0318: //
0319: LRESULT CD3DApplication::MsgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
0320: {
0321:     int wmId, wmEvent;
0322: 
0323:     switch( message ) 
0324:     {
0325:         case WM_CREATE:// 初期化
0326:             break;
0327:         case WM_PAINT:// 描画
0328:             if( m_bGL && //!m_bActive && m_bWindowed &&
0329:                 m_bDeviceObjectsInited && m_bDeviceObjectsRestored ){
0330:                 Render();
0331:                 //ダブルバッファ
0332:                 HDC hDC = wglGetCurrentDC();
0333:                 SwapBuffers(hDC);
0334:             }
0335:             break;
0336:         case WM_SIZE:
0337:             HandlePossibleSizeChange();         //リサイズ時のOpenGLの処理
0338:             break;
0339:         case WM_DESTROY:// 死亡
0340:             Cleanup3DEnvironment();
0341:             FinalCleanup();
0342:             PostQuitMessage( 0 );
0343:             break;
0344: 
0345:         case WM_COMMAND:
0346:             wmId    = LOWORD(wParam); 
0347:             wmEvent = HIWORD(wParam); 
0348:             // メニュー選択の解析:
0349: //          switch( wmId ) 
0350: //          {
0351: //              case IDM_EXIT:
0352: //                 DestroyWindow( hWnd );
0353: //                 break;
0354: //              default:
0355: //                 return DefWindowProc( hWnd, message, wParam, lParam );
0356: //          }
0357:             break;
0358:         default:
0359:             return DefWindowProc( hWnd, message, wParam, lParam );
0360:    }
0361:    return 0;
0362: }
0363: //-----------------------------------------------------------------------------
0364: // Name: HandlePossibleSizeChange()
0365: // Desc: Reset the device if the client area size has changed.
0366: //-----------------------------------------------------------------------------
0367: HRESULT CD3DApplication::HandlePossibleSizeChange()
0368: {
0369:     RECT rcClientOld;
0370:     rcClientOld = m_rcWindowClient;
0371: 
0372:     // Update window properties
0373:     GetWindowRect( m_hWnd, &m_rcWindowBounds );
0374:     GetClientRect( m_hWnd, &m_rcWindowClient );
0375: 
0376:     m_mysdBackBuffer.Width  = m_rcWindowClient.right - m_rcWindowClient.left;
0377:     m_mysdBackBuffer.Height = m_rcWindowClient.bottom - m_rcWindowClient.top;
0378: 
0379:     if( rcClientOld.right - rcClientOld.left !=
0380:         m_rcWindowClient.right - m_rcWindowClient.left ||
0381:         rcClientOld.bottom - rcClientOld.top !=
0382:         m_rcWindowClient.bottom - m_rcWindowClient.top)
0383:     {
0384:         if( m_bGL ) Reset3DEnvironment();
0385:     }
0386: 
0387:     //それによってビューポートを設定する
0388:     glViewport(0, 0, m_mysdBackBuffer.Width, m_mysdBackBuffer.Height);
0389: 
0390:     return S_OK;
0391: }
0392: