0001:
0002:
0003:
0004:
0005:
0006: #define STRICT
0007: #include "dxstdafx.h"
0008: #include "resource.h"
0009: #include "main_fx.h"
0010:
0011:
0012:
0013:
0014:
0015:
0016: ID3DXFont* g_pFont = NULL;
0017: ID3DXSprite* g_pTextSprite = NULL;
0018: bool g_bShowHelp = true;
0019: CDXUTDialog g_HUD;
0020: CDXUTDialog g_SampleUI;
0021:
0022: CModelViewerCamera g_Camera;
0023: D3DVIEWPORT9 g_ViewportFB;
0024:
0025: LPD3DXEFFECT g_pEffect;
0026: D3DXHANDLE g_hWorldViewProjection;
0027: D3DXHANDLE g_hMeshTexture;
0028: D3DXHANDLE g_hTech;
0029:
0030: LPD3DXMESH g_pScene1Mesh;
0031: LPDIRECT3DTEXTURE9 g_pScene1MeshTexture;
0032:
0033:
0034: FLOAT g_fWorldRotX;
0035: FLOAT g_fWorldRotY;
0036:
0037: FLOAT g_fLightRotX;
0038: FLOAT g_fLightRotY;
0039:
0040: D3DXMATRIX g_mW;
0041: D3DXMATRIX g_mV;
0042: D3DXMATRIX g_mP;
0043:
0044: D3DXMATRIX g_mLight;
0045:
0046:
0047:
0048:
0049:
0050: #define IDC_TOGGLEFULLSCREEN 1
0051: #define IDC_TOGGLEREF 2
0052: #define IDC_CHANGEDEVICE 3
0053:
0054:
0055:
0056:
0057:
0058:
0059: bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed );
0060: void CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps );
0061: HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
0062: HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
0063: void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
0064: void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
0065: LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing );
0066: void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown );
0067: void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl );
0068: void CALLBACK OnLostDevice();
0069: void CALLBACK OnDestroyDevice();
0070:
0071: void InitApp();
0072: HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh );
0073: void RenderText();
0074:
0075:
0076:
0077:
0078:
0079:
0080: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0081: {
0082:
0083: #if defined(DEBUG) | defined(_DEBUG)
0084: _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
0085: #endif
0086:
0087:
0088:
0089:
0090:
0091:
0092:
0093:
0094:
0095: DXUTSetCallbackDeviceCreated( OnCreateDevice );
0096: DXUTSetCallbackDeviceReset( OnResetDevice );
0097: DXUTSetCallbackDeviceLost( OnLostDevice );
0098: DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
0099: DXUTSetCallbackMsgProc( MsgProc );
0100: DXUTSetCallbackKeyboard( KeyboardProc );
0101: DXUTSetCallbackFrameRender( OnFrameRender );
0102: DXUTSetCallbackFrameMove( OnFrameMove );
0103:
0104:
0105: DXUTSetCursorSettings( true, true );
0106:
0107: InitApp();
0108:
0109:
0110:
0111:
0112: DXUTInit( true, true, true );
0113: DXUTCreateWindow( TEXT("main") );
0114: DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );
0115:
0116:
0117:
0118:
0119: DXUTMainLoop();
0120:
0121:
0122:
0123:
0124: return DXUTGetExitCode();
0125: }
0126:
0127:
0128:
0129:
0130:
0131:
0132:
0133: void InitApp()
0134: {
0135: g_pFont = NULL;
0136:
0137: g_pEffect = NULL;
0138:
0139: g_pScene1Mesh = NULL;
0140: g_pScene1MeshTexture = NULL;
0141:
0142: g_fWorldRotX = -0.437504f;
0143: g_fWorldRotY = 1.0f;
0144:
0145: g_fLightRotX = 0.344792f;
0146: g_fLightRotY =-0.722427f;
0147:
0148:
0149: g_HUD.SetCallback( OnGUIEvent ); int iY = 10;
0150: g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 35, iY, 125, 22 );
0151: g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 35, iY += 24, 125, 22 );
0152: g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22 );
0153: }
0154:
0155:
0156:
0157:
0158:
0159:
0160: bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
0161: D3DFORMAT BackBufferFormat, bool bWindowed )
0162: {
0163:
0164: IDirect3D9* pD3D = DXUTGetD3DObject();
0165: if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
0166: AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
0167: D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
0168: return false;
0169:
0170:
0171: if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )
0172: return false;
0173:
0174: return true;
0175: }
0176:
0177:
0178:
0179:
0180:
0181:
0182:
0183:
0184:
0185:
0186:
0187: void CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps )
0188: {
0189:
0190:
0191: if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
0192: pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
0193: {
0194: pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0195: }
0196: else
0197: {
0198: pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
0199: }
0200:
0201:
0202:
0203: if ((pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 &&
0204: (pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 )
0205: pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE;
0206:
0207:
0208:
0209: #ifdef DEBUG_VS
0210: if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
0211: {
0212: pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
0213: pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
0214: pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0215: }
0216: #endif
0217: #ifdef DEBUG_PS
0218: pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
0219: #endif
0220: }
0221:
0222:
0223:
0224:
0225:
0226:
0227:
0228:
0229:
0230:
0231: HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
0232: {
0233: WCHAR str[MAX_PATH];
0234: HRESULT hr;
0235:
0236:
0237: V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
0238: OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
0239: L"Arial", &g_pFont ) );
0240:
0241:
0242: V_RETURN( LoadMesh( pd3dDevice, TEXT("t-pot.x"), &g_pScene1Mesh ) );
0243:
0244:
0245: V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"t-pot.bmp" ) );
0246: V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, str, &g_pScene1MeshTexture) );
0247:
0248:
0249:
0250:
0251:
0252:
0253:
0254:
0255:
0256:
0257:
0258:
0259: DWORD dwShaderFlags = 0;
0260: #ifdef DEBUG_VS
0261: dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
0262: #endif
0263: #ifdef DEBUG_PS
0264: dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
0265: #endif
0266:
0267:
0268: V_RETURN( D3DXCreateEffect( pd3dDevice, g_effect, sizeof(g_effect),
0269: NULL, NULL, dwShaderFlags, NULL, &g_pEffect, NULL ) );
0270:
0271: return S_OK;
0272: }
0273:
0274:
0275:
0276:
0277:
0278:
0279:
0280:
0281:
0282:
0283: void CALLBACK OnDestroyDevice()
0284: {
0285: SAFE_RELEASE(g_pEffect);
0286: SAFE_RELEASE(g_pFont);
0287:
0288: SAFE_RELEASE(g_pScene1Mesh);
0289: SAFE_RELEASE(g_pScene1MeshTexture);
0290: }
0291:
0292:
0293:
0294:
0295:
0296:
0297:
0298:
0299:
0300: HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh )
0301: {
0302: ID3DXMesh* pMesh = NULL;
0303: WCHAR str[MAX_PATH];
0304: HRESULT hr;
0305:
0306:
0307:
0308:
0309:
0310: V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) );
0311:
0312: V_RETURN( D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh) );
0313:
0314: DWORD *rgdwAdjacency = NULL;
0315:
0316:
0317: if( !(pMesh->GetFVF() & D3DFVF_NORMAL) )
0318: {
0319: ID3DXMesh* pTempMesh;
0320: V( pMesh->CloneMeshFVF( pMesh->GetOptions(),
0321: pMesh->GetFVF() | D3DFVF_NORMAL,
0322: pd3dDevice, &pTempMesh ) );
0323: V( D3DXComputeNormals( pTempMesh, NULL ) );
0324:
0325: SAFE_RELEASE( pMesh );
0326: pMesh = pTempMesh;
0327: }
0328:
0329:
0330:
0331:
0332:
0333: rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
0334: if( rgdwAdjacency == NULL )
0335: return E_OUTOFMEMORY;
0336: V( pMesh->GenerateAdjacency(1e-6f,rgdwAdjacency) );
0337: V( pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
0338: delete []rgdwAdjacency;
0339:
0340: *ppMesh = pMesh;
0341:
0342: return S_OK;
0343: }
0344:
0345:
0346:
0347:
0348:
0349:
0350:
0351:
0352:
0353:
0354:
0355: HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
0356: const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
0357: {
0358: HRESULT hr;
0359:
0360: if( g_pFont )
0361: V_RETURN( g_pFont->OnResetDevice() );
0362: V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
0363:
0364: pd3dDevice->GetViewport(&g_ViewportFB);
0365:
0366:
0367: if( g_pEffect )
0368: V_RETURN( g_pEffect->OnResetDevice() );
0369:
0370: g_hWorldViewProjection = g_pEffect->GetParameterByName( NULL, "mWVP" );
0371: g_hMeshTexture = g_pEffect->GetParameterByName( NULL, "DecaleTex" );
0372: g_hTech = g_pEffect->GetTechniqueByName("TShader");
0373:
0374:
0375: D3DXVECTOR3 vecEye(0.0f, 0.0f, -4.0f);
0376: D3DXVECTOR3 vecAt (0.0f, 0.0f, 0.0f);
0377: g_Camera.SetViewParams( &vecEye, &vecAt );
0378:
0379:
0380: float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
0381: g_Camera.SetProjParams( D3DXToRadian(60.0f), fAspectRatio, 0.5f, 100.0f );
0382:
0383:
0384: pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
0385: pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
0386:
0387:
0388: g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
0389: g_HUD.SetSize( 170, 170 );
0390: g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width-170, pBackBufferSurfaceDesc->Height-300 );
0391: g_SampleUI.SetSize( 170, 250 );
0392:
0393: return S_OK;
0394: }
0395:
0396:
0397:
0398:
0399:
0400:
0401:
0402:
0403:
0404:
0405:
0406: void CALLBACK OnLostDevice()
0407: {
0408: if( g_pFont )
0409: g_pFont->OnLostDevice();
0410:
0411: if( g_pEffect )
0412: g_pEffect->OnLostDevice();
0413: SAFE_RELEASE(g_pTextSprite);
0414: }
0415:
0416:
0417:
0418:
0419:
0420:
0421:
0422:
0423:
0424:
0425: void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
0426: {
0427:
0428: g_Camera.FrameMove( fElapsedTime );
0429:
0430:
0431: D3DXMATRIX matRotY;
0432: D3DXMATRIX matRotX;
0433: D3DXMatrixRotationX( &matRotX, g_fLightRotX );
0434: D3DXMatrixRotationY( &matRotY, g_fLightRotY );
0435: D3DXMatrixMultiply( &g_mLight, &matRotY, &matRotX );
0436: }
0437:
0438:
0439:
0440:
0441:
0442:
0443:
0444:
0445:
0446:
0447: void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
0448: {
0449: HRESULT hr;
0450: D3DXMATRIXA16 m;
0451: D3DXMATRIXA16 mWorld;
0452: D3DXMATRIXA16 mView;
0453: D3DXMATRIXA16 mProj;
0454: D3DXMATRIXA16 mWorldViewProjection;
0455: D3DXVECTOR4 v;
0456: UINT iPass, cPasses;
0457:
0458: D3DXVECTOR4 LightPos = D3DXVECTOR4(0.0f, 0.0f, -3.0f, 0.0f);
0459: D3DXVec4Transform( &LightPos, &LightPos, &g_mLight );
0460:
0461:
0462: V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );
0463:
0464:
0465: if( SUCCEEDED( pd3dDevice->BeginScene() ) )
0466: {
0467:
0468: mWorld = *g_Camera.GetWorldMatrix();
0469: mProj = *g_Camera.GetProjMatrix();
0470: mView = *g_Camera.GetViewMatrix();
0471:
0472: mWorldViewProjection = mWorld * mView * mProj;
0473:
0474:
0475:
0476:
0477: V( g_pEffect->SetMatrix( g_hWorldViewProjection, &mWorldViewProjection) );
0478: V( g_pEffect->SetTexture( g_hMeshTexture, g_pScene1MeshTexture) );
0479:
0480: float shift = fmod( 0.1f*(float)fTime, 1.0f );
0481: V( g_pEffect->SetFloat( "fShift", shift ) );
0482:
0483: D3DXMatrixInverse( &m, NULL, &mWorld );
0484: D3DXVec4Transform( &v, &LightPos, &m );
0485: V( g_pEffect->SetVector( "LightPos", &v ) );
0486:
0487:
0488: V( g_pEffect->Begin(&cPasses, 0) );
0489: for (iPass = 0; iPass < cPasses; iPass++)
0490: {
0491: V( g_pEffect->BeginPass(iPass) );
0492: V( g_pScene1Mesh->DrawSubset(0) );
0493: V( g_pEffect->EndPass() );
0494: }
0495: V( g_pEffect->End() );
0496:
0497: {
0498: m = mView * mProj;
0499: v = LightPos;
0500: v.w = 1;
0501: D3DXVec4Transform( &v, &v, &m );
0502: float x = g_ViewportFB.Width *( 0.5f*v.x/v.w+0.5f);
0503: float y = g_ViewportFB.Height*(-0.5f*v.y/v.w+0.5f);
0504:
0505: pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
0506: pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_DIFFUSE);
0507: pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP, D3DTOP_DISABLE);
0508: pd3dDevice->SetVertexShader(NULL);
0509: pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_DIFFUSE );
0510: pd3dDevice->SetPixelShader(0);
0511:
0512: typedef struct {FLOAT p[4]; DWORD color;} LVERTEX;
0513: LVERTEX Vertex[4] = {
0514:
0515: {x-3,y-3, v.z/v.w, 1, 0xffffc0,},
0516: {x+3,y-3, v.z/v.w, 1, 0xffffc0,},
0517: {x+3,y+3, v.z/v.w, 1, 0xffffc0,},
0518: {x-3,y+3, v.z/v.w, 1, 0xffffc0,},
0519: };
0520: pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( LVERTEX ) );
0521: }
0522:
0523:
0524:
0525: DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" );
0526: RenderText();
0527: V( g_HUD.OnRender( fElapsedTime ) );
0528: V( g_SampleUI.OnRender( fElapsedTime ) );
0529: DXUT_EndPerfEvent();
0530:
0531: V( pd3dDevice->EndScene() );
0532: }
0533: }
0534:
0535:
0536:
0537:
0538:
0539:
0540:
0541:
0542: void RenderText()
0543: {
0544:
0545:
0546:
0547:
0548: CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
0549:
0550:
0551: txtHelper.Begin();
0552: txtHelper.SetInsertionPos( 5, 5 );
0553: txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
0554: txtHelper.DrawTextLine( DXUTGetFrameStats() );
0555: txtHelper.DrawTextLine( DXUTGetDeviceStats() );
0556:
0557: txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
0558:
0559:
0560:
0561:
0562:
0563: if( g_bShowHelp )
0564: {
0565: const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
0566: txtHelper.SetInsertionPos( 2, pd3dsdBackBuffer->Height-15*6 );
0567: txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );
0568: txtHelper.DrawTextLine( L"Controls (F1 to hide):" );
0569:
0570: txtHelper.SetInsertionPos( 20, pd3dsdBackBuffer->Height-15*5 );
0571: txtHelper.DrawTextLine( L"Look: Left drag mouse\n"
0572: L"Move: A,W,S,D or Arrow Keys\n"
0573: L"Move up/down: Q,E or PgUp,PgDn\n"
0574: L"Reset camera: End\n" );
0575: }
0576: else
0577: {
0578: txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
0579: txtHelper.DrawTextLine( L"Press F1 for help" );
0580: }
0581: txtHelper.End();
0582: }
0583:
0584:
0585:
0586:
0587:
0588:
0589:
0590: LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing )
0591: {
0592:
0593: *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
0594: if( *pbNoFurtherProcessing )
0595: return 0;
0596: *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
0597: if( *pbNoFurtherProcessing )
0598: return 0;
0599:
0600:
0601: g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
0602:
0603: return 0;
0604: }
0605:
0606:
0607:
0608:
0609:
0610:
0611:
0612:
0613: void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown )
0614: {
0615: if( bKeyDown )
0616: {
0617: switch( nChar )
0618: {
0619: case VK_F1: g_bShowHelp = !g_bShowHelp; break;
0620: }
0621: }
0622: }
0623:
0624:
0625:
0626:
0627:
0628: void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl )
0629: {
0630: switch( nControlID )
0631: {
0632: case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
0633: case IDC_TOGGLEREF: DXUTToggleREF(); break;
0634: case IDC_CHANGEDEVICE: DXUTSetShowSettingsDialog( !DXUTGetShowSettingsDialog() ); break;
0635: }
0636: }
0637: