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