0001:
0002:
0003:
0004:
0005:
0006: #define STRICT
0007: #include <windows.h>
0008: #include <basetsd.h>
0009: #include <math.h>
0010: #include <stdio.h>
0011: #include <D3DX8.h>
0012: #include <DXErr8.h>
0013: #include <tchar.h>
0014: #include "D3DApp.h"
0015: #include "D3DFont.h"
0016: #include "D3DFile.h"
0017: #include "D3DUtil.h"
0018: #include "DXUtil.h"
0019: #include "resource.h"
0020: #include "sample.h"
0021:
0022:
0023:
0024:
0025:
0026:
0027: CMyD3DApplication* g_pApp = NULL;
0028: HINSTANCE g_hInst = NULL;
0029:
0030:
0031:
0032:
0033:
0034:
0035:
0036:
0037:
0038: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0039: {
0040: CMyD3DApplication d3dApp;
0041:
0042: g_pApp = &d3dApp;
0043: g_hInst = hInst;
0044:
0045: if( FAILED( d3dApp.Create( hInst ) ) )
0046: return 0;
0047:
0048: return d3dApp.Run();
0049: }
0050:
0051:
0052:
0053:
0054:
0055:
0056:
0057:
0058: CMyD3DApplication::CMyD3DApplication()
0059: {
0060: m_dwCreationWidth = 500;
0061: m_dwCreationHeight = 375;
0062: m_strWindowTitle = TEXT( "sample" );
0063: m_bUseDepthBuffer = TRUE;
0064:
0065:
0066: m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0067: m_bLoadingApp = TRUE;
0068: m_pD3DXMesh = NULL;
0069:
0070: ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0071: m_fWorldRotX = 0.0f;
0072: m_fWorldRotY = 0.0f;
0073:
0074:
0075: ReadSettings();
0076: }
0077:
0078:
0079:
0080:
0081:
0082:
0083:
0084:
0085:
0086: HRESULT CMyD3DApplication::OneTimeSceneInit()
0087: {
0088:
0089:
0090:
0091: SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0092:
0093: m_bLoadingApp = FALSE;
0094:
0095: return S_OK;
0096: }
0097:
0098:
0099:
0100:
0101:
0102:
0103:
0104:
0105: VOID CMyD3DApplication::ReadSettings()
0106: {
0107: HKEY hkey;
0108: if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, DXAPP_KEY,
0109: 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
0110: {
0111:
0112:
0113:
0114:
0115: DXUtil_ReadIntRegKey( hkey, TEXT("Width"), &m_dwCreationWidth, m_dwCreationWidth );
0116: DXUtil_ReadIntRegKey( hkey, TEXT("Height"), &m_dwCreationHeight, m_dwCreationHeight );
0117:
0118: RegCloseKey( hkey );
0119: }
0120: }
0121:
0122:
0123:
0124:
0125:
0126:
0127:
0128:
0129: VOID CMyD3DApplication::WriteSettings()
0130: {
0131: HKEY hkey;
0132: DWORD dwType = REG_DWORD;
0133: DWORD dwLength = sizeof(DWORD);
0134:
0135: if( ERROR_SUCCESS == RegCreateKeyEx( HKEY_CURRENT_USER, DXAPP_KEY,
0136: 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ) )
0137: {
0138:
0139:
0140:
0141:
0142: DXUtil_WriteIntRegKey( hkey, TEXT("Width"), m_rcWindowClient.right );
0143: DXUtil_WriteIntRegKey( hkey, TEXT("Height"), m_rcWindowClient.bottom );
0144:
0145: RegCloseKey( hkey );
0146: }
0147: }
0148:
0149:
0150:
0151:
0152:
0153:
0154:
0155:
0156:
0157:
0158: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior,
0159: D3DFORMAT Format )
0160: {
0161: BOOL bCapsAcceptable;
0162:
0163:
0164: bCapsAcceptable = TRUE;
0165:
0166: if( bCapsAcceptable )
0167: return S_OK;
0168: else
0169: return E_FAIL;
0170: }
0171:
0172:
0173:
0174:
0175:
0176:
0177:
0178:
0179: HRESULT CMyD3DApplication::InitDeviceObjects()
0180: {
0181:
0182:
0183: HRESULT hr;
0184:
0185:
0186: m_pFont->InitDeviceObjects( m_pd3dDevice );
0187:
0188:
0189: if( FAILED( hr = D3DXCreateTeapot( m_pd3dDevice, &m_pD3DXMesh, NULL ) ) )
0190: return DXTRACE_ERR_NOMSGBOX( "D3DXCreateTeapot", hr );
0191:
0192: return S_OK;
0193: }
0194:
0195:
0196:
0197:
0198:
0199:
0200:
0201:
0202: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0203: {
0204:
0205:
0206:
0207: D3DMATERIAL8 mtrl;
0208: D3DUtil_InitMaterial( mtrl, 1.0f, 0.0f, 0.0f );
0209: m_pd3dDevice->SetMaterial( &mtrl );
0210:
0211:
0212: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
0213: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0214: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
0215: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
0216: m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
0217:
0218:
0219: m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, FALSE );
0220: m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
0221: m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
0222: m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x000F0F0F );
0223:
0224:
0225: D3DXMATRIX matIdentity;
0226: D3DXMatrixIdentity( &matIdentity );
0227: m_pd3dDevice->SetTransform( D3DTS_WORLD, &matIdentity );
0228:
0229:
0230:
0231:
0232:
0233: D3DXMATRIX matView;
0234: D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
0235: D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0236: D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0237: D3DXMatrixLookAtLH( &matView, &vFromPt, &vLookatPt, &vUpVec );
0238: m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
0239:
0240:
0241: D3DXMATRIX matProj;
0242: FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0243: D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0244: m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
0245:
0246:
0247: D3DLIGHT8 light;
0248: D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, -1.0f, -1.0f, 2.0f );
0249: m_pd3dDevice->SetLight( 0, &light );
0250: m_pd3dDevice->LightEnable( 0, TRUE );
0251: m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
0252:
0253:
0254: m_pFont->RestoreDeviceObjects();
0255:
0256: return S_OK;
0257: }
0258:
0259:
0260:
0261:
0262:
0263:
0264:
0265:
0266:
0267: HRESULT CMyD3DApplication::FrameMove()
0268: {
0269:
0270:
0271:
0272: UpdateInput( &m_UserInput );
0273:
0274:
0275: D3DXMATRIX matWorld;
0276: D3DXMATRIX matRotY;
0277: D3DXMATRIX matRotX;
0278:
0279: if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0280: m_fWorldRotY += m_fElapsedTime;
0281: else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0282: m_fWorldRotY -= m_fElapsedTime;
0283:
0284: if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0285: m_fWorldRotX += m_fElapsedTime;
0286: else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0287: m_fWorldRotX -= m_fElapsedTime;
0288:
0289: D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0290: D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0291:
0292: D3DXMatrixMultiply( &matWorld, &matRotX, &matRotY );
0293: m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
0294:
0295: return S_OK;
0296: }
0297:
0298:
0299:
0300:
0301:
0302:
0303:
0304:
0305: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0306: {
0307: pUserInput->bRotateUp = ( m_bHasFocus && (GetAsyncKeyState( VK_UP ) & 0x8000) == 0x8000 );
0308: pUserInput->bRotateDown = ( m_bHasFocus && (GetAsyncKeyState( VK_DOWN ) & 0x8000) == 0x8000 );
0309: pUserInput->bRotateLeft = ( m_bHasFocus && (GetAsyncKeyState( VK_LEFT ) & 0x8000) == 0x8000 );
0310: pUserInput->bRotateRight = ( m_bHasFocus && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0311: }
0312:
0313:
0314:
0315:
0316:
0317:
0318:
0319:
0320:
0321:
0322: HRESULT CMyD3DApplication::Render()
0323: {
0324:
0325: m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0326: 0x000000ff, 1.0f, 0L );
0327:
0328:
0329: if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0330: {
0331:
0332:
0333:
0334: m_pD3DXMesh->DrawSubset(0);
0335:
0336:
0337: RenderText();
0338:
0339:
0340: m_pd3dDevice->EndScene();
0341: }
0342:
0343: return S_OK;
0344: }
0345:
0346:
0347:
0348:
0349:
0350:
0351:
0352:
0353: HRESULT CMyD3DApplication::RenderText()
0354: {
0355: D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,0);
0356: D3DCOLOR fontWarningColor = D3DCOLOR_ARGB(255,0,255,255);
0357: TCHAR szMsg[MAX_PATH] = TEXT("");
0358:
0359:
0360: FLOAT fNextLine = 40.0f;
0361:
0362: lstrcpy( szMsg, m_strDeviceStats );
0363: fNextLine -= 20.0f;
0364: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0365:
0366: lstrcpy( szMsg, m_strFrameStats );
0367: fNextLine -= 20.0f;
0368: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0369:
0370:
0371: fNextLine = (FLOAT) m_d3dsdBackBuffer.Height;
0372:
0373: wsprintf( szMsg, TEXT("Arrow keys: Up=%d Down=%d Left=%d Right=%d"),
0374: m_UserInput.bRotateUp, m_UserInput.bRotateDown, m_UserInput.bRotateLeft, m_UserInput.bRotateRight );
0375: fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0376:
0377: lstrcpy( szMsg, TEXT("Use arrow keys to rotate object") );
0378: fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0379:
0380: lstrcpy( szMsg, TEXT("Press 'F2' to configure display") );
0381: fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0382:
0383: return S_OK;
0384: }
0385:
0386:
0387:
0388:
0389:
0390:
0391:
0392:
0393:
0394: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg, WPARAM wParam,
0395: LPARAM lParam )
0396: {
0397: switch( msg )
0398: {
0399: case WM_PAINT:
0400: {
0401: if( m_bLoadingApp )
0402: {
0403:
0404:
0405: HDC hDC = GetDC( hWnd );
0406: TCHAR strMsg[MAX_PATH];
0407: wsprintf( strMsg, TEXT("Loading... Please wait") );
0408: RECT rct;
0409: GetClientRect( hWnd, &rct );
0410: DrawText( hDC, strMsg, -1, &rct, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0411: ReleaseDC( hWnd, hDC );
0412: }
0413: break;
0414: }
0415:
0416: }
0417:
0418: return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0419: }
0420:
0421:
0422:
0423:
0424:
0425:
0426:
0427:
0428: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0429: {
0430:
0431: m_pFont->InvalidateDeviceObjects();
0432:
0433: return S_OK;
0434: }
0435:
0436:
0437:
0438:
0439:
0440:
0441:
0442:
0443:
0444: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0445: {
0446:
0447: m_pFont->DeleteDeviceObjects();
0448: SAFE_RELEASE( m_pD3DXMesh );
0449:
0450: return S_OK;
0451: }
0452:
0453:
0454:
0455:
0456:
0457:
0458:
0459:
0460:
0461: HRESULT CMyD3DApplication::FinalCleanup()
0462: {
0463:
0464:
0465: SAFE_DELETE( m_pFont );
0466:
0467:
0468: WriteSettings();
0469:
0470: return S_OK;
0471: }
0472:
0473:
0474:
0475:
0476: