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