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: