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:
0028:
0029:
0030:
0031: CMyD3DApplication* g_pApp = NULL;
0032: HINSTANCE g_hInst = NULL;
0033:
0034:
0035:
0036:
0037:
0038:
0039: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0040: {
0041: CMyD3DApplication d3dApp;
0042:
0043: g_pApp = &d3dApp;
0044: g_hInst = hInst;
0045:
0046: InitCommonControls();
0047: if( FAILED( d3dApp.Create( hInst ) ) )
0048: return 0;
0049:
0050: return d3dApp.Run();
0051: }
0052:
0053:
0054:
0055:
0056:
0057:
0058:
0059:
0060: CMyD3DApplication::CMyD3DApplication()
0061: {
0062: m_pTex = NULL;
0063: m_pMesh = new CD3DMesh();
0064:
0065: m_pEffect = NULL;
0066:
0067: m_dwCreationWidth = 500;
0068: m_dwCreationHeight = 375;
0069: m_strWindowTitle = TEXT( "main" );
0070: m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
0071: m_bStartFullscreen = false;
0072: m_bShowCursorWhenFullscreen = false;
0073:
0074: m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0075: m_bLoadingApp = TRUE;
0076:
0077: ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0078: m_fWorldRotX = -0.437504f;
0079: m_fWorldRotY = 1.0f;
0080:
0081: m_fLightRotX = 0.344792f;
0082: m_fLightRotY =-0.722427f;
0083: }
0084:
0085:
0086:
0087:
0088:
0089:
0090:
0091:
0092: CMyD3DApplication::~CMyD3DApplication()
0093: {
0094: }
0095:
0096:
0097:
0098:
0099:
0100:
0101:
0102:
0103:
0104:
0105: HRESULT CMyD3DApplication::OneTimeSceneInit()
0106: {
0107:
0108: SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0109:
0110: m_bLoadingApp = FALSE;
0111:
0112: return S_OK;
0113: }
0114:
0115:
0116:
0117:
0118:
0119:
0120:
0121:
0122:
0123:
0124:
0125:
0126:
0127:
0128: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
0129: D3DFORMAT Format )
0130: {
0131: UNREFERENCED_PARAMETER( Format );
0132:
0133:
0134:
0135: if( pCaps->PixelShaderVersion < D3DPS_VERSION(1,1) )
0136: return E_FAIL;
0137:
0138:
0139: if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,1)
0140: && 0==(dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING) )
0141: return E_FAIL;
0142:
0143: return S_OK;
0144: }
0145:
0146:
0147:
0148:
0149:
0150:
0151:
0152:
0153:
0154:
0155: HRESULT CMyD3DApplication::InitDeviceObjects()
0156: {
0157: HRESULT hr;
0158:
0159:
0160: if(FAILED(hr=m_pMesh ->Create( m_pd3dDevice, _T("t-pot.x"))))
0161: return DXTRACE_ERR( "Load Object", hr );
0162: m_pMesh->UseMeshMaterials(FALSE);
0163:
0164:
0165: D3DXCreateTextureFromFile(m_pd3dDevice, "toon.bmp", &m_pTex);
0166:
0167:
0168: LPD3DXBUFFER pErr;
0169: if( FAILED( hr = D3DXCreateEffectFromFile(
0170: m_pd3dDevice, "hlsl.fx", NULL, NULL,
0171: D3DXSHADER_DEBUG , NULL, &m_pEffect, &pErr ))){
0172: MessageBox( NULL, (LPCTSTR)pErr->GetBufferPointer()
0173: , "ERROR", MB_OK);
0174: return DXTRACE_ERR( "CreateEffectFromFile", hr );
0175: }
0176:
0177:
0178: hr = m_pFont->InitDeviceObjects( m_pd3dDevice );
0179: if( FAILED( hr ) )
0180: return DXTRACE_ERR( "m_pFont->InitDeviceObjects", hr );
0181:
0182: return S_OK;
0183: }
0184:
0185:
0186:
0187:
0188:
0189:
0190:
0191:
0192:
0193: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0194: {
0195:
0196: m_pEffect->OnResetDevice();
0197:
0198:
0199: m_pMesh->RestoreDeviceObjects( m_pd3dDevice );
0200:
0201:
0202: m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
0203: m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
0204:
0205:
0206: D3DXMATRIX matIdentity;
0207: D3DXMatrixIdentity( &matIdentity );
0208: m_pd3dDevice->SetTransform( D3DTS_WORLD, &matIdentity );
0209:
0210:
0211: D3DXMATRIX matView;
0212: D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -4.0f );
0213: D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0214: D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0215: D3DXMatrixLookAtLH( &m_mV, &vFromPt, &vLookatPt, &vUpVec );
0216:
0217:
0218: D3DXMATRIX matProj;
0219: FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0220: D3DXMatrixPerspectiveFovLH( &m_mP, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0221:
0222:
0223: m_pFont->RestoreDeviceObjects();
0224:
0225: return S_OK;
0226: }
0227:
0228:
0229:
0230:
0231:
0232:
0233:
0234:
0235: HRESULT CMyD3DApplication::FrameMove()
0236: {
0237:
0238: UpdateInput( &m_UserInput );
0239:
0240:
0241:
0242:
0243: D3DXMATRIX matRotY;
0244: D3DXMATRIX matRotX;
0245:
0246: if(m_UserInput.bShift){
0247:
0248: if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0249: m_fLightRotY += m_fElapsedTime;
0250: else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0251: m_fLightRotY -= m_fElapsedTime;
0252:
0253: if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0254: m_fLightRotX += m_fElapsedTime;
0255: else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0256: m_fLightRotX -= m_fElapsedTime;
0257: }else{
0258:
0259: if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0260: m_fWorldRotY += m_fElapsedTime;
0261: else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0262: m_fWorldRotY -= m_fElapsedTime;
0263:
0264: if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0265: m_fWorldRotX += m_fElapsedTime;
0266: else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0267: m_fWorldRotX -= m_fElapsedTime;
0268: }
0269:
0270:
0271: D3DXMatrixRotationX( &matRotX, m_fLightRotX );
0272: D3DXMatrixRotationY( &matRotY, m_fLightRotY );
0273: D3DXMatrixMultiply( &m_mLight, &matRotY, &matRotX );
0274:
0275: D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0276: D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0277: D3DXMatrixMultiply( &m_mW, &matRotY, &matRotX );
0278:
0279: m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_mW );
0280:
0281: return S_OK;
0282: }
0283:
0284:
0285:
0286:
0287:
0288:
0289:
0290:
0291: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0292: {
0293: pUserInput->bRotateUp = ( m_bActive && (GetAsyncKeyState( VK_UP ) & 0x8000) == 0x8000 );
0294: pUserInput->bRotateDown = ( m_bActive && (GetAsyncKeyState( VK_DOWN ) & 0x8000) == 0x8000 );
0295: pUserInput->bRotateLeft = ( m_bActive && (GetAsyncKeyState( VK_LEFT ) & 0x8000) == 0x8000 );
0296: pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0297:
0298: pUserInput->bShift = ((GetAsyncKeyState( VK_SHIFT ) & 0x8000) == 0x8000);
0299: }
0300:
0301:
0302:
0303:
0304:
0305:
0306:
0307:
0308: HRESULT CMyD3DApplication::Render()
0309: {
0310: D3DXMATRIX m, mX, mY;
0311: D3DXVECTOR4 v;
0312: DWORD i;
0313:
0314: D3DXVECTOR4 LightPos = D3DXVECTOR4(0.0f, 0.0f, -3.0f, 0.0f);
0315: D3DXVec4Transform( &LightPos, &LightPos, &m_mLight );
0316:
0317:
0318: m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0319: 0x000000ff, 1.0f, 0L );
0320:
0321:
0322:
0323:
0324: if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0325: {
0326: if(m_pEffect){
0327: m_pEffect->SetTechnique( "TShader" );
0328: m_pEffect->Begin( NULL, 0 );
0329: m_pEffect->Pass( 0 );
0330:
0331:
0332: D3DXMATRIX mWVP = m_mW * m_mV * m_mP;
0333: m_pEffect->SetMatrix("mWVP", &mWVP);
0334:
0335:
0336: m = m_mW;
0337: D3DXMatrixInverse( &m, NULL, &m );
0338: D3DXVec4Transform( &v, &LightPos, &m );
0339: m_pEffect->SetVector("LightPos", &v);
0340:
0341:
0342: v = D3DXVECTOR4(0,0,-5,0);
0343: m = m_mW;
0344: D3DXMatrixInverse( &m, NULL, &m );
0345: D3DXVec4Transform( &v, &v, &m );
0346: m_pEffect->SetVector("EyePos", &v);
0347:
0348: m_pEffect->SetTexture("ToonTex", m_pTex);
0349:
0350:
0351: D3DMATERIAL9 *pMtrl = m_pMesh->m_pMaterials;
0352: for( i=0; i<m_pMesh->m_dwNumMaterials; i++ ) {
0353: v.x = pMtrl->Diffuse.r;
0354: v.y = pMtrl->Diffuse.g;
0355: v.z = pMtrl->Diffuse.b;
0356: m_pEffect->SetVector( "vColor", &v );
0357: m_pEffect->SetTexture( "DecaleTex", m_pMesh->m_pTextures[i] );
0358: m_pMesh->m_pLocalMesh->DrawSubset( i );
0359: pMtrl++;
0360: }
0361:
0362: m_pEffect->End();
0363: }
0364:
0365: {
0366: m = m_mV * m_mP;
0367: v = LightPos;
0368: v.w = 1;
0369: D3DXVec4Transform( &v, &v, &m );
0370: float x = (this->m_rcWindowClient.right-this->m_rcWindowClient.left)*( 0.5f*v.x/v.w+0.5f);
0371: float y = (this->m_rcWindowClient.bottom-this->m_rcWindowClient.top)*(-0.5f*v.y/v.w+0.5f);
0372:
0373: m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
0374: m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_DIFFUSE);
0375: m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP, D3DTOP_DISABLE);
0376: m_pd3dDevice->SetVertexShader(NULL);
0377: m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_DIFFUSE );
0378: m_pd3dDevice->SetPixelShader(0);
0379:
0380: typedef struct {FLOAT p[4]; DWORD color;} LVERTEX;
0381: for(DWORD i=0; i<2; i++){
0382: LVERTEX Vertex[4] = {
0383:
0384: {x-3,y-3, v.z/v.w, 1, 0xffffc0,},
0385: {x+3,y-3, v.z/v.w, 1, 0xffffc0,},
0386: {x+3,y+3, v.z/v.w, 1, 0xffffc0,},
0387: {x-3,y+3, v.z/v.w, 1, 0xffffc0,},
0388: };
0389: m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( LVERTEX ) );
0390: }
0391: }
0392:
0393: #if 1
0394: {
0395: m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
0396: m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
0397: m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP, D3DTOP_DISABLE);
0398: m_pd3dDevice->SetVertexShader(NULL);
0399: m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0400: m_pd3dDevice->SetPixelShader(0);
0401: float scale = 128.0f;
0402: typedef struct {FLOAT p[4]; FLOAT tu, tv;} TVERTEX;
0403: for(DWORD i=0; i<1; i++){
0404: TVERTEX Vertex[4] = {
0405:
0406: { 0,(i+0)*scale,0, 1, 0, 0,},
0407: {scale,(i+0)*scale,0, 1, 1, 0,},
0408: {scale,(i+1)*scale,0, 1, 1, 1,},
0409: { 0,(i+1)*scale,0, 1, 0, 1,},
0410: };
0411: if(0==i) m_pd3dDevice->SetTexture( 0, m_pTex );
0412: m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0413: }
0414: }
0415: #endif
0416:
0417:
0418: RenderText();
0419:
0420:
0421: m_pd3dDevice->EndScene();
0422: }
0423:
0424: return S_OK;
0425: }
0426:
0427:
0428:
0429:
0430:
0431:
0432:
0433:
0434: HRESULT CMyD3DApplication::RenderText()
0435: {
0436: D3DCOLOR fontColor = D3DCOLOR_ARGB(255,255,255,0);
0437: TCHAR szMsg[MAX_PATH] = TEXT("");
0438:
0439: FLOAT fNextLine = 40.0f;
0440:
0441: lstrcpy( szMsg, m_strDeviceStats );
0442: fNextLine -= 20.0f;
0443: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0444:
0445: lstrcpy( szMsg, m_strFrameStats );
0446: fNextLine -= 20.0f;
0447: m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0448:
0449:
0450: fNextLine = (FLOAT) m_d3dsdBackBuffer.Height;
0451:
0452: wsprintf( szMsg, TEXT("Arrow keys: Up=%d Down=%d Left=%d Right=%d"),
0453: m_UserInput.bRotateUp, m_UserInput.bRotateDown, m_UserInput.bRotateLeft, m_UserInput.bRotateRight );
0454: fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0455:
0456: lstrcpy( szMsg, TEXT("Use arrow keys to rotate object") );
0457: fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0458:
0459: lstrcpy( szMsg, TEXT("Press 'F2' to configure display") );
0460: fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0461:
0462: return S_OK;
0463: }
0464:
0465:
0466:
0467:
0468:
0469:
0470:
0471:
0472: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg, WPARAM wParam,
0473: LPARAM lParam )
0474: {
0475: switch( msg )
0476: {
0477: case WM_PAINT:
0478: {
0479: if( m_bLoadingApp )
0480: {
0481:
0482: HDC hDC = GetDC( hWnd );
0483: TCHAR strMsg[MAX_PATH];
0484: wsprintf( strMsg, TEXT("Loading... Please wait") );
0485: RECT rct;
0486: GetClientRect( hWnd, &rct );
0487: DrawText( hDC, strMsg, -1, &rct, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0488: ReleaseDC( hWnd, hDC );
0489: }
0490: break;
0491: }
0492:
0493: }
0494:
0495: return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0496: }
0497:
0498:
0499:
0500:
0501:
0502:
0503:
0504:
0505: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0506: {
0507: if( m_pEffect ) m_pEffect->OnLostDevice();
0508:
0509: if( m_pMesh ) m_pMesh ->InvalidateDeviceObjects();
0510:
0511: m_pFont->InvalidateDeviceObjects();
0512:
0513: return S_OK;
0514: }
0515:
0516:
0517:
0518:
0519:
0520:
0521:
0522:
0523: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0524: {
0525:
0526: m_pMesh ->Destroy();
0527:
0528:
0529: SAFE_RELEASE( m_pTex );
0530:
0531:
0532: SAFE_RELEASE( m_pEffect );
0533:
0534:
0535: m_pFont->DeleteDeviceObjects();
0536:
0537: return S_OK;
0538: }
0539:
0540:
0541:
0542:
0543:
0544:
0545:
0546:
0547: HRESULT CMyD3DApplication::FinalCleanup()
0548: {
0549: SAFE_DELETE( m_pMesh );
0550: SAFE_DELETE( m_pFont );
0551:
0552: return S_OK;
0553: }
0554:
0555:
0556:
0557:
0558: