0001: 
0002: 
0003: 
0004: 
0005: 
0006: #define STRICT
0007: #include <windows.h>
0008: #include <tchar.h>
0009: #include <mmsystem.h>
0010: 
0011: #include "GLApp.h"
0012: 
0013: 
0014: 
0015: static CD3DApplication* g_pD3DApp = NULL;
0016: 
0017: LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
0018: 
0019: 
0020: 
0021: 
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: 
0030: 
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:     
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: 
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,                                  
0099:     PFD_DRAW_TO_WINDOW |                
0100:         PFD_SUPPORT_OPENGL |            
0101:         PFD_DOUBLEBUFFER,               
0102:     PFD_TYPE_RGBA,                      
0103:     24,                                 
0104:     0, 0,                               
0105:     0, 0,                               
0106:     0, 0,                               
0107:     0, 0,                               
0108:     0,                                  
0109:     0, 0, 0, 0,                         
0110:     16,                                 
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:     
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:     
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: 
0184: 
0185: 
0186: HRESULT CD3DApplication::Reset3DEnvironment()
0187: {
0188:     HRESULT hr;
0189: 
0190:     
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:         
0227:         
0228:         HGLRC hRC = wglGetCurrentContext();
0229:         HDC hDC = wglGetCurrentDC();
0230: 
0231:         
0232:         wglMakeCurrent(NULL, NULL);
0233:         if(!hRC){
0234:             
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: 
0278: 
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: 
0298: 
0299:     
0300:     HDC hDC = wglGetCurrentDC();
0301:     SwapBuffers(hDC);
0302: 
0303:     return S_OK;
0304: }
0305: 
0306: 
0307: 
0308: 
0309: 
0310: 
0311: 
0312: 
0313: 
0314: 
0315: 
0316: 
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 && 
0329:                 m_bDeviceObjectsInited && m_bDeviceObjectsRestored ){
0330:                 Render();
0331:                 
0332:                 HDC hDC = wglGetCurrentDC();
0333:                 SwapBuffers(hDC);
0334:             }
0335:             break;
0336:         case WM_SIZE:
0337:             HandlePossibleSizeChange();         
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: 
0350: 
0351: 
0352: 
0353: 
0354: 
0355: 
0356: 
0357:             break;
0358:         default:
0359:             return DefWindowProc( hWnd, message, wParam, lParam );
0360:    }
0361:    return 0;
0362: }
0363: 
0364: 
0365: 
0366: 
0367: HRESULT CD3DApplication::HandlePossibleSizeChange()
0368: {
0369:     RECT rcClientOld;
0370:     rcClientOld = m_rcWindowClient;
0371: 
0372:     
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: