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 "framework/DXUtil.h"
0017: #include "framework/D3DEnumeration.h"
0018: #include "framework/D3DSettings.h"
0019: #include "framework/D3DApp.h"
0020: #include "framework/D3DFont.h"
0021: #include "framework/D3DFile.h"
0022: #include "framework/D3DUtil.h"
0023: #include "resource.h"
0024: #include "main.h"
0025:
0026:
0027:
0028:
0029:
0030:
0031: CMyD3DApplication* g_pApp = NULL;
0032: HINSTANCE g_hInst = NULL;
0033:
0034:
0035:
0036: D3DVERTEXELEMENT9 decl[] =
0037: {
0038: {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
0039: {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
0040: {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
0041: {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_LOOKUP, D3DDECLUSAGE_SAMPLE, 0},
0042: D3DDECL_END()
0043: };
0044:
0045:
0046:
0047:
0048:
0049:
0050:
0051: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0052: {
0053: CMyD3DApplication d3dApp;
0054:
0055: g_pApp = &d3dApp;
0056: g_hInst = hInst;
0057:
0058: InitCommonControls();
0059: if( FAILED( d3dApp.Create( hInst ) ) )
0060: return 0;
0061:
0062: return d3dApp.Run();
0063: }
0064:
0065:
0066:
0067:
0068:
0069:
0070:
0071:
0072:
0073:
0074:
0075:
0076: CMyD3DApplication::CMyD3DApplication()
0077: {
0078: m_degree = 0.2f;
0079: m_pMesh = new CD3DMesh();
0080: m_pDecl = NULL;
0081: m_pDispMap = NULL;
0082: m_pEffect = NULL;
0083:
0084: m_dwCreationWidth = 500;
0085: m_dwCreationHeight = 375;
0086: m_strWindowTitle = TEXT( "main" );
0087: m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
0088: m_bStartFullscreen = false;
0089: m_bShowCursorWhenFullscreen = false;
0090:
0091:
0092: m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0093: m_bLoadingApp = TRUE;
0094:
0095: ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0096: m_fWorldRotX = 0.0f;
0097: m_fWorldRotY = D3DX_PI/2.0f;
0098: }
0099:
0100:
0101:
0102:
0103:
0104:
0105:
0106:
0107: CMyD3DApplication::~CMyD3DApplication()
0108: {
0109: }
0110:
0111:
0112:
0113:
0114:
0115:
0116:
0117:
0118:
0119:
0120:
0121:
0122: HRESULT CMyD3DApplication::OneTimeSceneInit()
0123: {
0124:
0125:
0126:
0127: SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0128:
0129: m_bLoadingApp = FALSE;
0130:
0131: return S_OK;
0132: }
0133:
0134:
0135:
0136:
0137:
0138:
0139:
0140:
0141:
0142:
0143:
0144:
0145:
0146:
0147: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
0148: D3DFORMAT Format )
0149: {
0150: UNREFERENCED_PARAMETER( Format );
0151: UNREFERENCED_PARAMETER( dwBehavior );
0152: UNREFERENCED_PARAMETER( pCaps );
0153:
0154: BOOL bCapsAcceptable;
0155:
0156:
0157: bCapsAcceptable = TRUE;
0158:
0159:
0160: bCapsAcceptable &= (D3DPS_VERSION(1,1) <= pCaps->PixelShaderVersion);
0161: bCapsAcceptable &= (D3DVS_VERSION(1,1) <= pCaps->VertexShaderVersion);
0162:
0163: if( bCapsAcceptable )
0164: return S_OK;
0165: else
0166: return E_FAIL;
0167: }
0168:
0169:
0170:
0171:
0172:
0173:
0174:
0175:
0176:
0177:
0178:
0179:
0180: HRESULT CMyD3DApplication::InitDeviceObjects()
0181: {
0182:
0183:
0184: HRESULT hr;
0185:
0186:
0187: m_pFont->InitDeviceObjects( m_pd3dDevice );
0188:
0189:
0190: if( FAILED( hr = m_pMesh->Create( m_pd3dDevice, "tiger.x" ) ) )
0191: return DXTRACE_ERR( "Load Mesh", hr );
0192: m_pMesh->UseMeshMaterials(FALSE);
0193:
0194:
0195: D3DFORMAT adapterFormat = m_d3dSettings.DisplayMode().Format;
0196: m_bDMap = ( (m_pd3dDevice->GetSoftwareVertexProcessing() == FALSE) &&
0197: (m_d3dCaps.DevCaps2 & D3DDEVCAPS2_DMAPNPATCH ) &&
0198: SUCCEEDED( m_pD3D->CheckDeviceFormat( m_d3dCaps.AdapterOrdinal,
0199: m_d3dCaps.DeviceType,
0200: adapterFormat,
0201: D3DUSAGE_DMAP,
0202: D3DRTYPE_TEXTURE,
0203: D3DFMT_L8 ) ) );
0204:
0205:
0206: if( FAILED( D3DXCreateEffectFromFile( m_pd3dDevice, "hlsl.fx", NULL, NULL,
0207: 0, NULL, &m_pEffect, NULL ) ) ) return E_FAIL;
0208:
0209: if(m_bDMap){
0210:
0211: if( FAILED( hr = m_pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl ) ) )
0212: return DXTRACE_ERR( "CreateVertexDeclaration", hr );
0213:
0214:
0215: if(FAILED(hr = D3DXCreateTextureFromFileEx( m_pd3dDevice, "tiger_disp.bmp"
0216: , D3DX_DEFAULT
0217: , D3DX_DEFAULT
0218: , D3DX_DEFAULT
0219: , D3DUSAGE_DMAP
0220: , D3DFMT_L8
0221: , D3DPOOL_MANAGED
0222: , D3DX_DEFAULT
0223: , D3DX_DEFAULT
0224: , 0
0225: , NULL
0226: , NULL
0227: , &m_pDispMap
0228: )))
0229: return DXTRACE_ERR( "Load Displacement Texture", hr );
0230:
0231: m_pd3dDevice->SetSamplerState( D3DDMAPSAMPLER, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
0232: m_pd3dDevice->SetSamplerState( D3DDMAPSAMPLER, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
0233: m_pd3dDevice->SetSamplerState( D3DDMAPSAMPLER, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
0234: m_pd3dDevice->SetSamplerState( D3DDMAPSAMPLER, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0235: m_pd3dDevice->SetSamplerState( D3DDMAPSAMPLER, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0236: }
0237:
0238: return S_OK;
0239: }
0240:
0241:
0242:
0243:
0244:
0245:
0246:
0247:
0248:
0249:
0250: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0251: {
0252:
0253:
0254:
0255: D3DMATERIAL9 mtrl;
0256: D3DUtil_InitMaterial( mtrl, 1.0f, 0.0f, 0.0f );
0257: m_pd3dDevice->SetMaterial( &mtrl );
0258:
0259:
0260: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
0261: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0262: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
0263: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
0264: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
0265: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
0266: m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP );
0267: m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP );
0268: m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0269: m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0270:
0271:
0272: m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, FALSE );
0273: m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
0274: m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
0275: m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x000F0F0F );
0276: m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
0277:
0278:
0279: D3DXMATRIX matIdentity;
0280: D3DXMatrixIdentity( &m_mWorld );
0281: m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_mWorld );
0282:
0283:
0284:
0285:
0286:
0287: D3DXMATRIX matView;
0288: D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
0289: D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0290: D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0291: D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0292: m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_mView );
0293:
0294:
0295: D3DXMATRIX matProj;
0296: FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0297: D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0298: m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_mProj );
0299:
0300: m_LighPos = D3DXVECTOR4(-0.6f, 0.6f, -0.6f, 0.3f);
0301:
0302:
0303: m_pFont->RestoreDeviceObjects();
0304:
0305: if(m_bDMap){
0306:
0307:
0308:
0309: if( m_pMesh->m_pSysMemMesh ){
0310: if( FAILED( m_pMesh->m_pSysMemMesh->CloneMesh( 0L|D3DXMESH_NPATCHES, decl,
0311: m_pd3dDevice, &m_pMesh->m_pLocalMesh ) ) )
0312: return E_FAIL;
0313: D3DXComputeNormals( m_pMesh->m_pLocalMesh, NULL );
0314: }
0315: }else{
0316: m_pMesh->RestoreDeviceObjects(m_pd3dDevice);
0317: }
0318:
0319:
0320:
0321: if( m_pEffect != NULL ) m_pEffect->OnResetDevice();
0322:
0323: return S_OK;
0324: }
0325:
0326:
0327:
0328:
0329:
0330:
0331:
0332:
0333:
0334: HRESULT CMyD3DApplication::FrameMove()
0335: {
0336:
0337:
0338:
0339: UpdateInput( &m_UserInput );
0340:
0341:
0342: D3DXMATRIX matWorld;
0343: D3DXMATRIX matRotY;
0344: D3DXMATRIX matRotX;
0345:
0346: if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0347: m_fWorldRotY += m_fElapsedTime;
0348: else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0349: m_fWorldRotY -= m_fElapsedTime;
0350:
0351: if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0352: m_fWorldRotX += m_fElapsedTime;
0353: else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0354: m_fWorldRotX -= m_fElapsedTime;
0355:
0356: if(m_UserInput.bZ && !m_UserInput.bX){
0357: m_degree += 0.01f;
0358: }
0359: if(m_UserInput.bX && !m_UserInput.bZ){
0360: m_degree -= 0.01f;
0361: }
0362:
0363: D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0364: D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0365:
0366: D3DXMatrixMultiply( &m_mWorld, &matRotX, &matRotY );
0367: m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_mWorld );
0368:
0369: return S_OK;
0370: }
0371:
0372:
0373:
0374:
0375:
0376:
0377:
0378:
0379: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0380: {
0381: pUserInput->bRotateUp = ( m_bActive && (GetAsyncKeyState( VK_UP ) & 0x8000) == 0x8000 );
0382: pUserInput->bRotateDown = ( m_bActive && (GetAsyncKeyState( VK_DOWN ) & 0x8000) == 0x8000 );
0383: pUserInput->bRotateLeft = ( m_bActive && (GetAsyncKeyState( VK_LEFT ) & 0x8000) == 0x8000 );
0384: pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0385: pUserInput->bZ = ( m_bActive && (GetAsyncKeyState( 'Z' ) & 0x8000) == 0x8000 );
0386: pUserInput->bX = ( m_bActive && (GetAsyncKeyState( 'X' ) & 0x8000) == 0x8000 );
0387: }
0388:
0389:
0390:
0391:
0392:
0393:
0394:
0395:
0396:
0397:
0398: HRESULT CMyD3DApplication::Render()
0399: {
0400:
0401: m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0402: 0x000000ff, 1.0f, 0L );
0403:
0404:
0405: if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0406: {
0407: if(m_bDMap){
0408: if( m_pEffect != NULL )
0409: {
0410:
0411:
0412:
0413:
0414: D3DXHANDLE hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
0415: m_pEffect->SetTechnique( hTechnique );
0416: m_pEffect->Begin( NULL, 0 );
0417: m_pEffect->Pass( 0 );
0418:
0419:
0420:
0421: D3DXMATRIX m = m_mWorld * m_mView * m_mProj;
0422: D3DXMatrixTranspose( &m, &m );
0423: m_pd3dDevice->SetVertexShaderConstantF( 0,(float*)&m,4 );
0424:
0425: D3DXVECTOR4 displacement = D3DXVECTOR4(m_degree,0.0f,0.0f,0.0f);
0426: m_pd3dDevice->SetVertexShaderConstantF( 4,(float*)&displacement,1 );
0427:
0428: D3DXVECTOR4 consts = D3DXVECTOR4(0.0f,0.5f,1.0f,2.0f);
0429: m_pd3dDevice->SetVertexShaderConstantF(12,(float*)&consts,1 );
0430:
0431: D3DXVECTOR4 v;
0432: D3DXMatrixInverse( &m, NULL, &m_mWorld);
0433: D3DXVec4Transform( &v, &m_LighPos, &m );
0434: D3DXVec4Normalize( &v, &v );v.w = 0.3f;
0435: m_pd3dDevice->SetVertexShaderConstantF(13,(float*)&v,1 );
0436:
0437:
0438: m_pd3dDevice->SetTexture(0, m_pMesh->m_pTextures[0]);
0439:
0440:
0441:
0442:
0443: m_pd3dDevice->SetTexture(D3DDMAPSAMPLER, m_pDispMap);
0444: m_pd3dDevice->SetNPatchMode(4);
0445: m_pd3dDevice->SetVertexDeclaration( m_pDecl );
0446:
0447:
0448:
0449:
0450: m_pMesh->Render( m_pd3dDevice );
0451:
0452:
0453:
0454:
0455: m_pd3dDevice->SetNPatchMode(0);
0456: m_pd3dDevice->SetVertexShader( NULL );
0457: m_pEffect->End();
0458: }
0459: }else{
0460: m_pd3dDevice->SetTexture(0, m_pMesh->m_pTextures[0]);
0461: m_pMesh->Render( m_pd3dDevice );
0462: }
0463:
0464:
0465: RenderText();
0466:
0467:
0468: m_pd3dDevice->EndScene();
0469: }
0470:
0471: return S_OK;
0472: }
0473:
0474:
0475:
0476:
0477:
0478:
0479:
0480:
0481: HRESULT CMyD3DApplication::RenderText()
0482: {
0483: D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,0);
0484: TCHAR szMsg[MAX_PATH] = TEXT("");
0485:
0486:
0487: FLOAT fNextLine = 40.0f;
0488:
0489: lstrcpy( szMsg, m_strDeviceStats );
0490: fNextLine -= 20.0f;
0491: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0492:
0493: lstrcpy( szMsg, m_strFrameStats );
0494: fNextLine -= 20.0f;
0495: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0496:
0497:
0498: fNextLine = (FLOAT) m_d3dsdBackBuffer.Height;
0499: sprintf( szMsg, "Displacement: %f", m_degree );
0500: fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0501: lstrcpy( szMsg, TEXT("Use arrow keys to rotate object") );
0502: fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0503: lstrcpy( szMsg, TEXT("Press 'z' or 'x' to change degree of the displacement") );
0504: fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0505: return S_OK;
0506: }
0507:
0508:
0509:
0510:
0511:
0512:
0513:
0514:
0515:
0516: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg, WPARAM wParam,
0517: LPARAM lParam )
0518: {
0519: switch( msg )
0520: {
0521: case WM_PAINT:
0522: {
0523: if( m_bLoadingApp )
0524: {
0525:
0526:
0527: HDC hDC = GetDC( hWnd );
0528: TCHAR strMsg[MAX_PATH];
0529: wsprintf( strMsg, TEXT("Loading... Please wait") );
0530: RECT rct;
0531: GetClientRect( hWnd, &rct );
0532: DrawText( hDC, strMsg, -1, &rct, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0533: ReleaseDC( hWnd, hDC );
0534: }
0535: break;
0536: }
0537:
0538: }
0539:
0540: return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0541: }
0542:
0543:
0544:
0545:
0546:
0547:
0548:
0549:
0550: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0551: {
0552:
0553: m_pFont->InvalidateDeviceObjects();
0554:
0555: m_pMesh->InvalidateDeviceObjects();
0556:
0557:
0558: if( m_pEffect != NULL ) m_pEffect->OnLostDevice();
0559:
0560: return S_OK;
0561: }
0562:
0563:
0564:
0565:
0566:
0567:
0568:
0569:
0570:
0571:
0572: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0573: {
0574:
0575: m_pFont->DeleteDeviceObjects();
0576:
0577: m_pMesh->Destroy();
0578:
0579:
0580: SAFE_RELEASE( m_pEffect );
0581:
0582: SAFE_RELEASE( m_pDecl );
0583: SAFE_RELEASE( m_pDispMap );
0584:
0585: return S_OK;
0586: }
0587:
0588:
0589:
0590:
0591:
0592:
0593:
0594:
0595:
0596:
0597: HRESULT CMyD3DApplication::FinalCleanup()
0598: {
0599:
0600:
0601: SAFE_DELETE( m_pFont );
0602:
0603: SAFE_DELETE( m_pMesh );
0604:
0605: return S_OK;
0606: }
0607:
0608:
0609:
0610:
0611: