0001: //-------------------------------------------------------------
0002: // File: main.cpp
0003: //
0004: // Desc: PRT
0005: // Copyright (c) 2004 IMAGIRE Takashi. All rights reserved.
0006: //-------------------------------------------------------------
0007: #define STRICT
0008: #include <windows.h>
0009: #include <commctrl.h>
0010: #include <commdlg.h>
0011: #include <basetsd.h>
0012: #include <math.h>
0013: #include <stdio.h>
0014: #include <d3dx9.h>
0015: #include <dxerr9.h>
0016: #include <tchar.h>
0017: #include "DXUtil.h"
0018: #include "D3DEnumeration.h"
0019: #include "D3DSettings.h"
0020: #include "D3DApp.h"
0021: #include "D3DFont.h"
0022: #include "D3DFile.h"
0023: #include "D3DUtil.h"
0024: #include "resource.h"
0025: #include "main.h"
0026: 
0027: #define MAP_SIZE        256// PRTテクスチャのサイズ。この数字を大きくすると細かくなる
0028: #define DIFFUSE_SIZE    64
0029: 
0030: 
0031: //-------------------------------------------------------------
0032: // 頂点の構造体
0033: //-------------------------------------------------------------
0034: typedef struct {
0035:     FLOAT       p[4];
0036:     FLOAT       tu, tv;
0037: } TVERTEX;
0038: 
0039: //-------------------------------------------------------------
0040: // グローバル変数
0041: //-------------------------------------------------------------
0042: CMyD3DApplication* g_pApp  = NULL;
0043: HINSTANCE          g_hInst = NULL;
0044: 
0045: //-------------------------------------------------------------
0046: // Name: WinMain()
0047: // Desc: メイン関数
0048: //-------------------------------------------------------------
0049: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0050: {
0051:     CMyD3DApplication d3dApp;
0052: 
0053:     g_pApp  = &d3dApp;
0054:     g_hInst = hInst;
0055: 
0056:     InitCommonControls();
0057:     if( FAILED( d3dApp.Create( hInst ) ) )
0058:         return 0;
0059: 
0060:     return d3dApp.Run();
0061: }
0062: 
0063: 
0064: 
0065: 
0066: //-------------------------------------------------------------
0067: // Name: CMyD3DApplication()
0068: // Desc: アプリケーションのコンストラクタ
0069: //-------------------------------------------------------------
0070: CMyD3DApplication::CMyD3DApplication()
0071: {
0072:     m_iState = -1;
0073:     m_Shader = 0;
0074: 
0075:     m_pMeshBg                   = new CD3DMesh();
0076: 
0077:     m_pMapZ                     = NULL;
0078:     m_pPosTex                   = NULL;
0079:     m_pPosSurf                  = NULL;
0080:     m_pPosLockTex               = NULL;
0081:     m_pPosLockSurf              = NULL;
0082:     m_pNormalTex                = NULL;
0083:     m_pNormalSurf               = NULL;
0084:     m_pNormalLockTex            = NULL;
0085:     m_pNormalLockSurf           = NULL;
0086: 
0087:     for(int i=0;i<TEX_MAX;i++){
0088:         m_pFinalTex[i]          = NULL;
0089:         m_pFinalSurf[i]         = NULL;
0090:     }
0091:     for(int j=0;j<REDUCTION_MAPS;j++){
0092:         m_pReductionTex[i]      = NULL;
0093:         m_pReductionSurf[i]     = NULL;
0094:     }
0095: 
0096:     m_pEffect                   = NULL;
0097:     m_hTechnique                = NULL;
0098:     m_hmWVP                     = NULL;
0099:     m_htSrcTex                  = NULL;
0100: 
0101:     m_fWorldRotX                = -0.5f;
0102:     m_fWorldRotY                = 0.0f;
0103:     m_fViewZoom                 = 13.0f;
0104: 
0105:     m_fLightRotX                = -0.80116916f;
0106:     m_fLightRotY                = 1.4874420f;
0107: 
0108:     m_dwCreationWidth           = 512;
0109:     m_dwCreationHeight          = 512;
0110:     m_strWindowTitle            = TEXT( "main" );
0111:     m_d3dEnumeration.AppUsesDepthBuffer   = TRUE;
0112:     m_bStartFullscreen          = false;
0113:     m_bShowCursorWhenFullscreen = false;
0114: 
0115:     m_pFont                     = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0116:     m_bLoadingApp               = TRUE;
0117: 
0118:     ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0119: }
0120: 
0121: 
0122: 
0123: 
0124: //-------------------------------------------------------------
0125: // Name: ~CMyD3DApplication()
0126: // Desc: デストラクタ
0127: //-------------------------------------------------------------
0128: CMyD3DApplication::~CMyD3DApplication()
0129: {
0130: }
0131: 
0132: 
0133: 
0134: 
0135: //-------------------------------------------------------------
0136: // Name: OneTimeSceneInit()
0137: // Desc: 一度だけ行う初期化
0138: //      ウィンドウの初期化やIDirect3D9の初期化は終わってます。
0139: //      ただ、LPDIRECT3DDEVICE9 の初期化は終わっていません。
0140: //-------------------------------------------------------------
0141: HRESULT CMyD3DApplication::OneTimeSceneInit()
0142: {
0143:     // ローディングメッセージを表示する
0144:     SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0145: 
0146:     m_bLoadingApp = FALSE;
0147: 
0148:     return S_OK;
0149: }
0150: 
0151: 
0152: 
0153: 
0154: //-------------------------------------------------------------
0155: // Name: ConfirmDevice()
0156: // Desc: 初期化の時に呼ばれます。必要な能力をチェックします。
0157: //-------------------------------------------------------------
0158: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps,
0159:                      DWORD dwBehavior,    D3DFORMAT Format )
0160: {
0161:     UNREFERENCED_PARAMETER( Format );
0162:     UNREFERENCED_PARAMETER( dwBehavior );
0163:     UNREFERENCED_PARAMETER( pCaps );
0164:     
0165: 
0166:     // ピクセルシェーダバージョンチェック
0167:     if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
0168:         return E_FAIL;
0169: 
0170:     // 頂点シェーダバージョンが上位かソフトウェア頂点処理
0171:     if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,1)
0172:     &&  0==(dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING) )
0173:             return E_FAIL;
0174: 
0175:     return S_OK;
0176: }
0177: 
0178: 
0179: //-------------------------------------------------------------
0180: // Name: InitDeviceObjects()
0181: // Desc: デバイスが生成された後の初期化をします。
0182: //      フレームバッファフォーマットやデバイスの種類が変わった
0183: //      後に通過します。
0184: //      ここで確保したメモリはDeleteDeviceObjects()で開放します
0185: //-------------------------------------------------------------
0186: HRESULT CMyD3DApplication::InitDeviceObjects()
0187: {
0188:     HRESULT hr;
0189: 
0190:     // 地面の読み込み
0191:     if(FAILED(hr=m_pMeshBg->Create( m_pd3dDevice, _T("map.x"))))
0192:         return DXTRACE_ERR( "Load Model", hr );
0193:     m_pMeshBg->UseMeshMaterials(FALSE);// レンダリング時にテクスチャの設定をしない
0194:         
0195:     // シェーダの読み込み
0196:     LPD3DXBUFFER pErr;
0197:     if( FAILED( hr = D3DXCreateEffectFromFile(
0198:                 m_pd3dDevice, "hlsl.fx", NULL, NULL, 
0199:                 D3DXSHADER_DEBUG , NULL, &m_pEffect, &pErr ))){
0200:         MessageBox( NULL, (LPCTSTR)pErr->GetBufferPointer()
0201:                     , "ERROR", MB_OK);
0202:         return DXTRACE_ERR( "CreateEffectFromFile", hr );
0203:     }
0204:     m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
0205:     m_hmWVP      = m_pEffect->GetParameterByName( NULL, "mWVP" );
0206:     m_htSrcTex   = m_pEffect->GetParameterByName( NULL, "SrcTex" );
0207: 
0208:     // フォント
0209:     m_pFont->InitDeviceObjects( m_pd3dDevice );
0210: 
0211:     return S_OK;
0212: }
0213: 
0214: //-------------------------------------------------------------
0215: // 真ん中が白い絵を作る
0216: //-------------------------------------------------------------
0217: VOID WINAPI FillTex (D3DXVECTOR4* pOut, CONST D3DXVECTOR2* pTexCoord, 
0218: CONST D3DXVECTOR2* pTexelSize, LPVOID pData)
0219: {
0220:     UNREFERENCED_PARAMETER( pTexelSize );
0221:     UNREFERENCED_PARAMETER( pData );
0222: 
0223:     FLOAT x = 2.0f*(pTexCoord->x-0.5f);
0224:     FLOAT y = 2.0f*(pTexCoord->y-0.5f);
0225:     FLOAT col = (x*x+y*y<(1.0f-1.0f/DIFFUSE_SIZE)*(1.0f-1.0f/DIFFUSE_SIZE))
0226:                 ? 1.0f : 0.0f;
0227:     
0228:     pOut->x = pOut->y = pOut->z = pOut->w = col;
0229: }
0230: 
0231: //-------------------------------------------------------------
0232: // Name: RestoreDeviceObjects()
0233: // Desc: 画面のサイズが変更された時等に呼ばれます。
0234: //      確保したメモリはInvalidateDeviceObjects()で開放します。
0235: //-------------------------------------------------------------
0236: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0237: {
0238:     m_iState = -1;
0239:     m_iChangeState = TRUE;
0240: 
0241:     DWORD i;
0242: 
0243:     // メッシュ
0244:     m_pMeshBg->RestoreDeviceObjects( m_pd3dDevice );
0245: 
0246:     // 質感の設定
0247:     D3DMATERIAL9 mtrl;
0248:     D3DUtil_InitMaterial( mtrl, 1.0f, 0.0f, 0.0f );
0249:     m_pd3dDevice->SetMaterial( &mtrl );
0250: 
0251: 
0252:     // レンダリング状態の設定
0253:     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,   FALSE );
0254:     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
0255:     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,        TRUE );
0256:     m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,        0x000F0F0F );
0257:     
0258:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
0259:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0260:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
0261:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
0262:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
0263:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
0264:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0265:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0266:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
0267:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
0268: 
0269:     // ワールド行列
0270:     D3DXMATRIX matIdentity;
0271:     D3DXMatrixIdentity( &m_mWorld );
0272: 
0273:     // ビュー行列
0274:     D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
0275:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0276:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0277:     D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0278: 
0279:     // 射影行列
0280:     FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0281:     D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0282: 
0283:     // フォント
0284:     m_pFont->RestoreDeviceObjects();
0285: 
0286:     // レンダリングターゲットの生成
0287:     if (FAILED(m_pd3dDevice->CreateDepthStencilSurface(MAP_SIZE, MAP_SIZE, 
0288:         D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, TRUE, &m_pMapZ, NULL)))
0289:         return E_FAIL;
0290:     // 位置マップ
0291:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0292:         D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &m_pPosTex, NULL)))
0293:         return E_FAIL;
0294:     if (FAILED(m_pPosTex->GetSurfaceLevel(0, &m_pPosSurf)))
0295:         return E_FAIL;
0296:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0297:         0, D3DFMT_A32B32G32R32F, D3DPOOL_SYSTEMMEM , &m_pPosLockTex, NULL)))
0298:         return E_FAIL;
0299:     if (FAILED(m_pPosLockTex->GetSurfaceLevel(0, &m_pPosLockSurf)))
0300:         return E_FAIL;
0301:     // 法線マップ
0302:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0303:         D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &m_pNormalTex, NULL)))
0304:         return E_FAIL;
0305:     if (FAILED(m_pNormalTex->GetSurfaceLevel(0, &m_pNormalSurf)))
0306:         return E_FAIL;
0307:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0308:         0, D3DFMT_A32B32G32R32F, D3DPOOL_SYSTEMMEM , &m_pNormalLockTex, NULL)))
0309:         return E_FAIL;
0310:     if (FAILED(m_pNormalLockTex->GetSurfaceLevel(0, &m_pNormalLockSurf)))
0311:         return E_FAIL;
0312:     // 拡散マップ
0313:     for(i=0;i<TEX_MAX;i++){
0314:         if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0315:             D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pFinalTex[i], NULL)))
0316:             return E_FAIL;
0317:         if (FAILED(m_pFinalTex[i]->GetSurfaceLevel(0, &m_pFinalSurf[i])))
0318:             return E_FAIL;
0319:     }
0320: 
0321:     // 縮小バッファ
0322:     for(i=0;i<REDUCTION_MAPS;i++){
0323:         int size = 1<<(3*(REDUCTION_MAPS-i));
0324:         if (FAILED(m_pd3dDevice->CreateTexture(size, size, 1, 
0325:             D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pReductionTex[i], NULL)))
0326:             return E_FAIL;
0327:         if (FAILED(m_pReductionTex[i]->GetSurfaceLevel(0, &m_pReductionSurf[i])))
0328:             return E_FAIL;
0329:     }
0330: 
0331:     // マスク用のテクスチャの生成
0332:     if( FAILED(m_pd3dDevice->CreateTexture(DIFFUSE_SIZE, DIFFUSE_SIZE, 1
0333:                           , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8
0334:                           , D3DPOOL_DEFAULT, &m_pMaskTex, NULL)))
0335:         return E_FAIL;
0336:     if( FAILED(D3DXFillTexture(m_pMaskTex, FillTex, NULL)))
0337:         return E_FAIL;
0338: 
0339:     m_pEffect->OnResetDevice();
0340: 
0341:     return S_OK;
0342: }
0343: 
0344: 
0345: //-------------------------------------------------------------
0346: // Name: FrameMoveCreateMap()
0347: // Desc: 位置、法線マップを作成する。
0348: //-------------------------------------------------------------
0349: int CMyD3DApplication::FrameMoveCreateMap()
0350: {
0351:     // 2回目の以降は次の処理に移る
0352:     if(1<m_iCount) return 1;
0353: 
0354:     return 0;
0355: }
0356: //-------------------------------------------------------------
0357: // Name: RenderCreateMap()
0358: // Desc: 位置、法線マップを作成する。
0359: //-------------------------------------------------------------
0360: void CMyD3DApplication::RenderCreateMap()
0361: {
0362:     LPDIRECT3DSURFACE9 pOldBackBuffer, pOldZBuffer;
0363:     D3DVIEWPORT9 oldViewport;
0364: 
0365:     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0366:     {
0367:         //-------------------------------------------------
0368:         // レンダリングターゲットの保存
0369:         //-------------------------------------------------
0370:         m_pd3dDevice->GetRenderTarget(0, &pOldBackBuffer);
0371:         m_pd3dDevice->GetDepthStencilSurface(&pOldZBuffer);
0372:         m_pd3dDevice->GetViewport(&oldViewport);
0373: 
0374:         //-------------------------------------------------
0375:         // レンダリングターゲットの変更
0376:         //-------------------------------------------------
0377:         m_pd3dDevice->SetRenderTarget(0, m_pPosSurf);
0378:         m_pd3dDevice->SetRenderTarget(1, m_pNormalSurf);
0379:         m_pd3dDevice->SetDepthStencilSurface(NULL);
0380:         // ビューポートの変更
0381:         D3DVIEWPORT9 viewport_height = {0,0      // 左上の座標
0382:                         , MAP_SIZE  // 幅
0383:                         , MAP_SIZE // 高さ
0384:                         , 0.0f,1.0f};     // 前面、後面
0385:         m_pd3dDevice->SetViewport(&viewport_height);
0386: 
0387:         //-------------------------------------------------
0388:         // フレームバッファのクリア
0389:         //-------------------------------------------------
0390:         m_pd3dDevice->Clear(0L, NULL
0391:                         , D3DCLEAR_TARGET
0392:                         , 0x00000000, 1.0f, 0L);
0393: 
0394:         if( m_pEffect != NULL ) 
0395:         {
0396:             //-------------------------------------------------
0397:             // シェーダの設定
0398:             //-------------------------------------------------
0399:             m_pEffect->SetTechnique( m_hTechnique );
0400:             m_pEffect->Begin( NULL, 0 );
0401:             m_pEffect->Pass( 0 );
0402: 
0403:             m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
0404:             m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
0405: 
0406:             //-------------------------------------------------
0407:             // 背景の描画
0408:             //-------------------------------------------------
0409:             m_pMeshBg->Render(m_pd3dDevice);
0410: 
0411:             m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
0412:             m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
0413: 
0414:             m_pEffect->End();
0415:         }
0416: 
0417:         //-----------------------------------------------------
0418:         // レンダリングターゲットを元に戻す
0419:         //-----------------------------------------------------
0420:         m_pd3dDevice->SetRenderTarget(0, pOldBackBuffer);
0421:         m_pd3dDevice->SetRenderTarget(1, NULL);
0422:         m_pd3dDevice->SetDepthStencilSurface(pOldZBuffer);
0423:         m_pd3dDevice->SetViewport(&oldViewport);
0424:         pOldBackBuffer->Release();
0425:         pOldZBuffer->Release();
0426: 
0427:         //-----------------------------------------------------
0428:         // ごまかしの画面
0429:         //-----------------------------------------------------
0430:         m_pd3dDevice->Clear(0L, NULL
0431:                         , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0432:                         , 0xff000000, 1.0f, 0L);
0433: 
0434:         m_pd3dDevice->EndScene();
0435:     }
0436: }
0437: 
0438: 
0439: //-------------------------------------------------------------
0440: // Name: FrameMoveCreateMap()
0441: // Desc: 位置、法線マップを作成する。
0442: //-------------------------------------------------------------
0443: static int itex=0;
0444: static int ix=0;
0445: static int iy=0;
0446: static float pos[MAP_SIZE][MAP_SIZE][3];
0447: static float normal[MAP_SIZE][MAP_SIZE][3];
0448: int CMyD3DApplication::FrameMoveFinalGathering()
0449: {
0450:     itex = this->m_iCount / (MAP_SIZE*MAP_SIZE);
0451:     ix = this->m_iCount % MAP_SIZE;
0452:     iy = (this->m_iCount / MAP_SIZE) % MAP_SIZE;
0453:     
0454:     if(0==this->m_iCount){
0455:         D3DLOCKED_RECT d3dlr;
0456:         float *p;
0457:         m_pd3dDevice->GetRenderTargetData(m_pPosSurf,m_pPosLockSurf);
0458:         m_pPosLockSurf->LockRect(&d3dlr,NULL,D3DLOCK_READONLY); //サーフェイス上の矩形をロック    
0459:         p = (float *)d3dlr.pBits;
0460:         for(int y=0;y<MAP_SIZE;y++){
0461:         for(int x=0;x<MAP_SIZE;x++){
0462:             pos[x][y][0]=p[0];
0463:             pos[x][y][1]=p[1];
0464:             pos[x][y][2]=p[2];
0465:             p+=4;
0466:         }
0467:         }
0468:         m_pPosLockSurf->UnlockRect();
0469: 
0470:         m_pd3dDevice->GetRenderTargetData(m_pNormalSurf,m_pNormalLockSurf);
0471:         m_pNormalLockSurf->LockRect(&d3dlr,NULL,D3DLOCK_READONLY); //サーフェイス上の矩形をロック    
0472:         p = (float *)d3dlr.pBits;        
0473:         for(int y=0;y<MAP_SIZE;y++){
0474:         for(int x=0;x<MAP_SIZE;x++){
0475:             normal[x][y][0]=p[0];
0476:             normal[x][y][1]=p[1];
0477:             normal[x][y][2]=p[2];
0478:             p+=4;
0479:         }
0480:         }
0481:         m_pNormalLockSurf->UnlockRect();
0482:     }
0483: 
0484:     // 終了条件
0485:     if(MAP_SIZE-1==ix && MAP_SIZE-1==iy && TEX_MAX-1==itex) return 1;
0486: 
0487:     return 0;
0488: }
0489: //-------------------------------------------------------------
0490: // Name: RenderFinalGathering()
0491: // Desc: それぞれの位置からのラディアンスを計算する。
0492: //-------------------------------------------------------------
0493: void CMyD3DApplication::RenderFinalGathering()
0494: {
0495:     int i;
0496:     D3DXMATRIX m, mView;
0497:     LPDIRECT3DSURFACE9 pOldBackBuffer, pOldZBuffer;
0498:     D3DVIEWPORT9 oldViewport;
0499:     D3DSURFACE_DESC d3dsd;
0500: 
0501:     D3DVIEWPORT9 viewport = {0,0      // 左上の座標
0502:                     , 1, 1  // 幅,高さ
0503:                     , 0.0f,1.0f};     // 前面、後面
0504: 
0505:     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0506:     {
0507:         m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
0508:         m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
0509: 
0510:         //-------------------------------------------------
0511:         // レンダリングターゲットの保存
0512:         //-------------------------------------------------
0513:         m_pd3dDevice->GetRenderTarget(0, &pOldBackBuffer);
0514:         m_pd3dDevice->GetDepthStencilSurface(&pOldZBuffer);
0515:         m_pd3dDevice->GetViewport(&oldViewport);
0516: 
0517:         //-------------------------------------------------
0518:         //-------------------------------------------------
0519:         // 各点から見たラディアンスの描画
0520:         //-------------------------------------------------
0521:         //-------------------------------------------------
0522: 
0523:         //-------------------------------------------------
0524:         // レンダリングターゲットの変更
0525:         //-------------------------------------------------
0526:         m_pd3dDevice->SetRenderTarget(0, m_pReductionSurf[0]);
0527:         m_pd3dDevice->SetDepthStencilSurface(NULL);
0528:         // ビューポートの変更
0529:         m_pReductionSurf[0]->GetDesc(&d3dsd);
0530:         viewport.Height = d3dsd.Width;
0531:         viewport.Width  = d3dsd.Height;
0532:         m_pd3dDevice->SetViewport(&viewport);
0533: 
0534:         if( m_pEffect != NULL ) 
0535:         {
0536:             //-------------------------------------------------
0537:             // 重みを持つ半球の部分だけ描画
0538:             //-------------------------------------------------
0539:             float x[3] = {pos[ix][iy][0], pos[ix][iy][1], pos[ix][iy][2]};
0540:             float n[3] = {normal[ix][iy][0], normal[ix][iy][1], normal[ix][iy][2]};
0541:             D3DXVECTOR3 vFromPt   = D3DXVECTOR3( x[0], x[1], x[2] ) + 0.001f*D3DXVECTOR3( n[0], n[1], n[2] );
0542:             D3DXVECTOR3 vLookatPt = D3DXVECTOR3( n[0], n[1], n[2] ) + vFromPt;
0543:             D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0544:             D3DXMatrixLookAtLH( &mView, &vFromPt, &vLookatPt, &vUpVec );
0545:             m_pEffect->SetMatrix( "mWV", &mView );
0546: 
0547:             D3DXMatrixTranspose(&m, &mView);
0548:             m_pEffect->SetMatrix( "mST", &m );
0549: 
0550:             // シェーダの設定
0551:             m_pEffect->SetTechnique( "TSphericalHarmonics" );
0552:             m_pEffect->Begin( NULL, 0 );
0553: 
0554:             TVERTEX Vertex[4] = {
0555:                 // x  y  z tu tv
0556:                 {-1,-1,0,  0, 0,},
0557:                 {+1,-1,0,  1, 0,},
0558:                 {+1,+1,0,  1, 1,},
0559:                 {-1,+1,0,  0, 1,},
0560:             };
0561:             m_pd3dDevice->SetFVF( D3DFVF_XYZ | D3DFVF_TEX1 );
0562:             m_pEffect->SetTexture(m_htSrcTex, m_pMaskTex);
0563: 
0564:             for(i=0;i<4;i++){
0565:                 switch(i){
0566:                 case 0:
0567:                     m_pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RED );
0568:                     break;
0569:                 case 1:
0570:                     m_pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN );
0571:                     break;
0572:                 case 2:
0573:                     m_pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_BLUE );
0574:                     break;
0575:                 case 3:
0576:                     m_pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA );
0577:                     break;
0578:                 }
0579:                 int no = 4*itex+i;
0580:                 m_pEffect->Pass( no );
0581:                 m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0582:             }
0583:             m_pEffect->End();
0584: 
0585:             //-------------------------------------------------
0586:             // シェーダの設定
0587:             //-------------------------------------------------
0588:             m_pEffect->SetTechnique( "TShader" );
0589:             m_pEffect->Begin( NULL, 0 );
0590:             m_pEffect->Pass( 1 );
0591:             
0592:             m_pd3dDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0xf );
0593: 
0594:             //-------------------------------------------------
0595:             // 背景の描画
0596:             //-------------------------------------------------
0597:             m_pMeshBg->Render(m_pd3dDevice);
0598: 
0599:             m_pEffect->End();
0600:         }
0601:         //-------------------------------------------------
0602:         //-------------------------------------------------
0603:         // ラディアンスをミップマップの要領で小さくする
0604:         //-------------------------------------------------
0605:         //-------------------------------------------------
0606:         m_pd3dDevice->SetRenderTarget(0, m_pReductionSurf[1]);
0607:         m_pd3dDevice->SetDepthStencilSurface(NULL);
0608:         // ビューポートの変更
0609:         m_pReductionSurf[1]->GetDesc(&d3dsd);
0610:         viewport.Height = d3dsd.Width;
0611:         viewport.Width  = d3dsd.Height;
0612:         m_pd3dDevice->SetViewport(&viewport);
0613: 
0614:         if( m_pEffect != NULL ) {
0615:             //-------------------------------------------------
0616:             // シェーダの設定
0617:             //-------------------------------------------------
0618:             m_pEffect->SetTechnique( m_hTechnique );
0619:             m_pEffect->Begin( NULL, 0 );
0620:             m_pEffect->Pass( 2 );
0621: 
0622:             m_pEffect->SetFloat("MAP_WIDTH",  DIFFUSE_SIZE);
0623:             m_pEffect->SetFloat("MAP_HEIGHT", DIFFUSE_SIZE);
0624: 
0625:             //-------------------------------------------------
0626:             // フィルタリング
0627:             //-------------------------------------------------
0628:             TVERTEX Vertex1[4] = {
0629:                 //   x    y     z    tu tv
0630:                 {-1.0f, +1.0f, 0.1f,  0, 0},
0631:                 {+1.0f, +1.0f, 0.1f,  1, 0},
0632:                 {+1.0f, -1.0f, 0.1f,  1, 1},
0633:                 {-1.0f, -1.0f, 0.1f,  0, 1},
0634:             };
0635:             m_pd3dDevice->SetFVF( D3DFVF_XYZ | D3DFVF_TEX1 );
0636:             m_pEffect->SetTexture("ReductionMap", m_pReductionTex[0]);
0637:             m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN
0638:                             , 2, Vertex1, sizeof( TVERTEX ) );
0639: 
0640:             m_pEffect->End();
0641:         }
0642: 
0643:         //-------------------------------------------------
0644:         //-------------------------------------------------
0645:         // ラディアンスをテクスチャの対応する位置に張る
0646:         //-------------------------------------------------
0647:         //-------------------------------------------------
0648:         m_pd3dDevice->SetRenderTarget(0, m_pFinalSurf[itex]);
0649:         m_pd3dDevice->SetDepthStencilSurface(NULL);
0650:         // ビューポートの変更
0651:         m_pFinalSurf[itex]->GetDesc(&d3dsd);
0652:         viewport.Height = d3dsd.Width;
0653:         viewport.Width  = d3dsd.Height;
0654:         m_pd3dDevice->SetViewport(&viewport);
0655:         
0656:         // 最初は灰色で塗りつぶす
0657:         if(0==ix&&0==iy)m_pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET, 0x80808080, 1.0f, 0L);
0658: 
0659:         if( m_pEffect != NULL ) {
0660:             //-------------------------------------------------
0661:             // シェーダの設定
0662:             //-------------------------------------------------
0663:             m_pEffect->SetTechnique( m_hTechnique );
0664:             m_pEffect->Begin( NULL, 0 );
0665:             m_pEffect->Pass( 2 );
0666: 
0667:             m_pEffect->SetFloat("MAP_WIDTH",  8);
0668:             m_pEffect->SetFloat("MAP_HEIGHT", 8);
0669: 
0670:             //-------------------------------------------------
0671:             // フィルタリング
0672:             //-------------------------------------------------
0673:             float x =  2.0f*((float)ix/(float)MAP_SIZE) - 1.0f;
0674:             float y = -2.0f*((float)iy/(float)MAP_SIZE) + 1.0f;
0675:             TVERTEX Vertex1[4] = {
0676:                 //   x    y     z    tu tv
0677:                 {x,                      y,                     0.1f,  0, 0},
0678:                 {x+2.0f/(float)MAP_SIZE, y,                     0.1f,  1, 0},
0679:                 {x+2.0f/(float)MAP_SIZE, y-2.0f/(float)MAP_SIZE,0.1f,  1, 1},
0680:                 {x,                      y-2.0f/(float)MAP_SIZE,0.1f,  0, 1},
0681:             };
0682:             m_pd3dDevice->SetFVF( D3DFVF_XYZ | D3DFVF_TEX1 );
0683:             m_pEffect->SetTexture("ReductionMap", m_pReductionTex[1]);
0684:             m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN
0685:                             , 2, Vertex1, sizeof( TVERTEX ) );
0686: 
0687:             m_pEffect->End();
0688:         }
0689: 
0690:         
0691:         //-----------------------------------------------------
0692:         // レンダリングターゲットを元に戻す
0693:         //-----------------------------------------------------
0694:         m_pd3dDevice->SetRenderTarget(0, pOldBackBuffer);
0695:         m_pd3dDevice->SetRenderTarget(1, NULL);
0696:         m_pd3dDevice->SetDepthStencilSurface(pOldZBuffer);
0697:         m_pd3dDevice->SetViewport(&oldViewport);
0698:         pOldBackBuffer->Release();
0699:         pOldZBuffer->Release();
0700: 
0701:         m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
0702:         m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
0703: 
0704:         //---------------------------------------------------------
0705:         // 画面の表示
0706:         //---------------------------------------------------------
0707:         m_pd3dDevice->Clear(0L, NULL
0708:                         , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0709:                         , 0x00001020, 1.0f, 0L);
0710: 
0711: #if 1 // デバッグ用にテクスチャを表示する
0712:         {
0713:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0714:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0715:         m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0716:         m_pd3dDevice->SetVertexShader(NULL);
0717:         m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0718:         m_pd3dDevice->SetPixelShader(0);
0719:         float scale = 256.0f*2/3;
0720:         for(DWORD i=0; i<3; i++){
0721:             TVERTEX Vertex[4] = {
0722:                 // x  y  z rhw tu tv
0723:                 {    0,(i+0)*scale,0, 1, 0, 0,},
0724:                 {scale,(i+0)*scale,0, 1, 1, 0,},
0725:                 {scale,(i+1)*scale,0, 1, 1, 1,},
0726:                 {    0,(i+1)*scale,0, 1, 0, 1,},
0727:             };
0728:             if(0==i) m_pd3dDevice->SetTexture( 0, m_pFinalTex[itex] );
0729:             if(1==i) m_pd3dDevice->SetTexture( 0, m_pReductionTex[0] );
0730:             if(2==i) m_pd3dDevice->SetTexture( 0, m_pReductionTex[1] );
0731:             m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0732:         }
0733:         }
0734: #endif      
0735: 
0736:         D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
0737:         TCHAR szMsg[MAX_PATH] = TEXT("");
0738: 
0739:         sprintf( szMsg, TEXT("x:%4d\ny:%4d"), ix, iy);
0740:         m_pFont->DrawText( 2, (FLOAT)m_d3dsdBackBuffer.Height-40, fontColor, szMsg );
0741: 
0742:         m_pd3dDevice->EndScene();
0743:     }
0744: }
0745: 
0746: 
0747: //-------------------------------------------------------------
0748: // Name: FrameMove()
0749: // Desc: 毎フレーム呼ばれます。アニメの処理などを行います。
0750: //-------------------------------------------------------------
0751: HRESULT CMyD3DApplication::FrameMove()
0752: {
0753:     m_iCount++;
0754:     
0755:     if(m_iChangeState) {m_iState++;m_iCount=0;m_iChangeState=0;}
0756: 
0757:     switch(m_iState){
0758:     case 0:
0759:         m_iChangeState = this->FrameMoveCreateMap();
0760:         return S_OK;
0761:     case 1:
0762:         m_iChangeState = this->FrameMoveFinalGathering();
0763:         return S_OK;
0764:     default:
0765:         break;
0766:     }
0767: 
0768: 
0769:     // 入力データの更新
0770:     UpdateInput( &m_UserInput );
0771: 
0772:     //---------------------------------------------------------
0773:     // 入力に応じて座標系を更新する
0774:     //---------------------------------------------------------
0775:     // 回転
0776:     D3DXMATRIX matRotY;
0777:     D3DXMATRIX matRotX;
0778: 
0779:     if(!m_UserInput.bShift){
0780:         if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0781:             m_fWorldRotY += m_fElapsedTime;
0782:         else
0783:         if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0784:             m_fWorldRotY -= m_fElapsedTime;
0785: 
0786:         if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0787:             m_fWorldRotX += m_fElapsedTime;
0788:         else
0789:         if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0790:             m_fWorldRotX -= m_fElapsedTime;
0791:     }
0792: 
0793:     D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0794:     D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0795: 
0796:     D3DXMatrixMultiply( &m_mWorld, &matRotY, &matRotX );
0797:     
0798:     //---------------------------------------------------------
0799:     // ライト
0800:     //---------------------------------------------------------
0801:     if(m_UserInput.bShift){
0802:         if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0803:             m_fLightRotY += m_fElapsedTime;
0804:         else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0805:             m_fLightRotY -= m_fElapsedTime;
0806: 
0807:         if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0808:             m_fLightRotX += m_fElapsedTime;
0809:         else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0810:             m_fLightRotX -= m_fElapsedTime;
0811:     }
0812:     // ライトのベクトル
0813:     D3DXMatrixRotationX( &matRotX, m_fLightRotX );
0814:     D3DXMatrixRotationY( &matRotY, m_fLightRotY );
0815:     D3DXMatrixMultiply( &m_mLight, &matRotX, &matRotY );
0816: 
0817:     //---------------------------------------------------------
0818:     // ビュー行列の設定
0819:     //---------------------------------------------------------
0820:     // ズーム
0821:     if( m_UserInput.bZoomIn && !m_UserInput.bZoomOut )
0822:         m_fViewZoom += m_fElapsedTime;
0823:     else if( m_UserInput.bZoomOut && !m_UserInput.bZoomIn )
0824:         m_fViewZoom -= m_fElapsedTime;
0825: 
0826:     D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -m_fViewZoom );
0827:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.3f, 0.0f );
0828:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0829:     D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0830: 
0831:     //---------------------------------------------------------
0832:     // シェーダの変更
0833:     //---------------------------------------------------------
0834:     if( m_UserInput.bChangeShader ) m_Shader = (m_Shader + 1) % 3;
0835: 
0836:     return S_OK;
0837: }
0838: //-------------------------------------------------------------
0839: // Name: UpdateInput()
0840: // Desc: 入力データを更新する
0841: //-------------------------------------------------------------
0842: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0843: {
0844:     pUserInput->bRotateUp    = ( m_bActive && (GetAsyncKeyState( VK_UP )    & 0x8000) == 0x8000 );
0845:     pUserInput->bRotateDown  = ( m_bActive && (GetAsyncKeyState( VK_DOWN )  & 0x8000) == 0x8000 );
0846:     pUserInput->bRotateLeft  = ( m_bActive && (GetAsyncKeyState( VK_LEFT )  & 0x8000) == 0x8000 );
0847:     pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0848:     
0849:     pUserInput->bZoomIn      = ( m_bActive && (GetAsyncKeyState( 'Z'     )  & 0x8000) == 0x8000 );
0850:     pUserInput->bZoomOut     = ( m_bActive && (GetAsyncKeyState( 'X'      ) & 0x8000) == 0x8000 );
0851:     
0852:     pUserInput->bChangeShader= ( m_bActive && (GetAsyncKeyState( 'A'      ) & 0x8001) == 0x8001 );
0853: 
0854:     pUserInput->bShift = ((GetAsyncKeyState( VK_SHIFT )    & 0x8000) == 0x8000);
0855: }
0856: 
0857: 
0858: 
0859: //-------------------------------------------------------------
0860: static float P(int l, int m, float x)
0861: {
0862:     float pmm=1.0;
0863: 
0864:     if(0<m){
0865:         float somx2 = sqrtf((1.0f-x)*(1.0f+x));
0866:         float fact = 1.0;
0867:         for(int i=1; i<=m; i++){
0868:             pmm *= (-fact)*somx2;
0869:             fact += 2.0f;
0870:         }
0871:     }
0872:     if(l==m) return pmm;
0873:     
0874:     float pmmp1=x*(2.0f*m+1.0f) * pmm;
0875:     if(l==m+1) return pmmp1;
0876:     
0877:     float pll = 0.0;
0878:     
0879:     for(int ll=m+2; ll<=l; ll++){
0880:         pll = ((2.0f*ll-1.0f)*x*pmmp1-(ll+m-1.0f)*pmm) / (ll-m);
0881:         pmm = pmmp1;
0882:         pmmp1 = pll;
0883:     }
0884:     
0885:     return pll;
0886: }
0887: //-------------------------------------------------------------
0888: static float K(int l, int m)
0889: {
0890:     int i;
0891:     float lpm=1;
0892:     float lnm=1;
0893: 
0894:     if(m<0)m=-m;
0895: 
0896:     for(i=l-m;0<i;i--)lnm *= i;
0897:     for(i=l+m;0<i;i--)lpm *= i;
0898: 
0899:     return ((2*l+1)*lnm)/(4*D3DX_PI*lpm);
0900: //  return sqrt(((2*l+1)*lnm)/(4*D3DX_PI*lpm));
0901: }
0902: //-------------------------------------------------------------
0903: static float SphericalHarmonics(int l, int m, float theta, float phi)
0904: {
0905:     float ret = K(l,m);
0906: 
0907:     if(0<m){
0908:         ret *= 2.f * cosf( m*phi) * P(l,  m, cosf(theta));
0909: //      ret *= sqrt(2) * cos( m*phi) * P(l,  m, cos(theta));
0910:     }else if(m<0){
0911:         ret *= 2.f * sinf(-m*phi) * P(l, -m, cosf(theta));
0912: //      ret *= sqrt(2) * sin(-m*phi) * P(l, -m, cos(theta));
0913:     }else{
0914:         ret *= P(l, m, cosf(theta));
0915:     }
0916: 
0917:     return ret;
0918: }
0919: 
0920: //-------------------------------------------------------------
0921: // Name: Render()
0922: // Desc: 画面を描画する.
0923: //-------------------------------------------------------------
0924: HRESULT CMyD3DApplication::Render()
0925: {
0926:     switch(m_iState){
0927:     case 0:
0928:         this->RenderCreateMap();
0929:         return S_OK;
0930:     case 1:
0931:         this->RenderFinalGathering();
0932:         return S_OK;
0933:     default:
0934:         break;
0935:     }
0936: 
0937:     D3DXMATRIX m, mT, mR, mW, mView, mProj;
0938:     DWORD i;
0939:     D3DXVECTOR4 v;
0940:     D3DMATERIAL9 *pMtrl;
0941: 
0942:     // ライトの位置
0943:     m = m_mLight * m_mWorld;
0944:     D3DXVECTOR4 LightPos = D3DXVECTOR4(0.0f, 0.0f, 5.0f, 0.0f);
0945:     D3DXVec4Transform( &LightPos, &LightPos, &m );
0946:     D3DXVECTOR4 LightDir = D3DXVECTOR4(0.0f, 0.0f, 1.0f, 0.0f);
0947:     D3DXVec4Transform( &LightDir, &LightDir, &m_mLight );
0948:     
0949:     //---------------------------------------------------------
0950:     // 描画
0951:     //---------------------------------------------------------
0952:     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0953:     {
0954:         // フレームバッファのクリア
0955:         m_pd3dDevice->Clear(0L, NULL
0956:                         , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0957:                         , 0xff000000, 1.0f, 0L);
0958: 
0959:         if( m_pEffect != NULL ) 
0960:         {
0961:             //-------------------------------------------------
0962:             // シェーダの設定
0963:             //-------------------------------------------------
0964:             m_pEffect->SetTechnique( m_hTechnique );
0965:             m_pEffect->Begin( NULL, 0 );
0966:             m_pEffect->Pass( 3+m_Shader );
0967: 
0968:             //-------------------------------------------------
0969:             // シーンの描画
0970:             //-------------------------------------------------
0971:             // 変換行列
0972:             m = m_mWorld * m_mView * m_mProj;
0973:             m_pEffect->SetMatrix( m_hmWVP, &m );
0974:             
0975:             D3DXVECTOR4 vSH[TEX_MAX];
0976:             
0977:             float ref = 3.0f;
0978:             
0979:             float phi = atan2f(LightDir.z, LightDir.x);
0980:             float theta = acosf(LightDir.y);
0981: 
0982:             for(int l=0; l<=L_MAX; l++){
0983:                 for(int m=-l; m<=l; m++){
0984:                     int n = l*(l+1) + m;
0985:                     ((float*)&vSH[0])[n] = ref * SphericalHarmonics(l, m, theta, phi);
0986:                     // テクスチャの展開の補正のため、(2l-1)!! の補正をつける
0987:                     if(2==l){
0988:                         ((float*)&vSH[0])[n] *= 3;
0989:                     }
0990:                     if(3==l){
0991:                         ((float*)&vSH[0])[n] *= 15;
0992:                     }
0993:                 }
0994:             }
0995: 
0996:             m_pEffect->SetVectorArray("vSH", vSH, (L_MAX+1)*(L_MAX+1)/4);
0997: 
0998:             // PRT テクスチャの設定
0999:             for(int tex = 0; tex < TEX_MAX; tex++){
1000:                 char str[256];
1001:                 sprintf(str, "PrtTex%d", tex);
1002:                 m_pEffect->SetTexture(str, this->m_pFinalTex[tex] );
1003:             }
1004:             // 背景の描画
1005:             pMtrl = m_pMeshBg->m_pMaterials;
1006:             for( i=0; i<m_pMeshBg->m_dwNumMaterials; i++ ) {
1007:                 m_pEffect->SetTexture(m_htSrcTex, m_pMeshBg->m_pTextures[i] );
1008:                 m_pMeshBg->m_pLocalMesh->DrawSubset( i );   // 描画
1009:                 pMtrl++;
1010:             }
1011: 
1012:             m_pEffect->End();
1013:         }
1014: 
1015:         //---------------------------------------------------------
1016:         // ライトの位置の表示
1017:         //---------------------------------------------------------
1018:         {
1019:         m = m_mView * m_mProj;
1020:         v = LightPos;
1021:         v.w = 1;
1022:         D3DXVec4Transform( &v, &v, &m );
1023:         float x = (this->m_rcWindowClient.right-this->m_rcWindowClient.left)*( 0.5f*v.x/v.w+0.5f);
1024:         float y = (this->m_rcWindowClient.bottom-this->m_rcWindowClient.top)*(-0.5f*v.y/v.w+0.5f);
1025: 
1026:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
1027:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_DIFFUSE);
1028:         m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
1029:         m_pd3dDevice->SetVertexShader(NULL);
1030:         m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_DIFFUSE );
1031:         m_pd3dDevice->SetPixelShader(0);
1032: 
1033:         typedef struct {FLOAT p[4]; DWORD color;} LVERTEX;
1034:         for(DWORD i=0; i<2; i++){
1035:             LVERTEX Vertex[4] = {
1036:                 // x  y   z rhw tu tv
1037:                 {x-3,y-3, v.z/v.w, 1, 0xffffc0,},
1038:                 {x+3,y-3, v.z/v.w, 1, 0xffffc0,},
1039:                 {x+3,y+3, v.z/v.w, 1, 0xffffc0,},
1040:                 {x-3,y+3, v.z/v.w, 1, 0xffffc0,},
1041:             };
1042:             m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( LVERTEX ) );
1043:         }
1044:         }
1045: 
1046: 
1047:         // ヘルプの表示
1048:         RenderText();
1049: 
1050: #if 1 // デバッグ用にテクスチャを表示する
1051:         {
1052:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
1053:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
1054:         m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
1055:         m_pd3dDevice->SetVertexShader(NULL);
1056:         m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
1057:         m_pd3dDevice->SetPixelShader(0);
1058:         float scale = 96.0f;
1059:         for(DWORD i=0; i<2+TEX_MAX; i++){
1060:             TVERTEX Vertex[4] = {
1061:                 // x  y  z rhw tu tv
1062:                 {(i+0)*scale,    0,0, 1, 0, 0,},
1063:                 {(i+1)*scale,    0,0, 1, 1, 0,},
1064:                 {(i+1)*scale,scale,0, 1, 1, 1,},
1065:                 {(i+0)*scale,scale,0, 1, 0, 1,},
1066:             };
1067:             if(0==i) m_pd3dDevice->SetTexture( 0, m_pPosTex );
1068:             if(1==i) m_pd3dDevice->SetTexture( 0, m_pNormalTex );
1069:             if(2<=i) m_pd3dDevice->SetTexture( 0, m_pFinalTex[i-2] );
1070:             m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
1071:         }
1072:         }
1073: #endif      
1074: 
1075:         // 描画の終了
1076:         m_pd3dDevice->EndScene();
1077:     }
1078: 
1079:     return S_OK;
1080: }
1081: 
1082: 
1083: 
1084: 
1085: //-------------------------------------------------------------
1086: // Name: RenderText()
1087: // Desc: 状態やヘルプを画面に表示する
1088: //-------------------------------------------------------------
1089: HRESULT CMyD3DApplication::RenderText()
1090: {
1091:     D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
1092:     TCHAR szMsg[MAX_PATH] = TEXT("");
1093: 
1094:     FLOAT fNextLine = 40.0f; // 表示する高さ
1095: 
1096:     // 操作法やパラメータを表示する
1097:     fNextLine = (FLOAT) m_d3dsdBackBuffer.Height; 
1098: 
1099:     lstrcpy( szMsg, TEXT("Press 'F2' to configure display") );
1100:     fNextLine -= 20.0f;
1101:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
1102: 
1103:     lstrcpy( szMsg, TEXT("Press 'A' to change shader") );
1104:     fNextLine -= 20.0f;
1105:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
1106: 
1107:     lstrcpy( szMsg, m_strDeviceStats );
1108:     fNextLine -= 20.0f;
1109:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
1110:     lstrcpy( szMsg, m_strFrameStats );
1111:     fNextLine -= 20.0f;
1112:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
1113:     
1114:     return S_OK;
1115: }
1116: 
1117: 
1118: 
1119: 
1120: //-------------------------------------------------------------
1121: // Name: MsgProc()
1122: // Desc: WndProc をオーバーライドしたもの
1123: //-------------------------------------------------------------
1124: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg,
1125:                                  WPARAM wParam, LPARAM lParam )
1126: {
1127:     switch( msg )
1128:     {
1129:         case WM_PAINT:
1130:         {
1131:             if( m_bLoadingApp )
1132:             {
1133:                 // ロード中
1134:                 HDC hDC = GetDC( hWnd );
1135:                 TCHAR strMsg[MAX_PATH];
1136:                 wsprintf(strMsg, TEXT("Loading... Please wait"));
1137:                 RECT rct;
1138:                 GetClientRect( hWnd, &rct );
1139:                 DrawText( hDC, strMsg, -1, &rct
1140:                         , DT_CENTER|DT_VCENTER|DT_SINGLELINE );
1141:                 ReleaseDC( hWnd, hDC );
1142:             }
1143:             break;
1144:         }
1145: 
1146:     }
1147: 
1148:     return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
1149: }
1150: 
1151: 
1152: 
1153: 
1154: //-------------------------------------------------------------
1155: // Name: InvalidateDeviceObjects()
1156: // Desc: RestoreDeviceObjects() で作成したオブジェクトの開放
1157: //-------------------------------------------------------------
1158: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
1159: {
1160:     // レンダリングターゲット
1161:     SAFE_RELEASE(m_pMaskTex);
1162:     for(int i=0;i<REDUCTION_MAPS;i++){
1163:         SAFE_RELEASE(m_pReductionSurf[i]);
1164:         SAFE_RELEASE(m_pReductionTex[i]);
1165:     }
1166:     for(int j=0;j<TEX_MAX;j++){
1167:         SAFE_RELEASE(m_pFinalSurf[j]);
1168:         SAFE_RELEASE(m_pFinalTex[j]);
1169:     }
1170:     SAFE_RELEASE(m_pNormalLockSurf);
1171:     SAFE_RELEASE(m_pNormalLockTex);
1172:     SAFE_RELEASE(m_pNormalSurf);
1173:     SAFE_RELEASE(m_pNormalTex);
1174:     SAFE_RELEASE(m_pPosLockSurf);
1175:     SAFE_RELEASE(m_pPosLockTex);
1176:     SAFE_RELEASE(m_pPosSurf);
1177:     SAFE_RELEASE(m_pPosTex);
1178:     SAFE_RELEASE(m_pMapZ);
1179: 
1180:     m_pMeshBg->InvalidateDeviceObjects();
1181: 
1182:     m_pFont->InvalidateDeviceObjects(); // フォント
1183: 
1184:     // シェーダ
1185:     if( m_pEffect != NULL ) m_pEffect->OnLostDevice();
1186: 
1187:     return S_OK;
1188: }
1189: 
1190: 
1191: 
1192: 
1193: //-------------------------------------------------------------
1194: // Name: DeleteDeviceObjects()
1195: // Desc: InitDeviceObjects() で作成したオブジェクトを開放する
1196: //-------------------------------------------------------------
1197: HRESULT CMyD3DApplication::DeleteDeviceObjects()
1198: {
1199:     // シェーダ
1200:     SAFE_RELEASE( m_pEffect );
1201:     
1202:     // メッシュ
1203:     m_pMeshBg->Destroy();
1204: 
1205:     // フォント
1206:     m_pFont->DeleteDeviceObjects();
1207: 
1208:     return S_OK;
1209: }
1210: 
1211: 
1212: 
1213: 
1214: //-------------------------------------------------------------
1215: // Name: FinalCleanup()
1216: // Desc: 終了する直線に呼ばれる
1217: //-------------------------------------------------------------
1218: HRESULT CMyD3DApplication::FinalCleanup()
1219: {
1220:     SAFE_DELETE( m_pMeshBg ); // メッシュ
1221: 
1222:     SAFE_DELETE( m_pFont ); // フォント
1223: 
1224:     return S_OK;
1225: }
1226: 
1227: 
1228: 
1229: 
1230: