0001: //--------------------------------------------------------------------------------------
0002: // File: main.cpp
0003: //
0004: // Starting point for new Direct3D applications
0005: // 新しいDirect3Dアプリケーションのための開始点
0006: //
0007: // Copyright (c) Microsoft Corporation. All rights reserved.
0008: //--------------------------------------------------------------------------------------
0009: #include "dxstdafx.h"
0010: #include "resource.h"
0011: #include "main_fx.h"
0012: 
0013: //#define DEBUG_VS   // Uncomment this line to debug vertex shaders 
0014:                      // 頂点シェーダをデバッグするにはこの行のコメントをはずせ
0015: //#define DEBUG_PS   // Uncomment this line to debug pixel shaders 
0016:                      // ピクセルシェーダをデバッグするにはこの行のコメントをはずせ
0017: 
0018: 
0019: //--------------------------------------------------------------------------------------
0020: // Vertex format
0021: //--------------------------------------------------------------------------------------
0022: struct VERTEX 
0023: {
0024:     D3DXVECTOR3 pos;
0025:     D3DXVECTOR2 tex;
0026: 
0027:     static const DWORD FVF;
0028: };
0029: const DWORD VERTEX::FVF = D3DFVF_XYZ | D3DFVF_TEX1;
0030: 
0031: //--------------------------------------------------------------------------------------
0032: // Global variables
0033: // グローバル変数
0034: //--------------------------------------------------------------------------------------
0035: IDirect3DDevice9*       g_pd3dDevice = NULL;
0036: ID3DXFont*              g_pFont = NULL;         // Font for drawing text
0037:                                                 // テキストを描画するためのテキスト
0038: ID3DXSprite*            g_pTextSprite = NULL;   // Sprite for batching draw text calls
0039:                                                 // 
0040: ID3DXEffect*            g_pEffect = NULL;       // D3DX effect interface
0041:                                                 // D3DX エフェクトのインターフェイス
0042: CModelViewerCamera      g_Camera;               // A model viewing camera
0043:                                                 // モデルを見ているカメラ
0044: bool                    g_bShowHelp = true;     // If true, it renders the UI control text
0045:                                                 // 真の時にはUI制御のテキストを描画する
0046: CDXUTDialog             g_HUD;                  // dialog for standard controls
0047:                                                 // 標準制御のダイアログ
0048: CDXUTDialog             g_SampleUI;             // dialog for sample specific controls
0049:                                                 // サンプル特有のコントロールのダイアログ
0050: 
0051: D3DVIEWPORT9            g_ViewportFB;
0052: 
0053: VERTEX                  g_Vertex[4];
0054: LPDIRECT3DTEXTURE9      g_pWangTexture = NULL;
0055: 
0056: DWORD                   g_MapSize = 32;
0057: LPDIRECT3DTEXTURE9      g_pRandTexture = NULL;
0058: 
0059: 
0060: //--------------------------------------------------------------------------------------
0061: // UI control IDs
0062: // UI を制御するためのID群
0063: //--------------------------------------------------------------------------------------
0064: #define IDC_TOGGLEFULLSCREEN    1
0065: #define IDC_TOGGLEREF           2
0066: #define IDC_CHANGEDEVICE        3
0067: #define IDC_CHANGE_LEVEL_STATIC 4
0068: #define IDC_CHANGE_LEVEL        5
0069: 
0070: 
0071: 
0072: //--------------------------------------------------------------------------------------
0073: // Forward declarations 
0074: // 前宣言
0075: //--------------------------------------------------------------------------------------
0076: bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed );
0077: void    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps );
0078: HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
0079: HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
0080: void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
0081: void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
0082: LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing );
0083: void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown  );
0084: void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl );
0085: void    CALLBACK OnLostDevice();
0086: void    CALLBACK OnDestroyDevice();
0087: 
0088: void    InitApp();
0089: HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh );
0090: void    RenderText();
0091: 
0092: 
0093: //--------------------------------------------------------------------------------------
0094: // Entry point to the program. Initializes everything and goes into a message processing 
0095: // loop. Idle time is used to render the scene.
0096: // プログラムの開始点。全てを初期化してメッセージ処理ループに入る。待機時間はシーンの描画
0097: // に使われる
0098: //--------------------------------------------------------------------------------------
0099: INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
0100: {
0101:     // Set the callback functions. These functions allow the sample framework to notify
0102:     // the application about device changes, user input, and windows messages.  The 
0103:     // callbacks are optional so you need only set callbacks for events you're interested 
0104:     // in. However, if you don't handle the device reset/lost callbacks then the sample 
0105:     // framework won't be able to reset your device since the application must first 
0106:     // release all device resources before resetting.  Likewise, if you don't handle the 
0107:     // device created/destroyed callbacks then the sample framework won't be able to 
0108:     // recreate your device resources.
0109:     DXUTSetCallbackDeviceCreated( OnCreateDevice );
0110:     DXUTSetCallbackDeviceReset( OnResetDevice );
0111:     DXUTSetCallbackDeviceLost( OnLostDevice );
0112:     DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
0113:     DXUTSetCallbackMsgProc( MsgProc );
0114:     DXUTSetCallbackKeyboard( KeyboardProc );
0115:     DXUTSetCallbackFrameRender( OnFrameRender );
0116:     DXUTSetCallbackFrameMove( OnFrameMove );
0117: 
0118:     // Show the cursor and clip it when in full screen
0119:     DXUTSetCursorSettings( true, true );
0120: 
0121:     InitApp();
0122: 
0123:     // Initialize the sample framework and create the desired Win32 window and Direct3D 
0124:     // device for the application. Calling each of these functions is optional, but they
0125:     // allow you to set several options which control the behavior of the framework.
0126:     DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
0127:     DXUTCreateWindow( L"main" );
0128:     DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );
0129: 
0130:     // Pass control to the sample framework for handling the message pump and 
0131:     // dispatching render calls. The sample framework will call your FrameMove 
0132:     // and FrameRender callback when there is idle time between handling window messages.
0133:     DXUTMainLoop();
0134: 
0135:     // Perform any application-level cleanup here. Direct3D device resources are released within the
0136:     // appropriate callback functions and therefore don't require any cleanup code here.
0137: 
0138:     return DXUTGetExitCode();
0139: }
0140: 
0141: 
0142: //--------------------------------------------------------------------------------------
0143: // Initialize the app 
0144: // アプリケーションの初期化
0145: //--------------------------------------------------------------------------------------
0146: void InitApp()
0147: {
0148:     g_pEffect = NULL;
0149: 
0150:     g_Vertex[0].pos = D3DXVECTOR3(+1,0,-1);
0151:     g_Vertex[1].pos = D3DXVECTOR3(-1,0,-1);
0152:     g_Vertex[2].pos = D3DXVECTOR3(+1,0,+1);
0153:     g_Vertex[3].pos = D3DXVECTOR3(-1,0,+1);
0154:     g_Vertex[0].tex = D3DXVECTOR2(1,1);
0155:     g_Vertex[1].tex = D3DXVECTOR2(0,1);
0156:     g_Vertex[2].tex = D3DXVECTOR2(1,0);
0157:     g_Vertex[3].tex = D3DXVECTOR2(0,0);
0158: 
0159:     // Initialize dialogs
0160:     // ダイアログの初期化
0161:     g_HUD.SetCallback( OnGUIEvent ); int iY = 10; 
0162:     g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 35, iY, 125, 22 );
0163:     g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 35, iY += 24, 125, 22 );
0164:     g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22 );
0165: 
0166:     g_SampleUI.SetCallback( OnGUIEvent ); iY = 10; 
0167: //    g_SampleUI.AddComboBox( 19, 35, iY += 24, 125, 22 );
0168: //    g_SampleUI.GetComboBox( 19 )->AddItem( L"Text1", NULL );
0169: //    g_SampleUI.GetComboBox( 19 )->AddItem( L"Text2", NULL );
0170: //    g_SampleUI.GetComboBox( 19 )->AddItem( L"Text3", NULL );
0171: //    g_SampleUI.GetComboBox( 19 )->AddItem( L"Text4", NULL );
0172: //    g_SampleUI.AddCheckBox( 21, L"Checkbox1", 35, iY += 24, 125, 22 );
0173: //    g_SampleUI.AddCheckBox( 11, L"Checkbox2", 35, iY += 24, 125, 22 );
0174: //    g_SampleUI.AddRadioButton( 12, 1, L"Radio1G1", 35, iY += 24, 125, 22 );
0175: //    g_SampleUI.AddRadioButton( 13, 1, L"Radio2G1", 35, iY += 24, 125, 22 );
0176: //    g_SampleUI.AddRadioButton( 14, 1, L"Radio3G1", 35, iY += 24, 125, 22 );
0177: //    g_SampleUI.GetRadioButton( 14 )->SetChecked( true ); 
0178: //    g_SampleUI.AddButton( 17, L"Button1", 35, iY += 24, 125, 22 );
0179: //    g_SampleUI.AddButton( 18, L"Button2", 35, iY += 24, 125, 22 );
0180: //    g_SampleUI.AddRadioButton( 15, 2, L"Radio1G2", 35, iY += 24, 125, 22 );
0181: //    g_SampleUI.AddRadioButton( 16, 2, L"Radio2G3", 35, iY += 24, 125, 22 );
0182: //    g_SampleUI.GetRadioButton( 16 )->SetChecked( true );
0183: //    g_SampleUI.AddSlider( 20, 50, iY += 24, 100, 22 );
0184: //    g_SampleUI.GetSlider( 20 )->SetRange( 0, 100 );
0185: //    g_SampleUI.GetSlider( 20 )->SetValue( 50 );
0186: //    g_SampleUI.AddEditBox( 20, L"Test", 35, iY += 24, 125, 22 );
0187: 
0188:     WCHAR sz[100];
0189:     iY += 256;
0190:     _snwprintf( sz, 100, L"SIZE: %3d", g_MapSize ); sz[99] = 0;
0191:     g_SampleUI.AddStatic( IDC_CHANGE_LEVEL_STATIC, sz, 35, iY += 24, 125, 22 );
0192:     g_SampleUI.AddSlider( IDC_CHANGE_LEVEL, -150, iY += 24, 300, 22, 1, 256, (int)g_MapSize );
0193: }
0194: 
0195: //--------------------------------------------------------------------------------------
0196: // Called during device initialization, this code checks the device for some 
0197: // minimum set of capabilities, and rejects those that don't pass by returning false.
0198: //--------------------------------------------------------------------------------------
0199: bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
0200:                                   D3DFORMAT BackBufferFormat, bool bWindowed )
0201: {
0202:     // Skip backbuffer formats that don't support alpha blending
0203:     // アルファブレンディングをサポートしていないバックバッファフォーマットはスキップする
0204:     IDirect3D9* pD3D = DXUTGetD3DObject(); 
0205:     if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
0206:                     AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
0207:                     D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
0208:         return false;
0209: 
0210:     // Must support vertex shader 1.1
0211:     if( pCaps->VertexShaderVersion < D3DVS_VERSION( 1, 1 ) )
0212:         return false;
0213: 
0214:     // Must support pixel shader 2.0
0215:     if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )
0216:         return false;
0217: 
0218:     return true;
0219: }
0220: 
0221: 
0222: //--------------------------------------------------------------------------------------
0223: // This callback function is called immediately before a device is created to allow the 
0224: // application to modify the device settings. The supplied pDeviceSettings parameter 
0225: // contains the settings that the framework has selected for the new device, and the 
0226: // application can make any desired changes directly to this structure.  Note however that 
0227: // the sample framework will not correct invalid device settings so care must be taken 
0228: // to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail.  
0229: //--------------------------------------------------------------------------------------
0230: void CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps )
0231: {
0232:     // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 
0233:     // then switch to SWVP.
0234:     if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
0235:          pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
0236:     {
0237:         pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0238:     }
0239:     else
0240:     {
0241:         pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
0242:     }
0243: 
0244:     // This application is designed to work on a pure device by not using 
0245:     // IDirect3D9::Get*() methods, so create a pure device if supported and using HWVP.
0246:     if ((pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 && 
0247:         (pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 )
0248:         pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE;
0249: 
0250:     // Debugging vertex shaders requires either REF or software vertex processing 
0251:     // and debugging pixel shaders requires REF.  
0252: #ifdef DEBUG_VS
0253:     if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
0254:     {
0255:         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
0256:         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
0257:         pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0258:     }
0259: #endif
0260: #ifdef DEBUG_PS
0261:     pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
0262: #endif
0263: }
0264: 
0265: //-------------------------------------------------------------
0266: // マップの乱数生成
0267: //-------------------------------------------------------------
0268: #define frand() ((FLOAT)rand()/(FLOAT)RAND_MAX)
0269: 
0270: VOID WINAPI FillRand (D3DXVECTOR4* pOut, CONST D3DXVECTOR2* pTexCoord, 
0271: CONST D3DXVECTOR2* pTexelSize, LPVOID pData)
0272: {
0273:     UNREFERENCED_PARAMETER( pTexCoord );
0274:     UNREFERENCED_PARAMETER( pTexelSize );
0275:     UNREFERENCED_PARAMETER( pData );
0276: 
0277:     pOut->x = frand();
0278:     pOut->y = frand();
0279:     pOut->z = pOut->w = 0.0f;
0280: }
0281: 
0282: 
0283: //--------------------------------------------------------------------------------------
0284: // This callback function will be called immediately after the Direct3D device has been 
0285: // created, which will happen during application initialization and windowed/full screen 
0286: // toggles. This is the best location to create D3DPOOL_MANAGED resources since these 
0287: // resources need to be reloaded whenever the device is destroyed. Resources created  
0288: // here should be released in the OnDestroyDevice callback. 
0289: //--------------------------------------------------------------------------------------
0290: HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
0291: {
0292:     HRESULT hr;
0293:     WCHAR str[MAX_PATH];
0294: 
0295:     g_pd3dDevice = pd3dDevice;
0296: 
0297:     // Initialize the font
0298:     V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, 
0299:                          OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
0300:                          L"Arial", &g_pFont ) );
0301: 
0302:     // Load the textures
0303:     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"wang.bmp" ) );
0304:     V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, str, &g_pWangTexture) );
0305: 
0306:     V_RETURN( pd3dDevice->CreateTexture( g_MapSize, g_MapSize, 1
0307:                         , 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &g_pRandTexture, NULL));
0308:     V_RETURN( D3DXFillTexture( g_pRandTexture, FillRand, NULL ));
0309: 
0310: 
0311:     // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the 
0312:     // shader debugger. Debugging vertex shaders requires either REF or software vertex 
0313:     // processing, and debugging pixel shaders requires REF.  The 
0314:     // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the 
0315:     // shader debugger.  It enables source level debugging, prevents instruction 
0316:     // reordering, prevents dead code elimination, and forces the compiler to compile 
0317:     // against the next higher available software target, which ensures that the 
0318:     // unoptimized shaders do not exceed the shader model limitations.  Setting these 
0319:     // flags will cause slower rendering since the shaders will be unoptimized and 
0320:     // forced into software.  See the DirectX documentation for more information about 
0321:     // using the shader debugger.
0322:     DWORD dwShaderFlags = 0;
0323:     #ifdef DEBUG_VS
0324:         dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
0325:     #endif
0326:     #ifdef DEBUG_PS
0327:         dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
0328:     #endif
0329: 
0330: 
0331:     // Create the D3DX effect file
0332:     V_RETURN( D3DXCreateEffect( pd3dDevice, g_effect, sizeof(g_effect),
0333:         NULL, NULL, dwShaderFlags, NULL, &g_pEffect, NULL ) );
0334: 
0335: 
0336:     // Setup the camera's view parameters
0337:     D3DXVECTOR3 vecEye(0.0f, 3.0f, -3.0f);
0338:     D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f);
0339:     g_Camera.SetViewParams( &vecEye, &vecAt );
0340: 
0341:     return S_OK;
0342: }
0343: 
0344: 
0345: //--------------------------------------------------------------------------------------
0346: // This function loads the mesh and ensures the mesh has normals; it also optimizes the 
0347: // mesh for the graphics card's vertex cache, which improves performance by organizing 
0348: // the internal triangle list for less cache misses.
0349: //--------------------------------------------------------------------------------------
0350: HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh )
0351: {
0352:     ID3DXMesh* pMesh = NULL;
0353:     WCHAR str[MAX_PATH];
0354:     HRESULT hr;
0355: 
0356:     // Load the mesh with D3DX and get back a ID3DXMesh*.  For this
0357:     // sample we'll ignore the X file's embedded materials since we know 
0358:     // exactly the model we're loading.  See the mesh samples such as
0359:     // "OptimizedMesh" for a more generic mesh loading example.
0360:     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) );
0361: 
0362:     V_RETURN( D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh) );
0363: 
0364:     DWORD *rgdwAdjacency = NULL;
0365: 
0366:     // Make sure there are normals which are required for lighting
0367:     if( !(pMesh->GetFVF() & D3DFVF_NORMAL) )
0368:     {
0369:         ID3DXMesh* pTempMesh;
0370:         V( pMesh->CloneMeshFVF( pMesh->GetOptions(), 
0371:                                   pMesh->GetFVF() | D3DFVF_NORMAL, 
0372:                                   pd3dDevice, &pTempMesh ) );
0373:         V( D3DXComputeNormals( pTempMesh, NULL ) );
0374: 
0375:         SAFE_RELEASE( pMesh );
0376:         pMesh = pTempMesh;
0377:     }
0378: 
0379:     // Optimize the mesh for this graphics card's vertex cache 
0380:     // so when rendering the mesh's triangle list the vertices will 
0381:     // cache hit more often so it won't have to re-execute the vertex shader 
0382:     // on those vertices so it will improve perf.     
0383:     rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
0384:     if( rgdwAdjacency == NULL )
0385:         return E_OUTOFMEMORY;
0386:     V( pMesh->ConvertPointRepsToAdjacency(NULL, rgdwAdjacency) );
0387:     V( pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
0388:     delete []rgdwAdjacency;
0389: 
0390:     *ppMesh = pMesh;
0391: 
0392:     return S_OK;
0393: }
0394: 
0395: 
0396: //--------------------------------------------------------------------------------------
0397: // This callback function will be called immediately after the Direct3D device has been 
0398: // reset, which will happen after a lost device scenario. This is the best location to 
0399: // create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever 
0400: // the device is lost. Resources created here should be released in the OnLostDevice 
0401: // callback. 
0402: //--------------------------------------------------------------------------------------
0403: HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
0404:                                 const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
0405: {
0406:     HRESULT hr;
0407: 
0408:     pd3dDevice->GetViewport(&g_ViewportFB);
0409: 
0410: 
0411:     if( g_pFont )
0412:         V_RETURN( g_pFont->OnResetDevice() );
0413:     if( g_pEffect )
0414:         V_RETURN( g_pEffect->OnResetDevice() );
0415: 
0416:     // Create a sprite to help batch calls when drawing many lines of text
0417:     V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
0418: 
0419:     // Setup the camera's projection parameters
0420:     float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
0421:     g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1f, 1000.0f );
0422:     g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
0423: 
0424:     g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
0425:     g_HUD.SetSize( 170, 170 );
0426:     g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width-170, pBackBufferSurfaceDesc->Height-350 );
0427:     g_SampleUI.SetSize( 170, 300 );
0428: 
0429:     return S_OK;
0430: }
0431: 
0432: 
0433: //--------------------------------------------------------------------------------------
0434: // This callback function will be called once at the beginning of every frame. This is the
0435: // best location for your application to handle updates to the scene, but is not 
0436: // intended to contain actual rendering calls, which should instead be placed in the 
0437: // OnFrameRender callback.  
0438: //--------------------------------------------------------------------------------------
0439: void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
0440: {
0441:     // Update the camera's position based on user input 
0442:     g_Camera.FrameMove( fElapsedTime );
0443: }
0444: 
0445: 
0446: 
0447: //--------------------------------------------------------------------------------------
0448: // This callback function will be called at the end of every frame to perform all the 
0449: // rendering calls for the scene, and it will also be called if the window needs to be 
0450: // repainted. After this function has returned, the sample framework will call 
0451: // IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
0452: //--------------------------------------------------------------------------------------
0453: void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
0454: {
0455:     HRESULT hr;
0456:     UINT iPass, cPasses;
0457:     D3DXMATRIXA16 mWorld;
0458:     D3DXMATRIXA16 mCamera;
0459:     D3DXMATRIXA16 mView;
0460:     D3DXMATRIXA16 mProj;
0461:     D3DXMATRIXA16 mWorldViewProjection;
0462:     
0463:     // Clear the render target and the zbuffer 
0464:     V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );
0465: 
0466:     // Render the scene
0467:     if( SUCCEEDED( pd3dDevice->BeginScene() ) )
0468:     {
0469:         // Get the projection & view matrix from the camera class
0470:         mCamera = *g_Camera.GetWorldMatrix();
0471:         mView = *g_Camera.GetViewMatrix();
0472:         mProj = *g_Camera.GetProjMatrix();
0473: 
0474:         mWorldViewProjection = mCamera * mView * mProj;
0475: 
0476:         // Set world render technique
0477:         V( g_pEffect->SetTechnique( "WangTechnique" ) );
0478: 
0479:         // Update the effect's variables.  Instead of using strings, it would 
0480:         // be more efficient to cache a handle to the parameter by calling 
0481:         // ID3DXEffect::GetParameterByName
0482:         V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
0483: 
0484:         V( g_pEffect->SetTexture( "WangTexture", g_pWangTexture ) );
0485:         V( g_pEffect->SetTexture( "RandTexture", g_pRandTexture ) );
0486:         V( g_pEffect->SetFloat( "g_fTexSize",         (float)g_MapSize ) );
0487:         V( g_pEffect->SetFloat( "g_fInvTexSize", 1.0f/(float)g_MapSize ) );
0488: 
0489:         pd3dDevice->SetFVF( VERTEX::FVF );
0490: 
0491:         V( g_pEffect->Begin(&cPasses, 0) );
0492:         for (iPass = 0; iPass < cPasses; iPass++)
0493:         {
0494:             V( g_pEffect->BeginPass(iPass) );
0495:             pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP,2, g_Vertex, sizeof(VERTEX) );
0496:             V( g_pEffect->EndPass() );
0497:         }
0498:         V( g_pEffect->End() );
0499: 
0500: 
0501: 
0502:         DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); // These events are to help PIX identify what the code is doing
0503:         RenderText();
0504:         V( g_HUD.OnRender( fElapsedTime ) );
0505:         V( g_SampleUI.OnRender( fElapsedTime ) );
0506:         DXUT_EndPerfEvent();
0507: 
0508: #ifdef _DEBUG // Textures are displaying when debugging, (デバッグ用にテクスチャを表示する)
0509:         {
0510:         pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,  D3DTOP_SELECTARG1);
0511:         pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,    D3DTA_TEXTURE);
0512:         pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0513:         pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0514:         pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
0515:         pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0516:         float scale = 64.0f;
0517:         typedef struct { FLOAT p[4]; FLOAT tu, tv;} TVERTEX;
0518: 
0519:         for(DWORD i=0; i<2; i++){
0520:             TVERTEX Vertex[4] = {
0521:                 //    x                             y         z rhw tu tv
0522:                 {(i+0)*scale, (FLOAT)g_ViewportFB.Height-scale, 0, 1, 0, 0,},
0523:                 {(i+1)*scale, (FLOAT)g_ViewportFB.Height-scale, 0, 1, 1, 0,},
0524:                 {(i+1)*scale, (FLOAT)g_ViewportFB.Height-    0, 0, 1, 1, 1,},
0525:                 {(i+0)*scale, (FLOAT)g_ViewportFB.Height-    0, 0, 1, 0, 1,},
0526:             };
0527:             if(0==i) pd3dDevice->SetTexture( 0, g_pWangTexture );
0528:             if(1==i) pd3dDevice->SetTexture( 0, g_pRandTexture );
0529: 
0530:             pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0531:         }
0532:         }
0533: #endif      
0534: 
0535:         V( pd3dDevice->EndScene() );
0536:     }
0537: }
0538: 
0539: 
0540: //--------------------------------------------------------------------------------------
0541: // Render the help and statistics text. This function uses the ID3DXFont interface for 
0542: // efficient text rendering.
0543: //--------------------------------------------------------------------------------------
0544: void RenderText()
0545: {
0546:     // The helper object simply helps keep track of text position, and color
0547:     // and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );
0548:     // If NULL is passed in as the sprite object, then it will work however the 
0549:     // pFont->DrawText() will not be batched together.  Batching calls will improves performance.
0550:     const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
0551:     CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
0552: 
0553:     // Output statistics
0554:     txtHelper.Begin();
0555:     txtHelper.SetInsertionPos( 5, 5 );
0556:     txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
0557:     txtHelper.DrawTextLine( DXUTGetFrameStats() );
0558:     txtHelper.DrawTextLine( DXUTGetDeviceStats() );
0559: 
0560:     txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
0561:     txtHelper.DrawTextLine( L"Put whatever misc status here" );
0562:     
0563:     // Draw help
0564:     if( g_bShowHelp )
0565:     {
0566:         txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*3 );
0567:         txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );
0568:         txtHelper.DrawTextLine( L"Controls (F1 to hide):" );
0569: 
0570:         txtHelper.SetInsertionPos( 40, pd3dsdBackBuffer->Height-15*5 );
0571:         txtHelper.DrawTextLine( L"Quit: ESC" );
0572:     }
0573:     else
0574:     {
0575:         txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*2 );
0576:         txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
0577:         txtHelper.DrawTextLine( L"Press F1 for help" );
0578:     }
0579:     txtHelper.End();
0580: }
0581: 
0582: 
0583: //--------------------------------------------------------------------------------------
0584: // Before handling window messages, the sample framework passes incoming windows 
0585: // messages to the application through this callback function. If the application sets 
0586: // *pbNoFurtherProcessing to TRUE, then the sample framework will not process this message.
0587: //--------------------------------------------------------------------------------------
0588: LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing )
0589: {
0590:     // Give the dialogs a chance to handle the message first
0591:     *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
0592:     if( *pbNoFurtherProcessing )
0593:         return 0;
0594:     *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
0595:     if( *pbNoFurtherProcessing )
0596:         return 0;
0597: 
0598:     // Pass all remaining windows messages to camera so it can respond to user input
0599:     g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
0600: 
0601:     return 0;
0602: }
0603: 
0604: 
0605: //--------------------------------------------------------------------------------------
0606: // As a convenience, the sample framework inspects the incoming windows messages for
0607: // keystroke messages and decodes the message parameters to pass relevant keyboard
0608: // messages to the application.  The framework does not remove the underlying keystroke 
0609: // messages, which are still passed to the application's MsgProc callback.
0610: //--------------------------------------------------------------------------------------
0611: void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown )
0612: {
0613:     if( bKeyDown )
0614:     {
0615:         switch( nChar )
0616:         {
0617:             case VK_F1: g_bShowHelp = !g_bShowHelp; break;
0618:         }
0619:     }
0620: }
0621: 
0622: 
0623: //--------------------------------------------------------------------------------------
0624: // Handles the GUI events
0625: //--------------------------------------------------------------------------------------
0626: void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl )
0627: {
0628:     switch( nControlID )
0629:     {
0630:         case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
0631:         case IDC_TOGGLEREF:        DXUTToggleREF(); break;
0632:         case IDC_CHANGEDEVICE:     DXUTSetShowSettingsDialog( !DXUTGetShowSettingsDialog() ); break;
0633:         case IDC_CHANGE_LEVEL:
0634:         {
0635:             WCHAR sz[100];
0636:             g_MapSize = g_SampleUI.GetSlider( IDC_CHANGE_LEVEL )->GetValue();
0637:             _snwprintf( sz, 100, L"SIZE: %3d", g_MapSize ); sz[99] = 0;
0638:             g_SampleUI.GetStatic( IDC_CHANGE_LEVEL_STATIC )->SetText( sz );
0639:             
0640:             if( g_pRandTexture )
0641:             {
0642:                 SAFE_RELEASE( g_pRandTexture );
0643:                 g_pd3dDevice->CreateTexture( g_MapSize, g_MapSize, 1
0644:                                     , 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &g_pRandTexture, NULL);
0645:                 D3DXFillTexture( g_pRandTexture, FillRand, NULL );
0646:             }
0647: 
0648:             break;
0649:         }
0650:    }
0651: }
0652: 
0653: 
0654: //--------------------------------------------------------------------------------------
0655: // This callback function will be called immediately after the Direct3D device has 
0656: // entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
0657: // in the OnResetDevice callback should be released here, which generally includes all 
0658: // D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for 
0659: // information about lost devices.
0660: //--------------------------------------------------------------------------------------
0661: void CALLBACK OnLostDevice()
0662: {
0663:     if( g_pFont )
0664:         g_pFont->OnLostDevice();
0665:     if( g_pEffect )
0666:         g_pEffect->OnLostDevice();
0667:     SAFE_RELEASE( g_pTextSprite );
0668: }
0669: 
0670: 
0671: //--------------------------------------------------------------------------------------
0672: // This callback function will be called immediately after the Direct3D device has 
0673: // been destroyed, which generally happens as a result of application termination or 
0674: // windowed/full screen toggles. Resources created in the OnCreateDevice callback 
0675: // should be released here, which generally includes all D3DPOOL_MANAGED resources. 
0676: //--------------------------------------------------------------------------------------
0677: void CALLBACK OnDestroyDevice()
0678: {
0679:     SAFE_RELEASE( g_pEffect );
0680:     SAFE_RELEASE( g_pFont );
0681: 
0682:     SAFE_RELEASE( g_pRandTexture );
0683:     SAFE_RELEASE( g_pWangTexture );
0684: }
0685: 
0686: 
0687: 
0688: