0001: //-------------------------------------------------------------
0002: // File: main.cpp
0003: //
0004: // Desc: 丸影
0005: //-------------------------------------------------------------
0006: #define STRICT
0007: #include <windows.h>
0008: #include <commctrl.h>
0009: #include <commdlg.h>
0010: #include <basetsd.h>
0011: #include <math.h>
0012: #include <stdio.h>
0013: #include <d3dx9.h>
0014: #include <dxerr9.h>
0015: #include <tchar.h>
0016: #include "DXUtil.h"
0017: #include "D3DEnumeration.h"
0018: #include "D3DSettings.h"
0019: #include "D3DApp.h"
0020: #include "D3DFont.h"
0021: #include "D3DFile.h"
0022: #include "D3DUtil.h"
0023: #include "resource.h"
0024: #include "main.h"
0025: 
0026: static const UINT MAP_SIZE = 256;
0027: 
0028: //-------------------------------------------------------------
0029: // グローバル変数
0030: //-------------------------------------------------------------
0031: CMyD3DApplication* g_pApp  = NULL;
0032: HINSTANCE          g_hInst = NULL;
0033: 
0034: 
0035: //-------------------------------------------------------------
0036: // Name: WinMain()
0037: // Desc: メイン関数
0038: //-------------------------------------------------------------
0039: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0040: {
0041:     CMyD3DApplication d3dApp;
0042: 
0043:     g_pApp  = &d3dApp;
0044:     g_hInst = hInst;
0045: 
0046:     InitCommonControls();
0047:     if( FAILED( d3dApp.Create( hInst ) ) )
0048:         return 0;
0049: 
0050:     return d3dApp.Run();
0051: }
0052: 
0053: 
0054: 
0055: 
0056: //-------------------------------------------------------------
0057: // Name: CMyD3DApplication()
0058: // Desc: アプリケーションのコンストラクタ
0059: //-------------------------------------------------------------
0060: CMyD3DApplication::CMyD3DApplication()
0061: {
0062:     m_pMeshBG                   = new CD3DMesh();               
0063: 
0064:     m_pMapZ                     = NULL;
0065:     m_pIrradianceMap            = NULL;
0066:     m_pIrradianceMapSurf        = NULL;
0067:     m_pSubLightMap[0]           = NULL;
0068:     m_pSubLightMap[1]           = NULL;
0069:     m_pSubLightMapSurf[0]       = NULL;
0070:     m_pSubLightMapSurf[1]       = NULL;
0071:     m_pPosMap                   = NULL;
0072:     m_pPosMapSurf               = NULL;
0073:     m_pDistMap                  = NULL;
0074:     m_pDistMapSurf              = NULL;
0075:     m_bDistMap                  = FALSE;
0076: 
0077:     m_pEffect                   = NULL;
0078:     m_pDecl                     = NULL;
0079:     m_hTechPos                  = NULL;
0080:     m_hTechDist                 = NULL;
0081:     m_hTechIrradiance           = NULL;
0082:     m_hTechSubLight             = NULL;
0083:     m_hTechFinal                = NULL;
0084:     m_hmWVP                     = NULL;
0085:     m_hvDir                     = NULL;
0086:     m_htDecale                  = NULL;
0087:     m_htIrradiance              = NULL;
0088:     m_htSubLight                = NULL;
0089: 
0090: 
0091:     m_zoom                      = 5.0f;
0092:     m_fWorldRotX                = -0.26337099f;
0093:     m_fWorldRotY                = 1.8705539f;
0094:     m_LightDir                  = D3DXVECTOR3( 0.8f, 0.6f,-0.0f);
0095: 
0096: 
0097:     m_dwCreationWidth           = 500;
0098:     m_dwCreationHeight          = 375;
0099:     m_strWindowTitle            = TEXT( "main" );
0100:     m_d3dEnumeration.AppUsesDepthBuffer   = TRUE;
0101:     m_bStartFullscreen          = false;
0102:     m_bShowCursorWhenFullscreen = false;
0103: 
0104:     m_pFont                     = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0105:     m_bLoadingApp               = TRUE;
0106:     
0107:     ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0108: }
0109: 
0110: 
0111: 
0112: 
0113: //-------------------------------------------------------------
0114: // Name: ~CMyD3DApplication()
0115: // Desc: デストラクタ
0116: //-------------------------------------------------------------
0117: CMyD3DApplication::~CMyD3DApplication()
0118: {
0119: }
0120: 
0121: 
0122: 
0123: 
0124: //-------------------------------------------------------------
0125: // Name: OneTimeSceneInit()
0126: // Desc: 一度だけ行う初期化
0127: //      ウィンドウの初期化やIDirect3D9の初期化は終わってます。
0128: //      ただ、LPDIRECT3DDEVICE9 の初期化は終わっていません。
0129: //-------------------------------------------------------------
0130: HRESULT CMyD3DApplication::OneTimeSceneInit()
0131: {
0132:     // ローディングメッセージを表示する
0133:     SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0134: 
0135:     m_bLoadingApp = FALSE;
0136: 
0137:     return S_OK;
0138: }
0139: 
0140: 
0141: 
0142: 
0143: //-------------------------------------------------------------
0144: // Name: ConfirmDevice()
0145: // Desc: 初期化の時に呼ばれます。必要な能力をチェックします。
0146: //-------------------------------------------------------------
0147: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps
0148:                         , DWORD dwBehavior, D3DFORMAT Format )
0149: {
0150:     BOOL bCapsAcceptable = TRUE;
0151: 
0152:     UNREFERENCED_PARAMETER( Format );
0153:     UNREFERENCED_PARAMETER( dwBehavior );
0154:     UNREFERENCED_PARAMETER( pCaps );
0155:     
0156:     // ピクセルシェーダバージョンチェック
0157:     if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
0158:         bCapsAcceptable = FALSE;
0159: 
0160:     // 頂点シェーダバージョンが上位かソフトウェア頂点処理
0161:     if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
0162:         if( (dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING ) == 0 )
0163:             bCapsAcceptable = FALSE;
0164: 
0165:     return bCapsAcceptable;
0166: }
0167: 
0168: 
0169: //-------------------------------------------------------------
0170: // Name: InitDeviceObjects()
0171: // Desc: デバイスが生成された後の初期化をします。
0172: //      フレームバッファフォーマットやデバイスの種類が変わった
0173: //      後に通過します。
0174: //      ここで確保したメモリはDeleteDeviceObjects()で開放します
0175: //-------------------------------------------------------------
0176: HRESULT CMyD3DApplication::InitDeviceObjects()
0177: {
0178:     HRESULT hr;
0179: 
0180:     // 背景メッシュの読み込み
0181:     if( FAILED( hr = m_pMeshBG->Create(m_pd3dDevice, "map.x" )))
0182:         return DXTRACE_ERR( "Load Mesh", hr );
0183:     m_pMeshBG->SetFVF( m_pd3dDevice, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 );
0184:         
0185:     // シェーダの読み込み
0186:     LPD3DXBUFFER pErr;
0187:     if( FAILED( hr = D3DXCreateEffectFromFile(
0188:                         m_pd3dDevice, "hlsl.fx", NULL, NULL, 
0189:                         D3DXSHADER_DEBUG , NULL, &m_pEffect, &pErr ) ) ){
0190:         MessageBox( NULL, (LPCTSTR)pErr->GetBufferPointer(), "ERROR", MB_OK);
0191:         return DXTRACE_ERR( "CreateEffectFromFile", hr );
0192:     }
0193:     m_hTechPos        = m_pEffect->GetTechniqueByName( "TPos" );
0194:     m_hTechDist       = m_pEffect->GetTechniqueByName( "TDistance" );
0195:     m_hTechIrradiance = m_pEffect->GetTechniqueByName( "TIrradiance" );
0196:     m_hTechSubLight   = m_pEffect->GetTechniqueByName( "TSubLight" );
0197:     m_hTechFinal      = m_pEffect->GetTechniqueByName( "TFinal" );
0198: 
0199:     m_hmWVP         = m_pEffect->GetParameterByName( NULL, "mWVP" );
0200:     m_hvDir         = m_pEffect->GetParameterByName( NULL, "vLightDir" );
0201:     m_htDecale      = m_pEffect->GetParameterByName( NULL, "TexDecale" );
0202:     m_htIrradiance  = m_pEffect->GetParameterByName( NULL, "TexIrradiance" );
0203:     m_htSubLight    = m_pEffect->GetParameterByName( NULL, "TexSubLight" );
0204: 
0205:     // 頂点宣言のオブジェクトの生成(地形用)
0206:     D3DVERTEXELEMENT9 decl[] =
0207:     {
0208:         {0,  0, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
0209:         {0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0},
0210:         {0, 24, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
0211:         D3DDECL_END()
0212:     };
0213:     if( FAILED( hr = m_pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl )))
0214:         return DXTRACE_ERR ("CreateVertexDeclaration", hr);
0215: 
0216:     // フォント
0217:     m_pFont->InitDeviceObjects( m_pd3dDevice );
0218:     
0219:     return S_OK;
0220: }
0221: 
0222: //-------------------------------------------------------------
0223: // Name: RestoreDeviceObjects()
0224: // Desc: 画面のサイズが変更された時等に呼ばれます。
0225: //      確保したメモリはInvalidateDeviceObjects()で開放します。
0226: //-------------------------------------------------------------
0227: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0228: {
0229:     m_pMeshBG->RestoreDeviceObjects(m_pd3dDevice);
0230: 
0231:     // レンダリングターゲット深度の生成
0232:     if (FAILED(m_pd3dDevice->CreateDepthStencilSurface(MAP_SIZE, MAP_SIZE, 
0233:         D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, TRUE, &m_pMapZ, NULL)))
0234:         return E_FAIL;
0235:     // 照射マップ
0236:     if (FAILED(m_pd3dDevice->CreateTexture( MAP_SIZE, MAP_SIZE, 1, 
0237:         D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pIrradianceMap, NULL)))
0238:         return E_FAIL;
0239:     if (FAILED(m_pIrradianceMap->GetSurfaceLevel(0, &m_pIrradianceMapSurf)))
0240:         return E_FAIL;
0241:     // 表面下散乱マップ
0242:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0243:         D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pSubLightMap[0], NULL)))
0244:         return E_FAIL;
0245:     if (FAILED(m_pSubLightMap[0]->GetSurfaceLevel(0, &m_pSubLightMapSurf[0])))
0246:         return E_FAIL;
0247:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0248:         D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pSubLightMap[1], NULL)))
0249:         return E_FAIL;
0250:     if (FAILED(m_pSubLightMap[1]->GetSurfaceLevel(0, &m_pSubLightMapSurf[1])))
0251:         return E_FAIL;
0252:     // 高さマップ
0253:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0254:         D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &m_pPosMap, NULL)))
0255:         return E_FAIL;
0256:     if (FAILED(m_pPosMap->GetSurfaceLevel(0, &m_pPosMapSurf)))
0257:         return E_FAIL;
0258:     // ピクセル間の距離
0259:     m_bDistMap = FALSE;
0260:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0261:         D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &m_pDistMap, NULL)))
0262:         return E_FAIL;
0263:     if (FAILED(m_pDistMap->GetSurfaceLevel(0, &m_pDistMapSurf)))
0264:         return E_FAIL;
0265: 
0266: 
0267:     // 長いから短縮形を作ってみた
0268:     #define RS   m_pd3dDevice->SetRenderState
0269:     #define SAMP m_pd3dDevice->SetSamplerState
0270: 
0271:     // レンダリング状態の設定
0272:     RS  ( D3DRS_ZENABLE,        TRUE );
0273:     SAMP( 0, D3DSAMP_ADDRESSU,  D3DTADDRESS_CLAMP );
0274:     SAMP( 0, D3DSAMP_ADDRESSV,  D3DTADDRESS_CLAMP );
0275:     SAMP( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0276:     SAMP( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0277: 
0278:     // ライトの設定
0279:     D3DLIGHT9 light;
0280:     D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL,-m_LightDir.x,-m_LightDir.y,-m_LightDir.z );
0281:     m_pd3dDevice->SetLight( 0, &light );
0282:     m_pd3dDevice->LightEnable( 0, TRUE );
0283:     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
0284: 
0285:     // ワールド行列
0286:     D3DXMatrixIdentity( &m_mWorld );
0287: 
0288:     // 射影行列の設定
0289:     FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width )
0290:                   / ((FLOAT)m_d3dsdBackBuffer.Height);
0291:     D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect
0292:                                 , 1.0f, 100.0f );
0293:     m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_mProj );
0294: 
0295:     
0296:     if( m_pEffect!=NULL ) m_pEffect->OnResetDevice();// シェーダ
0297: 
0298:     m_pFont->RestoreDeviceObjects();    // フォント
0299: 
0300:     return S_OK;
0301: }
0302: 
0303: 
0304: 
0305: 
0306: //-------------------------------------------------------------
0307: // Name: FrameMove()
0308: // Desc: 毎フレーム呼ばれます。アニメの処理などを行います。
0309: //-------------------------------------------------------------
0310: HRESULT CMyD3DApplication::FrameMove()
0311: {
0312:     UpdateInput( &m_UserInput ); // 入力データの更新
0313: 
0314:     //---------------------------------------------------------
0315:     // 入力に応じて座標系を更新する
0316:     //---------------------------------------------------------
0317:     // 回転
0318:     if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0319:         m_fWorldRotY += m_fElapsedTime;
0320:     else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0321:         m_fWorldRotY -= m_fElapsedTime;
0322: 
0323:     if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0324:         m_fWorldRotX += m_fElapsedTime;
0325:     else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0326:         m_fWorldRotX -= m_fElapsedTime;
0327: 
0328:     // ズーム
0329:     if(m_UserInput.bZ && !m_UserInput.bX)
0330:         m_zoom += 0.01f;
0331:     else if(m_UserInput.bX && !m_UserInput.bZ)
0332:         m_zoom -= 0.01f;
0333: 
0334:     //---------------------------------------------------------
0335:     // 行列の更新
0336:     //---------------------------------------------------------
0337:     // ワールドの回転
0338:     D3DXMATRIX m, matRotX, matRotY;
0339:     D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0340:     D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0341:     D3DXMatrixMultiply( &m_mCamera, &matRotY, &matRotX );
0342: 
0343:     // ビュー行列
0344:     D3DXVECTOR3 vEye    = D3DXVECTOR3( 0.0f, 0.0f, -m_zoom );
0345:     D3DXVECTOR3 vLookat = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0346:     D3DXVECTOR3 vUp     = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0347:     D3DXMatrixLookAtLH( &m_mView, &vEye, &vLookat, &vUp );
0348:     m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_mView );
0349: 
0350: 
0351:     return S_OK;
0352: }
0353: 
0354: 
0355: 
0356: 
0357: //-------------------------------------------------------------
0358: // Name: UpdateInput()
0359: // Desc: 入力データを更新する
0360: //-------------------------------------------------------------
0361: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0362: {
0363:     pUserInput->bRotateUp    = ( m_bActive && (GetAsyncKeyState( VK_UP )    & 0x8000) == 0x8000 );
0364:     pUserInput->bRotateDown  = ( m_bActive && (GetAsyncKeyState( VK_DOWN )  & 0x8000) == 0x8000 );
0365:     pUserInput->bRotateLeft  = ( m_bActive && (GetAsyncKeyState( VK_LEFT )  & 0x8000) == 0x8000 );
0366:     pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0367:     pUserInput->bZ = ( m_bActive && (GetAsyncKeyState( 'Z' ) & 0x8000) == 0x8000 );
0368:     pUserInput->bX = ( m_bActive && (GetAsyncKeyState( 'X' ) & 0x8000) == 0x8000 );
0369: }
0370: 
0371: 
0372: 
0373: 
0374: //-------------------------------------------------------------
0375: // Name: Render()
0376: // Desc: 画面を描画する.
0377: //-------------------------------------------------------------
0378: HRESULT CMyD3DApplication::Render()
0379: {
0380:     LPDIRECT3DSURFACE9 pOldBackBuffer, pOldZBuffer;
0381:     D3DVIEWPORT9 oldViewport;
0382:     D3DXMATRIX m, mL;
0383:     D3DXVECTOR4 v;
0384:     FLOAT ds = 0.5f/(FLOAT)MAP_SIZE;// テクセル中心移動用
0385:     FLOAT dt = 0.5f/(FLOAT)MAP_SIZE;
0386: 
0387:     static int id = 0;  // 表面下散乱マップのどちらを使うか
0388:     id ^= 1;
0389: 
0390:     // 変更用ビューポート    x y   width   height  minz maxz
0391:     D3DVIEWPORT9 viewport = {0,0, MAP_SIZE,MAP_SIZE,0.0f,1.0f};
0392: 
0393:     if( SUCCEEDED( m_pd3dDevice->BeginScene())) // 描画の開始
0394:     {
0395:         if(m_pEffect != NULL)
0396:         {
0397:             //-------------------------------------------------
0398:             // レンダリングターゲットの保存
0399:             //-------------------------------------------------
0400:             m_pd3dDevice->GetRenderTarget(0, &pOldBackBuffer);
0401:             m_pd3dDevice->GetDepthStencilSurface(&pOldZBuffer);
0402:             m_pd3dDevice->GetViewport(&oldViewport);
0403: 
0404:             if(!m_bDistMap){// 距離マップの生成
0405:                 m_bDistMap = TRUE;
0406:                 //---------------------------------------------
0407:                 // 高さマップの生成
0408:                 //---------------------------------------------
0409:                 m_pd3dDevice->SetRenderTarget(0, m_pPosMapSurf);
0410:                 m_pd3dDevice->SetDepthStencilSurface(m_pMapZ);
0411:                 m_pd3dDevice->SetViewport(&viewport);
0412: 
0413:                 // レンダリングターゲットのクリア
0414:                 m_pd3dDevice->Clear(0L, NULL,
0415:                                 D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0416:                                 0x000000, 1.0f, 0L);
0417: 
0418:                 m_pEffect->SetTechnique( m_hTechPos );
0419:                 m_pEffect->Begin( NULL, 0 );
0420:                 m_pEffect->Pass( 0 );
0421:                 m_pd3dDevice->SetVertexDeclaration( m_pDecl );
0422: 
0423:                 m_pMeshBG->Render( m_pd3dDevice );
0424: 
0425:                 m_pEffect->End();
0426: 
0427:                 //---------------------------------------------
0428:                 // 距離マップの生成
0429:                 //---------------------------------------------
0430:                 m_pd3dDevice->SetRenderTarget(0, m_pDistMapSurf);
0431:                 m_pd3dDevice->SetDepthStencilSurface(m_pMapZ);
0432:                 m_pd3dDevice->SetViewport(&viewport);
0433: 
0434:                 // レンダリングターゲットのクリア
0435:                 m_pd3dDevice->Clear(0L, NULL,
0436:                                 D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0437:                                 0x000000, 1.0f, 0L);
0438: 
0439:                 m_pEffect->SetTechnique( m_hTechDist );
0440:                 m_pEffect->Begin( NULL, 0 );
0441:                 m_pEffect->Pass( 0 );
0442:                 m_pd3dDevice->SetFVF( D3DFVF_XYZ | D3DFVF_TEX1 );
0443: 
0444:                 typedef struct {FLOAT p[3]; FLOAT tu, tv;} TVERTEX;
0445: 
0446:                 TVERTEX Vertex[4] = {
0447:                     //x  y   z     tu    tv
0448:                     {-1,-1, 0.1f, 0.0f+ds, 1.0f+dt,},
0449:                     { 1,-1, 0.1f, 1.0f+ds, 1.0f+dt,},
0450:                     { 1, 1, 0.1f, 1.0f+ds, 0.0f+dt,},
0451:                     {-1, 1, 0.1f, 0.0f+ds, 0.0f+dt,},
0452:                 };
0453:                 m_pd3dDevice->SetTexture( 0, m_pPosMap );
0454:                 m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0455: 
0456:                 m_pEffect->End();
0457: 
0458:                 //---------------------------------------------
0459:                 // 表面下散乱マップのクリア
0460:                 //---------------------------------------------
0461:                 id = 0;
0462:                 for(int i=0; i<2; i++){
0463:                     m_pd3dDevice->SetRenderTarget(0, m_pSubLightMapSurf[i]);
0464:                     m_pd3dDevice->SetDepthStencilSurface(m_pMapZ);
0465:                     m_pd3dDevice->SetViewport(&viewport);
0466: 
0467:                     // レンダリングターゲットのクリア
0468:                     m_pd3dDevice->Clear(0L, NULL,
0469:                                     D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0470:                                     0x000000, 1.0f, 0L);
0471:                 }
0472:             }
0473:             //---------------------------------------------
0474:             // 照射マップの生成
0475:             //---------------------------------------------
0476:             m_pd3dDevice->SetRenderTarget(0, m_pIrradianceMapSurf);
0477:             m_pd3dDevice->SetDepthStencilSurface(m_pMapZ);
0478:             m_pd3dDevice->SetViewport(&viewport);
0479: 
0480:             // レンダリングターゲットのクリア
0481:             m_pd3dDevice->Clear(0L, NULL,
0482:                             D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0483:                             0x000000, 1.0f, 0L);
0484: 
0485:             m_pEffect->SetTechnique( m_hTechIrradiance );
0486:             m_pEffect->Begin( NULL, 0 );
0487:             m_pEffect->Pass( 0 );
0488:             m_pd3dDevice->SetVertexDeclaration( m_pDecl );
0489: 
0490:             D3DXMatrixInverse( &m, NULL, &m_mCamera);
0491:             D3DXVec3Transform( &v, &m_LightDir, &m );
0492:             v.w = 0.1f;// 環境色
0493:             m_pEffect->SetVector( m_hvDir, &v );
0494: 
0495:             m_pMeshBG->Render( m_pd3dDevice );
0496: 
0497:             m_pEffect->End();
0498: 
0499:             //---------------------------------------------
0500:             // 表面下散乱マップの生成
0501:             //---------------------------------------------
0502:             m_pd3dDevice->SetRenderTarget(0, m_pSubLightMapSurf[id]);
0503:             m_pd3dDevice->SetDepthStencilSurface(m_pMapZ);
0504:             m_pd3dDevice->SetViewport(&viewport);
0505: 
0506:             m_pEffect->SetTechnique( m_hTechSubLight );
0507:             m_pEffect->Begin( NULL, 0 );
0508:             m_pEffect->Pass( 0 );
0509: 
0510:             m_pEffect->SetTexture( m_htIrradiance, m_pIrradianceMap);
0511:             m_pEffect->SetTexture( m_htSubLight, m_pSubLightMap[1-id]);
0512:             m_pd3dDevice->SetFVF( D3DFVF_XYZ | D3DFVF_TEX1 );
0513: 
0514:             typedef struct {FLOAT p[3]; FLOAT tu, tv;} TVERTEX;
0515:             TVERTEX Vertex[4] = {
0516:                 //x  y   z     tu    tv
0517:                 {-1,-1, 0.1f, 0.0f+ds, 1.0f+dt,},
0518:                 { 1,-1, 0.1f, 1.0f+ds, 1.0f+dt,},
0519:                 { 1, 1, 0.1f, 1.0f+ds, 0.0f+dt,},
0520:                 {-1, 1, 0.1f, 0.0f+ds, 0.0f+dt,},
0521:             };
0522:             m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0523: 
0524:             m_pEffect->End();
0525: 
0526: 
0527:             //-------------------------------------------------
0528:             // レンダリングターゲットを元に戻す
0529:             //-------------------------------------------------
0530:             m_pd3dDevice->SetRenderTarget(0, pOldBackBuffer);
0531:             m_pd3dDevice->SetDepthStencilSurface(pOldZBuffer);
0532:             m_pd3dDevice->SetViewport(&oldViewport);
0533:             pOldBackBuffer->Release();
0534:             pOldZBuffer->Release();
0535: 
0536:             // 画面をクリアする
0537:             m_pd3dDevice->Clear( 0L, NULL,
0538:                                 D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0539:                                 0x4004080, 1.0f, 0L );
0540:             
0541:             // エフェクトの設定
0542:             m_pEffect->SetTechnique( m_hTechFinal );
0543:             m_pEffect->Begin( NULL, 0 );
0544:             m_pEffect->Pass( 0 );
0545:             m_pd3dDevice->SetVertexDeclaration( m_pDecl );
0546: 
0547:             m = m_mCamera * m_mView * m_mProj;
0548:             m_pEffect->SetMatrix( m_hmWVP, &m );
0549: 
0550:             // 背景の描画
0551:             m_pMeshBG->Render( m_pd3dDevice );
0552: 
0553:             m_pEffect->End();
0554:         }
0555: 
0556: #if 1 // デバッグ用にテクスチャを表示する
0557:     m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0558:     m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0559:     m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0560:     m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0561:     m_pd3dDevice->SetVertexShader(NULL);
0562:     m_pd3dDevice->SetPixelShader(0);
0563:     for(DWORD loop = 0; loop < 2; loop++){
0564:         const float scale = 64.0f;
0565:         typedef struct {FLOAT p[4]; FLOAT tu, tv;} TVERTEX;
0566: 
0567:         TVERTEX Vertex[4] = {
0568:             //       x        y   z rhw tu tv
0569:             {(loop  )*scale,    0,0, 1, 0.0f+ds, 0.0f+dt,},
0570:             {(loop+1)*scale,    0,0, 1, 1.0f+ds, 0.0f+dt,},
0571:             {(loop+1)*scale,scale,0, 1, 1.0f+ds, 1.0f+dt,},
0572:             {(loop  )*scale,scale,0, 1, 0.0f+ds, 1.0f+dt,},
0573:         };
0574:         switch(loop){
0575: //      case 0: m_pd3dDevice->SetTexture( 0, m_pPosMap          ); break;
0576: //      case 1: m_pd3dDevice->SetTexture( 0, m_pDistMap         ); break;
0577:         case 0: m_pd3dDevice->SetTexture( 0, m_pIrradianceMap   ); break;
0578:         case 1: m_pd3dDevice->SetTexture( 0, m_pSubLightMap[0]  ); break;
0579:         }
0580:         m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0581:     }
0582: #endif      
0583:         RenderText();               // ヘルプ等の表示
0584: 
0585:         m_pd3dDevice->EndScene();   // 描画の終了
0586:     }
0587:     
0588:     return S_OK;
0589: }
0590: 
0591: 
0592: 
0593: 
0594: //-------------------------------------------------------------
0595: // Name: RenderText()
0596: // Desc: 状態やヘルプを画面に表示する
0597: //-------------------------------------------------------------
0598: HRESULT CMyD3DApplication::RenderText()
0599: {
0600:     D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
0601:     TCHAR szMsg[MAX_PATH] = TEXT("");
0602: 
0603:     FLOAT fNextLine = 40.0f; 
0604: 
0605:     // 操作法やパラメータを表示する
0606:     fNextLine = (FLOAT) m_d3dsdBackBuffer.Height; 
0607:     sprintf( szMsg, "Zoom: %f", m_zoom );
0608:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0609:     lstrcpy( szMsg, TEXT("Use arrow keys to rotate object") );
0610:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0611:     lstrcpy( szMsg, TEXT("Press 'z' or 'x' to change zoom") );
0612:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0613:     // ディスプレイの状態を表示する
0614:     lstrcpy( szMsg, m_strDeviceStats );
0615:     fNextLine -= 20.0f;m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0616:     lstrcpy( szMsg, m_strFrameStats );
0617:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0618:     
0619:     return S_OK;
0620: }
0621: 
0622: 
0623: 
0624: 
0625: //-------------------------------------------------------------
0626: // Name: MsgProc()
0627: // Desc: WndProc をオーバーライドしたもの
0628: //-------------------------------------------------------------
0629: LRESULT CMyD3DApplication::MsgProc( HWND hWnd,
0630:                     UINT msg, WPARAM wParam, LPARAM lParam )
0631: {
0632:     switch( msg )
0633:     {
0634:         case WM_PAINT:
0635:         {
0636:             if( m_bLoadingApp )
0637:             {
0638:                 // ロード中
0639:                 HDC hDC = GetDC( hWnd );
0640:                 TCHAR strMsg[MAX_PATH];
0641:                 wsprintf(strMsg, TEXT("Loading... Please wait"));
0642:                 RECT rct;
0643:                 GetClientRect( hWnd, &rct );
0644:                 DrawText( hDC, strMsg, -1, &rct,
0645:                         DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0646:                 ReleaseDC( hWnd, hDC );
0647:             }
0648:             break;
0649:         }
0650: 
0651:     }
0652: 
0653:     return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0654: }
0655: 
0656: 
0657: 
0658: 
0659: //-------------------------------------------------------------
0660: // Name: InvalidateDeviceObjects()
0661: // Desc: RestoreDeviceObjects() で作成したオブジェクトの開放
0662: //-------------------------------------------------------------
0663: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0664: {
0665:     // レンダリングターゲット
0666:     SAFE_RELEASE(m_pIrradianceMapSurf);
0667:     SAFE_RELEASE(m_pIrradianceMap);
0668:     SAFE_RELEASE(m_pSubLightMapSurf[0]);
0669:     SAFE_RELEASE(m_pSubLightMapSurf[1]);
0670:     SAFE_RELEASE(m_pSubLightMap[0]);
0671:     SAFE_RELEASE(m_pSubLightMap[1]);
0672:     SAFE_RELEASE(m_pDistMapSurf);
0673:     SAFE_RELEASE(m_pDistMap);
0674:     SAFE_RELEASE(m_pPosMapSurf);
0675:     SAFE_RELEASE(m_pPosMap);
0676:     SAFE_RELEASE(m_pMapZ);
0677:     m_bDistMap = FALSE;
0678: 
0679:     if(m_pEffect!=NULL) m_pEffect->OnLostDevice();  // シェーダ
0680: 
0681:     m_pMeshBG->InvalidateDeviceObjects(); // メッシュ
0682:     
0683:     m_pFont->InvalidateDeviceObjects(); // フォント
0684: 
0685:     return S_OK;
0686: }
0687: 
0688: 
0689: 
0690: 
0691: //-------------------------------------------------------------
0692: // Name: DeleteDeviceObjects()
0693: // Desc: InitDeviceObjects() で作成したオブジェクトを開放する
0694: //-------------------------------------------------------------
0695: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0696: {
0697:     m_pMeshBG->Destroy();
0698: 
0699:     SAFE_RELEASE( m_pDecl );        // 頂点宣言
0700:     SAFE_RELEASE( m_pEffect );      // シェーダ
0701: 
0702:     m_pFont->DeleteDeviceObjects(); // フォント
0703: 
0704:     return S_OK;
0705: }
0706: 
0707: 
0708: 
0709: 
0710: //-------------------------------------------------------------
0711: // Name: FinalCleanup()
0712: // Desc: 終了する直線に呼ばれる
0713: //-------------------------------------------------------------
0714: HRESULT CMyD3DApplication::FinalCleanup()
0715: {
0716:     SAFE_DELETE( m_pMeshBG ); // メッシュ
0717: 
0718:     SAFE_DELETE( m_pFont ); // フォント
0719: 
0720:     return S_OK;
0721: }
0722: 
0723: 
0724: 
0725: 
0726: