0001: 
0002: 
0003: 
0004: 
0005: 
0006: #define STRICT
0007: #include <windows.h>
0008: #include <commctrl.h>
0009: #include <commdlg.h>
0010: #include <basetsd.h>
0011: #include <math.h>
0012: #include <stdio.h>
0013: #include <d3dx9.h>
0014: #include <dxerr9.h>
0015: #include <tchar.h>
0016: #include "DXUtil.h"
0017: #include "D3DEnumeration.h"
0018: #include "D3DSettings.h"
0019: #include "D3DApp.h"
0020: #include "D3DFont.h"
0021: #include "D3DFile.h"
0022: #include "D3DUtil.h"
0023: #include "resource.h"
0024: #include "main.h"
0025: 
0026: 
0027: #define RS   m_pd3dDevice->SetRenderState
0028: #define TSS  m_pd3dDevice->SetTextureStageState
0029: #define SAMP m_pd3dDevice->SetSamplerState
0030: 
0031: 
0032: 
0033: 
0034: D3DVERTEXELEMENT9 decl[] =
0035: {
0036:     {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
0037:     {0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
0038:     {0, 24, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,  0},
0039:     {0, 36, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
0040:     D3DDECL_END()
0041: };
0042: 
0043: 
0044: 
0045: 
0046: CMyD3DApplication* g_pApp  = NULL;
0047: HINSTANCE          g_hInst = NULL;
0048: 
0049: 
0050: 
0051: 
0052: 
0053: 
0054: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0055: {
0056:     CMyD3DApplication d3dApp;
0057: 
0058:     g_pApp  = &d3dApp;
0059:     g_hInst = hInst;
0060: 
0061:     InitCommonControls();
0062:     if( FAILED( d3dApp.Create( hInst ) ) )
0063:         return 0;
0064: 
0065:     return d3dApp.Run();
0066: }
0067: 
0068: 
0069: 
0070: 
0071: 
0072: 
0073: 
0074: 
0075: CMyD3DApplication::CMyD3DApplication()
0076: {
0077:     m_iShader                   = Parallax;
0078: 
0079:     m_pMesh                     = new CD3DMesh();
0080:     m_pMeshBg                   = new CD3DMesh();
0081:     m_pDecl                     = NULL;
0082:     m_pNormalMap                = NULL;
0083:     m_pHeightMap                = NULL;
0084: 
0085:     m_pEffect                   = NULL;
0086:     m_hTechnique                = NULL;
0087:     m_hmWVP                     = NULL;
0088:     m_hvLightDir                = NULL;
0089:     m_hvColor                   = NULL;
0090:     m_hvEyePos                  = NULL;
0091:     m_htDecaleTex               = NULL;
0092:     m_htNormalMap               = NULL;
0093:     m_htHeightMap               = NULL;
0094: 
0095:     m_fWorldRotX                = -D3DX_PI/10;
0096:     m_fWorldRotY                = D3DX_PI/2;
0097:     m_fViewZoom                 = 5.0f;
0098: 
0099:     m_dwCreationWidth           = 512;
0100:     m_dwCreationHeight          = 512;
0101:     m_strWindowTitle            = TEXT( "main" );
0102:     m_d3dEnumeration.AppUsesDepthBuffer   = TRUE;
0103:     m_bStartFullscreen          = false;
0104:     m_bShowCursorWhenFullscreen = false;
0105: 
0106:     m_pFont                     = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0107:     m_bLoadingApp               = TRUE;
0108: 
0109:     ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0110: }
0111: 
0112: 
0113: 
0114: 
0115: 
0116: 
0117: 
0118: 
0119: CMyD3DApplication::~CMyD3DApplication()
0120: {
0121: }
0122: 
0123: 
0124: 
0125: 
0126: 
0127: 
0128: 
0129: 
0130: 
0131: 
0132: HRESULT CMyD3DApplication::OneTimeSceneInit()
0133: {
0134:     
0135:     SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0136: 
0137:     m_bLoadingApp = FALSE;
0138: 
0139:     return S_OK;
0140: }
0141: 
0142: 
0143: 
0144: 
0145: 
0146: 
0147: 
0148: 
0149: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps,
0150:                      DWORD dwBehavior,    D3DFORMAT Format )
0151: {
0152:     UNREFERENCED_PARAMETER( Format );
0153:     
0154: 
0155:     
0156:     if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
0157:         return E_FAIL;
0158: 
0159:     
0160:     if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,1)
0161:     &&  0==(dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING) )
0162:             return E_FAIL;
0163: 
0164:     return S_OK;
0165: }
0166: 
0167: 
0168: 
0169: 
0170: 
0171: 
0172: 
0173: 
0174: 
0175: 
0176: 
0177: HRESULT CMyD3DApplication::InitDeviceObjects()
0178: {
0179:     HRESULT hr;
0180:     D3DXVECTOR4 offset;
0181: 
0182:     
0183:     if(FAILED(hr=D3DXCreateTextureFromFile(
0184:                 m_pd3dDevice, _T("height.bmp"), &m_pHeightMap)))
0185:         return DXTRACE_ERR( "Load Texture", hr );
0186: 
0187:     
0188:     if(FAILED(hr=D3DXCreateTextureFromFile(
0189:                 m_pd3dDevice, _T("normal.bmp"), &m_pNormalMap)))
0190:         return DXTRACE_ERR( "Load Texture", hr );
0191: 
0192:     
0193:     if( FAILED( hr = m_pd3dDevice->CreateVertexDeclaration(
0194:                                         decl, &m_pDecl )))
0195:         return DXTRACE_ERR ("CreateVertexDeclaration", hr);
0196:     
0197:     
0198:     if(FAILED(hr=m_pMesh  ->Create( m_pd3dDevice, _T("t-pot.x"))))
0199:         return DXTRACE_ERR( "Load Object", hr );
0200:         
0201:     
0202:     if(FAILED(hr=m_pMeshBg->Create( m_pd3dDevice, _T("map.x"))))
0203:         return DXTRACE_ERR( "Load Ground", hr );
0204:         
0205:     
0206:     LPD3DXBUFFER pErr=NULL;
0207:     if( FAILED( hr = D3DXCreateEffectFromFile(
0208:                 m_pd3dDevice, "hlsl.fx", NULL, NULL, 
0209:                 0 , NULL, &m_pEffect, &pErr ))){
0210:         
0211:         MessageBox( NULL, (LPCTSTR)pErr->GetBufferPointer()
0212:                     , "ERROR", MB_OK);
0213:     }else{
0214:         m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
0215:         m_hmWVP      = m_pEffect->GetParameterByName( NULL, "mWVP" );
0216:         m_hvLightDir = m_pEffect->GetParameterByName( NULL, "vLightDir" );
0217:         m_hvColor    = m_pEffect->GetParameterByName( NULL, "vColor" );
0218:         m_hvEyePos   = m_pEffect->GetParameterByName( NULL, "vEyePos" );
0219:         m_htDecaleTex= m_pEffect->GetParameterByName( NULL, "DecaleTex" );
0220:         m_htNormalMap= m_pEffect->GetParameterByName( NULL, "NormalMap" );
0221:         m_htHeightMap= m_pEffect->GetParameterByName( NULL, "HeightMap" );
0222:     }
0223:     SAFE_RELEASE(pErr);
0224: 
0225:     
0226:     m_pFont->InitDeviceObjects( m_pd3dDevice );
0227: 
0228:     return S_OK;
0229: }
0230: 
0231: 
0232: 
0233: 
0234: 
0235: 
0236: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0237: {
0238:     
0239:     if(m_pEffect) m_pEffect->OnResetDevice();
0240: 
0241:     
0242:     m_pMeshBg->RestoreDeviceObjects( m_pd3dDevice );
0243: 
0244:     
0245:     
0246:     
0247:     if( m_pMesh && m_pMesh->GetSysMemMesh() ){
0248:         LPD3DXMESH pMesh;
0249: 
0250:         m_pMesh->GetSysMemMesh()->CloneMesh(
0251:             m_pMesh->GetSysMemMesh()->GetOptions(), decl,
0252:             m_pd3dDevice, &pMesh );
0253:         D3DXComputeNormals( pMesh, NULL );
0254:         D3DXComputeTangent( pMesh, 0, 0, 0, TRUE, NULL );
0255: 
0256:         SAFE_RELEASE(m_pMesh->m_pLocalMesh);
0257:         m_pMesh->m_pLocalMesh = pMesh;
0258:     }
0259: 
0260:     
0261:     RS( D3DRS_ZENABLE,        TRUE );
0262:     RS( D3DRS_LIGHTING, FALSE );
0263:     
0264:     SAMP( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0265:     SAMP( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0266:     SAMP( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
0267:     SAMP( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
0268: 
0269:     
0270:     D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
0271:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0272:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0273:     D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0274: 
0275:     
0276:     FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0277:     D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0278: 
0279:     
0280:     m_pFont->RestoreDeviceObjects();
0281: 
0282:     return S_OK;
0283: }
0284: 
0285: 
0286: 
0287: 
0288: 
0289: 
0290: 
0291: 
0292: HRESULT CMyD3DApplication::FrameMove()
0293: {
0294:     
0295:     UpdateInput( &m_UserInput );
0296: 
0297:     
0298:     if( m_UserInput.sw ){
0299:         this->m_iShader++;
0300:         if(SHADER_TYPE_MAX<=this->m_iShader) this->m_iShader = 0;
0301:     }
0302: 
0303:     
0304:     
0305:     
0306:     
0307:     D3DXMATRIX matRotY;
0308:     D3DXMATRIX matRotX;
0309:     D3DXMATRIX mCamera;
0310: 
0311:     if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0312:         m_fWorldRotY += m_fElapsedTime;
0313:     else
0314:     if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0315:         m_fWorldRotY -= m_fElapsedTime;
0316: 
0317:     if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0318:         m_fWorldRotX += m_fElapsedTime;
0319:     else
0320:     if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0321:         m_fWorldRotX -= m_fElapsedTime;
0322: 
0323:     D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0324:     D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0325: 
0326:     D3DXMatrixMultiply( &mCamera, &matRotY, &matRotX );
0327:     
0328:     
0329:     
0330:     
0331:     
0332:     if( m_UserInput.bZoomIn && !m_UserInput.bZoomOut )
0333:         m_fViewZoom += m_fElapsedTime;
0334:     else if( m_UserInput.bZoomOut && !m_UserInput.bZoomIn )
0335:         m_fViewZoom -= m_fElapsedTime;
0336: 
0337:     m_vFromPt   = D3DXVECTOR4( 0.0f, 0.f, -m_fViewZoom,1 );
0338:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0339:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0340:     D3DXMatrixLookAtLH( &m_mView, (D3DXVECTOR3*)&m_vFromPt, &vLookatPt, &vUpVec );
0341:     
0342:     m_mView = mCamera * m_mView;
0343: 
0344:     return S_OK;
0345: }
0346: 
0347: 
0348: 
0349: 
0350: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0351: {
0352:     pUserInput->bRotateUp    = ( m_bActive && (GetAsyncKeyState( VK_UP )    & 0x8000) == 0x8000 );
0353:     pUserInput->bRotateDown  = ( m_bActive && (GetAsyncKeyState( VK_DOWN )  & 0x8000) == 0x8000 );
0354:     pUserInput->bRotateLeft  = ( m_bActive && (GetAsyncKeyState( VK_LEFT )  & 0x8000) == 0x8000 );
0355:     pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0356:     
0357:     pUserInput->bZoomIn      = ( m_bActive && (GetAsyncKeyState( 'Z'     )  & 0x8000) == 0x8000 );
0358:     pUserInput->bZoomOut     = ( m_bActive && (GetAsyncKeyState( 'X'      ) & 0x8000) == 0x8000 );
0359: 
0360:     pUserInput->sw = ( m_bActive && (GetAsyncKeyState( VK_SPACE ) & 0x8001) == 0x8001 );
0361: }
0362: 
0363: 
0364: 
0365: 
0366: 
0367: 
0368: HRESULT CMyD3DApplication::Render()
0369: {
0370:     D3DXMATRIX m, mT, mR, mView, mProj;
0371:     D3DXMATRIX mWorld;
0372:     D3DXVECTOR4 v, light_pos, eye_pos;
0373:     DWORD i;
0374: 
0375:     
0376:     
0377:     
0378:     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0379:     {
0380:         
0381:         m_pd3dDevice->Clear(0L, NULL
0382:                         , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0383:                         , 0x0060c0, 1.0f, 0L);
0384: 
0385:         
0386:         
0387:         
0388:         
0389:         D3DXMatrixScaling( &m,  3.0f, 3.0f, 3.0f );
0390:         D3DXMatrixRotationY( &mR,  D3DX_PI );
0391:         D3DXMatrixTranslation( &mT, 0.0f,-2.0f ,0.0f );
0392:         mWorld = m * mR * mT;
0393: 
0394:         
0395:         m_pd3dDevice->SetTransform( D3DTS_WORLD,  &mWorld);
0396:         m_pd3dDevice->SetTransform( D3DTS_VIEW,  &m_mView );
0397:         m_pd3dDevice->SetTransform( D3DTS_PROJECTION,  &m_mProj );
0398: 
0399:         TSS( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
0400:         TSS( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0401:         m_pMeshBg->Render( m_pd3dDevice );
0402: 
0403:         if( m_pEffect != NULL ) 
0404:         {
0405:             
0406:             
0407:             
0408:             m_pEffect->SetTechnique( m_hTechnique );
0409:             m_pEffect->Begin( NULL, 0 );
0410:             m_pEffect->Pass( this->m_iShader );
0411:             m_pd3dDevice->SetFVF( D3DFVF_XYZ | D3DFVF_NORMAL );
0412: 
0413:             
0414:             
0415:             
0416:             TSS( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
0417:             TSS( 0, D3DTSS_COLORARG1, D3DTA_DIFFUSE );
0418: 
0419:             
0420:             D3DXMatrixRotationY( &mWorld,  m_fTime );
0421: 
0422:             
0423:             m = mWorld * m_mView * m_mProj;
0424:             m_pEffect->SetMatrix( m_hmWVP, &m );
0425: 
0426:             
0427:             light_pos = D3DXVECTOR4( -0.577f, -0.577f, -0.577f,0);
0428:             D3DXMatrixInverse( &m, NULL, &mWorld);
0429:             D3DXVec4Transform( &v, &light_pos, &m );
0430:             D3DXVec3Normalize( (D3DXVECTOR3 *)&v, (D3DXVECTOR3 *)&v );
0431:             v.w = -0.7f;        
0432:             m_pEffect->SetVector( m_hvLightDir, &v );
0433:             
0434:             
0435:             m = mWorld * m_mView;
0436:             D3DXMatrixInverse( &m, NULL, &m);
0437:             v = D3DXVECTOR4( 0, 0, 0, 1);
0438:             D3DXVec4Transform( &v, &v, &m );
0439:             m_pEffect->SetVector( m_hvEyePos, &v );
0440: 
0441:             
0442:             m_pEffect->SetTexture( m_htNormalMap, m_pNormalMap );
0443:             
0444:             m_pEffect->SetTexture( m_htHeightMap, m_pHeightMap );
0445:             
0446:             m_pd3dDevice->SetVertexDeclaration( m_pDecl );
0447: 
0448:             D3DMATERIAL9 *pMtrl = m_pMesh->m_pMaterials;
0449:             for( i=0; i<m_pMesh->m_dwNumMaterials; i++ ) {
0450:                 v.x = pMtrl->Diffuse.r;
0451:                 v.y = pMtrl->Diffuse.g;
0452:                 v.z = pMtrl->Diffuse.b;
0453:                 m_pEffect->SetVector( m_hvColor, &v );
0454:                 m_pEffect->SetTexture( m_htDecaleTex, m_pMesh->m_pTextures[i] );
0455:                 m_pMesh->m_pLocalMesh->DrawSubset( i );  
0456:                 pMtrl++;
0457:             }
0458: 
0459:             m_pEffect->End();
0460:         }
0461: 
0462:         
0463:         RenderText();
0464: 
0465:         
0466:         m_pd3dDevice->EndScene();
0467:     }
0468: 
0469:     return S_OK;
0470: }
0471: 
0472: 
0473: 
0474: 
0475: 
0476: 
0477: 
0478: 
0479: HRESULT CMyD3DApplication::RenderText()
0480: {
0481:     D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
0482:     TCHAR szMsg[MAX_PATH] = TEXT("");
0483: 
0484:     FLOAT fNextLine = 40.0f; 
0485:     
0486:     const TCHAR *shader[] = {
0487:         "Parallax Mapping",
0488:         "Bump Mapping",
0489:     };
0490: 
0491:     
0492:     fNextLine = (FLOAT) m_d3dsdBackBuffer.Height;
0493: 
0494:     sprintf( szMsg, TEXT("SHADER %s"), shader[this->m_iShader] );
0495:     fNextLine -= 20.0f;
0496:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0497: 
0498:     lstrcpy( szMsg, m_strDeviceStats );
0499:     fNextLine -= 20.0f;
0500:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0501:     lstrcpy( szMsg, m_strFrameStats );
0502:     fNextLine -= 20.0f;
0503:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0504:     
0505:     return S_OK;
0506: }
0507: 
0508: 
0509: 
0510: 
0511: 
0512: 
0513: 
0514: 
0515: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg,
0516:                                  WPARAM wParam, LPARAM lParam )
0517: {
0518:     switch( msg )
0519:     {
0520:         case WM_PAINT:
0521:         {
0522:             if( m_bLoadingApp )
0523:             {
0524:                 
0525:                 HDC hDC = GetDC( hWnd );
0526:                 TCHAR strMsg[MAX_PATH];
0527:                 wsprintf(strMsg, TEXT("Loading... Please wait"));
0528:                 RECT rct;
0529:                 GetClientRect( hWnd, &rct );
0530:                 DrawText( hDC, strMsg, -1, &rct
0531:                         , DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0532:                 ReleaseDC( hWnd, hDC );
0533:             }
0534:             break;
0535:         }
0536: 
0537:     }
0538: 
0539:     return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0540: }
0541: 
0542: 
0543: 
0544: 
0545: 
0546: 
0547: 
0548: 
0549: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0550: {
0551:     m_pMesh  ->InvalidateDeviceObjects(); 
0552:     m_pMeshBg->InvalidateDeviceObjects();
0553: 
0554:     m_pFont->InvalidateDeviceObjects(); 
0555: 
0556:     
0557:     if( m_pEffect != NULL ) m_pEffect->OnLostDevice();
0558: 
0559:     return S_OK;
0560: }
0561: 
0562: 
0563: 
0564: 
0565: 
0566: 
0567: 
0568: 
0569: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0570: {
0571:     SAFE_RELEASE( m_pEffect );      
0572:     SAFE_RELEASE( m_pDecl );        
0573:     SAFE_RELEASE( m_pNormalMap );
0574:     SAFE_RELEASE( m_pHeightMap );
0575: 
0576:     
0577:     m_pMesh  ->Destroy();
0578:     m_pMeshBg->Destroy();
0579: 
0580:     
0581:     m_pFont->DeleteDeviceObjects();
0582: 
0583:     return S_OK;
0584: }
0585: 
0586: 
0587: 
0588: 
0589: 
0590: 
0591: 
0592: 
0593: HRESULT CMyD3DApplication::FinalCleanup()
0594: {
0595:     SAFE_DELETE( m_pMeshBg ); 
0596:     SAFE_DELETE( m_pMesh );
0597: 
0598:     SAFE_DELETE( m_pFont ); 
0599: 
0600:     return S_OK;
0601: }
0602: 
0603: 
0604: 
0605: 
0606: