0001: //-----------------------------------------------------------------------------
0002: // File: main.cpp
0003: //
0004: // Desc: DirectX window application created by the DirectX AppWizard
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 "framework/DXUtil.h"
0017: #include "framework/D3DEnumeration.h"
0018: #include "framework/D3DSettings.h"
0019: #include "framework/D3DApp.h"
0020: #include "framework/D3DFont.h"
0021: #include "framework/D3DFile.h"
0022: #include "framework/D3DUtil.h"
0023: #include "resource.h"
0024: #include "main.h"
0025: 
0026: #define SHADOW_MAP_FORMAT D3DFMT_R32F
0027: //#define SHADOW_MAP_FORMAT D3DFMT_A8R8G8B8
0028: #define SHADOW_MAP_SIZE   2048
0029: 
0030: //-----------------------------------------------------------------------------
0031: // デバッグ用に表示するテクスチャ用の構造体
0032: //-----------------------------------------------------------------------------
0033: typedef struct {
0034:     FLOAT       p[4];
0035:     FLOAT       tu, tv;
0036: } TVERTEX;
0037: 
0038: //-----------------------------------------------------------------------------
0039: // Global access to the app (needed for the global WndProc())
0040: //-----------------------------------------------------------------------------
0041: CMyD3DApplication* g_pApp  = NULL;
0042: HINSTANCE          g_hInst = NULL;
0043: 
0044: 
0045: 
0046: 
0047: //-----------------------------------------------------------------------------
0048: // Name: WinMain()
0049: // Desc: Entry point to the program. Initializes everything, and goes into a
0050: //       message-processing loop. Idle time is used to render the scene.
0051: //-----------------------------------------------------------------------------
0052: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0053: {
0054:     CMyD3DApplication d3dApp;
0055: 
0056:     g_pApp  = &d3dApp;
0057:     g_hInst = hInst;
0058: 
0059:     InitCommonControls();
0060:     if( FAILED( d3dApp.Create( hInst ) ) )
0061:         return 0;
0062: 
0063:     return d3dApp.Run();
0064: }
0065: 
0066: 
0067: 
0068: 
0069: //-----------------------------------------------------------------------------
0070: // Name: CMyD3DApplication()
0071: // Desc: Application constructor.   Paired with ~CMyD3DApplication()
0072: //       Member variables should be initialized to a known state here.  
0073: //       The application window has not yet been created and no Direct3D device 
0074: //       has been created, so any initialization that depends on a window or 
0075: //       Direct3D should be deferred to a later stage. 
0076: //-----------------------------------------------------------------------------
0077: CMyD3DApplication::CMyD3DApplication()
0078: {
0079:     m_pMeshCar   = new CD3DMesh();
0080:     m_pMeshChess = new CD3DMesh();
0081: 
0082:     m_pShadowMap     = NULL;
0083:     m_pShadowMapSurf = NULL;
0084:     m_pShadowMapZ    = NULL;
0085: 
0086:     m_pFx = NULL;
0087:     m_hmWVP                     = NULL;
0088:     m_hmWLP                     = NULL;
0089:     m_hmWLPB                    = NULL;
0090:     m_hvCol                     = NULL;
0091:     m_hvDir                     = NULL;
0092: 
0093:     m_fWorldRotX                = -0.41271535f;
0094:     m_fWorldRotY                = 0.0f;
0095:     m_fViewZoom                 = 5.0f;
0096:     m_LighPos                   = D3DXVECTOR3( -5.0f, 5.0f,-2.0f );
0097: 
0098:     m_dwCreationWidth           = 500;
0099:     m_dwCreationHeight          = 375;
0100:     m_strWindowTitle            = TEXT( "main" );
0101:     m_d3dEnumeration.AppUsesDepthBuffer   = TRUE;
0102:     m_bStartFullscreen          = false;
0103:     m_bShowCursorWhenFullscreen = false;
0104: 
0105:     // Create a D3D font using d3dfont.cpp
0106:     m_pFont                     = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0107:     m_bLoadingApp               = TRUE;
0108: 
0109:     ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0110: }
0111: 
0112: 
0113: 
0114: 
0115: //-----------------------------------------------------------------------------
0116: // Name: ~CMyD3DApplication()
0117: // Desc: Application destructor.  Paired with CMyD3DApplication()
0118: //-----------------------------------------------------------------------------
0119: CMyD3DApplication::~CMyD3DApplication()
0120: {
0121: }
0122: 
0123: 
0124: 
0125: 
0126: //-----------------------------------------------------------------------------
0127: // Name: OneTimeSceneInit()
0128: // Desc: Paired with FinalCleanup().
0129: //       The window has been created and the IDirect3D9 interface has been
0130: //       created, but the device has not been created yet.  Here you can
0131: //       perform application-related initialization and cleanup that does
0132: //       not depend on a device.
0133: //-----------------------------------------------------------------------------
0134: HRESULT CMyD3DApplication::OneTimeSceneInit()
0135: {
0136:     // TODO: perform one time initialization
0137: 
0138:     // Drawing loading status message until app finishes loading
0139:     SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0140: 
0141:     m_bLoadingApp = FALSE;
0142: 
0143:     return S_OK;
0144: }
0145: 
0146: 
0147: 
0148: 
0149: 
0150: 
0151: 
0152: 
0153: 
0154: //-----------------------------------------------------------------------------
0155: // Name: ConfirmDevice()
0156: // Desc: Called during device initialization, this code checks the display device
0157: //       for some minimum set of capabilities
0158: //-----------------------------------------------------------------------------
0159: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
0160:                                           D3DFORMAT Format )
0161: {
0162:     UNREFERENCED_PARAMETER( Format );
0163:     UNREFERENCED_PARAMETER( dwBehavior );
0164:     UNREFERENCED_PARAMETER( pCaps );
0165:     
0166:     BOOL bCapsAcceptable;
0167: 
0168:     // TODO: Perform checks to see if these display caps are acceptable.
0169:     bCapsAcceptable = TRUE;
0170: 
0171:     // ピクセルシェーダバージョンチェック
0172:     if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
0173:         bCapsAcceptable = FALSE;
0174: 
0175:     // 頂点シェーダバージョンが上位かソフトウェア頂点処理
0176:     if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
0177:         if( (dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING ) == 0 )
0178:             bCapsAcceptable = FALSE;
0179: 
0180:     if( bCapsAcceptable )         
0181:         return S_OK;
0182:     else
0183:         return E_FAIL;
0184: }
0185: 
0186: 
0187: //-----------------------------------------------------------------------------
0188: // Name: LoadPixelShader()
0189: // Desc: Creates and loads pixel shader from file
0190: //-----------------------------------------------------------------------------
0191: HRESULT LoadPixelShader(LPDIRECT3DDEVICE9 pd3dDevice, TCHAR* fileName, LPDIRECT3DPIXELSHADER9* pShader)
0192: {
0193:     LPD3DXBUFFER pShaderBuf = NULL;
0194:     LPD3DXBUFFER pErrorBuf = NULL;
0195:     HRESULT hr;
0196: 
0197:     hr = D3DXAssembleShaderFromFile(fileName, NULL, NULL, 0, &pShaderBuf, &pErrorBuf);
0198:     if (SUCCEEDED(hr))
0199:     {
0200:        if (pShaderBuf) 
0201:            hr = pd3dDevice->CreatePixelShader((DWORD*)pShaderBuf->GetBufferPointer(), pShader);
0202:        else
0203:            hr = E_FAIL;
0204:     }
0205:     SAFE_RELEASE(pShaderBuf);
0206:     SAFE_RELEASE(pErrorBuf);
0207: 
0208:     return hr;
0209: }
0210: 
0211: //-----------------------------------------------------------------------------
0212: // Name: InitDeviceObjects()
0213: // Desc: Paired with DeleteDeviceObjects()
0214: //       The device has been created.  Resources that are not lost on
0215: //       Reset() can be created here -- resources in D3DPOOL_MANAGED,
0216: //       D3DPOOL_SCRATCH, or D3DPOOL_SYSTEMMEM.  Image surfaces created via
0217: //       CreateImageSurface are never lost and can be created here.  Vertex
0218: //       shaders and pixel shaders can also be created here as they are not
0219: //       lost on Reset().
0220: //-----------------------------------------------------------------------------
0221: HRESULT CMyD3DApplication::InitDeviceObjects()
0222: {
0223:     HRESULT hr;
0224: 
0225:     // 車の読み込み
0226:     if( FAILED( hr = m_pMeshCar->Create( m_pd3dDevice, _T("car.x") )))
0227:         return DXTRACE_ERR( "LoadCar", hr );
0228:     m_pMeshCar->UseMeshMaterials(FALSE);// レンダリング時にテクスチャの設定をしない
0229:     // 地面の読み込み
0230:     if( FAILED( hr = m_pMeshChess->Create( m_pd3dDevice, _T("chess.x") )))
0231:         return DXTRACE_ERR( "LoadChess", hr );
0232:     m_pMeshChess->UseMeshMaterials(FALSE);// レンダリング時にテクスチャの設定をしない
0233: 
0234:     // Init the font
0235:     m_pFont->InitDeviceObjects( m_pd3dDevice );
0236: 
0237:     // シェーダの読み込み
0238:     if( FAILED( D3DXCreateEffectFromFile( m_pd3dDevice, "shadowmap.fx", NULL, NULL, 
0239:                                         0, NULL, &m_pFx, NULL ) ) ) return E_FAIL;
0240:     m_hmWVP = m_pFx->GetParameterByName( NULL, "mWVP" );
0241:     m_hmWLP = m_pFx->GetParameterByName( NULL, "mWLP" );
0242:     m_hmWLPB= m_pFx->GetParameterByName( NULL, "mWLPB" );
0243:     m_hvCol = m_pFx->GetParameterByName( NULL, "vCol" );
0244:     m_hvDir = m_pFx->GetParameterByName( NULL, "vLightDir" );
0245: 
0246:     return S_OK;
0247: }
0248: 
0249: //-----------------------------------------------------------------------------
0250: // Name: RestoreDeviceObjects()
0251: // Desc: Paired with InvalidateDeviceObjects()
0252: //       The device exists, but may have just been Reset().  Resources in
0253: //       D3DPOOL_DEFAULT and any other device state that persists during
0254: //       rendering should be set here.  Render states, matrices, textures,
0255: //       etc., that don't change during rendering can be set once here to
0256: //       avoid redundant state setting during Render() or FrameMove().
0257: //-----------------------------------------------------------------------------
0258: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0259: {
0260:     // TODO: setup render states
0261: 
0262:     // Setup a material
0263:     D3DMATERIAL9 mtrl;
0264:     D3DUtil_InitMaterial( mtrl, 1.0f, 0.0f, 0.0f );
0265:     m_pd3dDevice->SetMaterial( &mtrl );
0266: 
0267:     // Set up the textures
0268:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
0269:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0270:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
0271:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
0272:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
0273:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
0274:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0275:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0276: 
0277:     // Set miscellaneous render states
0278:     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,   FALSE );
0279:     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
0280:     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,        TRUE );
0281:     m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,        0x000F0F0F );
0282: 
0283:     // Set the world matrix
0284:     D3DXMATRIX matIdentity;
0285:     D3DXMatrixIdentity( &m_mWorld );
0286: 
0287:     // Set up our view matrix. A view matrix can be defined given an eye point,
0288:     // a point to lookat, and a direction for which way is up. Here, we set the
0289:     // eye five units back along the z-axis and up three units, look at the
0290:     // origin, and define "up" to be in the y-direction.
0291:     D3DXMATRIX matView;
0292:     D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
0293:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0294:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0295:     D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0296: 
0297:     // Set the projection matrix
0298:     D3DXMATRIX matProj;
0299:     FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0300:     D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0301: 
0302:     // Restore the font
0303:     m_pFont->RestoreDeviceObjects();
0304: 
0305:     m_pMeshCar  ->RestoreDeviceObjects( m_pd3dDevice );
0306:     m_pMeshChess->RestoreDeviceObjects( m_pd3dDevice );
0307: 
0308:     // シャドウマップの生成
0309:     if (FAILED(m_pd3dDevice->CreateTexture(SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, 1, 
0310:         D3DUSAGE_RENDERTARGET, SHADOW_MAP_FORMAT, D3DPOOL_DEFAULT, &m_pShadowMap, NULL)))
0311:         return E_FAIL;
0312:     if (FAILED(m_pShadowMap->GetSurfaceLevel(0, &m_pShadowMapSurf)))
0313:         return E_FAIL;
0314:     if (FAILED(m_pd3dDevice->CreateDepthStencilSurface(SHADOW_MAP_SIZE, SHADOW_MAP_SIZE, 
0315:         D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, TRUE, &m_pShadowMapZ, NULL)))
0316:         return E_FAIL;
0317: 
0318:     if( m_pFx != NULL ) m_pFx->OnResetDevice();
0319: 
0320:     return S_OK;
0321: }
0322: 
0323: 
0324: 
0325: 
0326: //-----------------------------------------------------------------------------
0327: // Name: FrameMove()
0328: // Desc: Called once per frame, the call is the entry point for animating
0329: //       the scene.
0330: //-----------------------------------------------------------------------------
0331: HRESULT CMyD3DApplication::FrameMove()
0332: {
0333:     // TODO: update world
0334: 
0335:     // Update user input state
0336:     UpdateInput( &m_UserInput );
0337: 
0338:     // Update the world state according to user input
0339:     D3DXMATRIX matWorld;
0340:     D3DXMATRIX matRotY;
0341:     D3DXMATRIX matRotX;
0342: 
0343:     if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0344:         m_fWorldRotY += m_fElapsedTime;
0345:     else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0346:         m_fWorldRotY -= m_fElapsedTime;
0347: 
0348:     if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0349:         m_fWorldRotX += m_fElapsedTime;
0350:     else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0351:         m_fWorldRotX -= m_fElapsedTime;
0352: 
0353:     D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0354:     D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0355: 
0356:     D3DXMatrixMultiply( &m_mWorld, &matRotX, &matRotY );
0357:     
0358:     // --------------------------------------------------------------------------
0359:     // ビュー行列の設定
0360:     // --------------------------------------------------------------------------
0361:     if( m_UserInput.bZoomIn && !m_UserInput.bZoomOut )
0362:         m_fViewZoom += m_fElapsedTime;
0363:     else if( m_UserInput.bZoomOut && !m_UserInput.bZoomIn )
0364:         m_fViewZoom -= m_fElapsedTime;
0365: 
0366:     D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -m_fViewZoom );
0367:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0368:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0369:     D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0370: 
0371:     return S_OK;
0372: }
0373: //-----------------------------------------------------------------------------
0374: // Name: UpdateInput()
0375: // Desc: Update the user input.  Called once per frame 
0376: //-----------------------------------------------------------------------------
0377: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0378: {
0379:     pUserInput->bRotateUp    = ( m_bActive && (GetAsyncKeyState( VK_UP )    & 0x8000) == 0x8000 );
0380:     pUserInput->bRotateDown  = ( m_bActive && (GetAsyncKeyState( VK_DOWN )  & 0x8000) == 0x8000 );
0381:     pUserInput->bRotateLeft  = ( m_bActive && (GetAsyncKeyState( VK_LEFT )  & 0x8000) == 0x8000 );
0382:     pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0383:     
0384:     pUserInput->bZoomIn      = ( m_bActive && (GetAsyncKeyState( 'Z'     )  & 0x8000) == 0x8000 );
0385:     pUserInput->bZoomOut     = ( m_bActive && (GetAsyncKeyState( 'X'      ) & 0x8000) == 0x8000 );
0386: }
0387: 
0388: //-----------------------------------------------------------------------------
0389: // 各モデルの描画
0390: //-----------------------------------------------------------------------------
0391: VOID CMyD3DApplication::DrawModel( int pass )
0392: {
0393:     D3DXMATRIX m, mL, mS, mT, mR;
0394:     D3DXVECTOR3 vDir;
0395:     D3DXVECTOR4 v;
0396:     D3DMATERIAL9 *pMtrl;
0397:     DWORD i;
0398:     
0399:     //-------------------------------------------------------------------------
0400:     // 行列の生成
0401:     //-------------------------------------------------------------------------
0402:     D3DXMATRIX mVP = m_mWorld * m_mView * m_mProj;
0403:     
0404:     // 射影空間から、テクスチャーの空間に変換する
0405:     float fOffsetX = 0.5f + (0.5f / (float)SHADOW_MAP_SIZE);
0406:     float fOffsetY = 0.5f + (0.5f / (float)SHADOW_MAP_SIZE);
0407:     D3DXMATRIX mScaleBias(  0.5f,     0.0f,     0.0f,   0.0f,
0408:                             0.0f,    -0.5f,     0.0f,   0.0f,
0409:                             0.0f,     0.0f,     0.0f,   0.0f,
0410:                             fOffsetX, fOffsetY, 0.0f,   1.0f );
0411: 
0412:     //-------------------------------------------------------------------------
0413:     // 車
0414:     //-------------------------------------------------------------------------
0415:     // ワールド行列の生成
0416:     D3DXMatrixScaling( &mS, 0.05f, 0.05f, 0.05f );
0417:     D3DXMatrixTranslation( &mT, 1.0f, 0.0f ,0.0f );
0418: // m_fTime=1.3f;
0419:     D3DXMatrixRotationY( &mR, m_fTime );
0420:     mL = mS * mT * mR;
0421:     switch(pass){
0422:     case 0:// シャドウマップの作成
0423:         m = mL * m_mLightVP;
0424:         if( m_hmWLP != NULL ) m_pFx->SetMatrix( m_hmWLP, &m );
0425:         m_pMeshCar  ->Render( m_pd3dDevice );// 描画
0426:         break;
0427:     default:// シーンの描画
0428:         m = mL * mVP;
0429:         if( m_hmWVP != NULL ) m_pFx->SetMatrix( m_hmWVP, &m );
0430:         m = mL * m_mLightVP;
0431:         if( m_hmWLP != NULL ) m_pFx->SetMatrix( m_hmWLP, &m );
0432:         m = m * mScaleBias;
0433:         if( m_hmWLPB != NULL ) m_pFx->SetMatrix( m_hmWLPB, &m );
0434:         D3DXMatrixInverse( &m, NULL, &mL);
0435:         D3DXVec3Transform( &v, &m_LighPos, &m );
0436:         D3DXVec4Normalize( &v, &v );v.w = 0;
0437:         if( m_hvDir != NULL ) m_pFx->SetVector( m_hvDir, &v );
0438: 
0439:         pMtrl = m_pMeshCar->m_pMaterials;
0440:         for( i=0; i<m_pMeshCar->m_dwNumMaterials; i++ ) {
0441:             v.x = pMtrl->Diffuse.r;
0442:             v.y = pMtrl->Diffuse.g;
0443:             v.z = pMtrl->Diffuse.b;
0444:             v.w = pMtrl->Diffuse.a;
0445:             if( m_hvCol != NULL ) m_pFx->SetVector( m_hvCol, &v );
0446:             m_pMeshCar->m_pLocalMesh->DrawSubset( i );  // 描画
0447:             pMtrl++;
0448:         }
0449:         break;
0450:     }
0451: 
0452:     //-------------------------------------------------------------------------
0453:     // 地形
0454:     //-------------------------------------------------------------------------
0455:     // ワールド行列の生成
0456:     D3DXMatrixIdentity( &mL );
0457:     switch(pass){
0458:     case 0:// シャドウマップの作成
0459:         m = mL * m_mLightVP;
0460:         if( m_hmWLP != NULL ) m_pFx->SetMatrix( m_hmWLP, &m );
0461:         m_pMeshChess->Render( m_pd3dDevice );// 描画
0462:         break;
0463:     default:// シーンの描画
0464:         m = mL * mVP;
0465:         if( m_hmWVP != NULL ) m_pFx->SetMatrix( m_hmWVP, &m );
0466:         m = mL * m_mLightVP;
0467:         if( m_hmWLP != NULL ) m_pFx->SetMatrix( m_hmWLP, &m );
0468:         m = m * mScaleBias;
0469:         if( m_hmWLPB != NULL ) m_pFx->SetMatrix( m_hmWLPB, &m );
0470:         D3DXMatrixInverse( &m, NULL, &mL);
0471:         D3DXVec3Transform( &v, &m_LighPos, &m );
0472:         D3DXVec4Normalize( &v, &v );v.w = 0;
0473:         if( m_hvDir != NULL ) m_pFx->SetVector( m_hvDir, &v );
0474: 
0475:         pMtrl = m_pMeshChess->m_pMaterials;
0476:         for( i=0; i<m_pMeshChess->m_dwNumMaterials; i++ ) {
0477:             v.x = pMtrl->Diffuse.r;
0478:             v.y = pMtrl->Diffuse.g;
0479:             v.z = pMtrl->Diffuse.b;
0480:             v.w = pMtrl->Diffuse.a;
0481:             if( m_hvCol != NULL ) m_pFx->SetVector( m_hvCol, &v );
0482:             m_pMeshChess->m_pLocalMesh->DrawSubset( i );    // 描画
0483:             pMtrl++;
0484:         }
0485:         break;
0486:     }
0487: 
0488: }
0489: 
0490: 
0491: //-----------------------------------------------------------------------------
0492: // Name: Render()
0493: // Desc: Called once per frame, the call is the entry point for 3d
0494: //       rendering. This function sets up render states, clears the
0495: //       viewport, and renders the scene.
0496: //-----------------------------------------------------------------------------
0497: HRESULT CMyD3DApplication::Render()
0498: {
0499:     D3DXMATRIX mLP, mView, mProj;
0500:     LPDIRECT3DSURFACE9 pOldBackBuffer, pOldZBuffer;
0501:     D3DVIEWPORT9 oldViewport;
0502: 
0503:     //-------------------------------------------------------------------------
0504:     // 行列の作成
0505:     //-------------------------------------------------------------------------
0506:     // ライト方向から見た射影空間への行列
0507:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0508:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0509:     D3DXMatrixLookAtLH( &mView, &m_LighPos, &vLookatPt, &vUpVec );
0510:     D3DXMatrixPerspectiveFovLH( &mProj
0511:                             , 0.21f*D3DX_PI     // 視野角
0512:                             , 1.0f              // アスペクト比
0513:                             , 5.0f, 12.0f );    // near far
0514:     m_mLightVP = mView * mProj;
0515: 
0516:     //-------------------------------------------------------------------------
0517:     // 描画
0518:     //-------------------------------------------------------------------------
0519:     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0520:     {
0521:         if( m_pFx != NULL ) 
0522:         {
0523:             //-------------------------------------------------------------------------
0524:             // シェーダの設定
0525:             //-------------------------------------------------------------------------
0526:             D3DXHANDLE hTechnique = m_pFx->GetTechniqueByName( "TShader" );
0527:             m_pFx->SetTechnique( hTechnique );
0528:             m_pFx->Begin( NULL, 0 );
0529: 
0530:             //-------------------------------------------------------------------------
0531:             // レンダリングターゲットの保存
0532:             //--------------------------------------------------------------------------
0533:             m_pd3dDevice->GetRenderTarget(0, &pOldBackBuffer);
0534:             m_pd3dDevice->GetDepthStencilSurface(&pOldZBuffer);
0535:             m_pd3dDevice->GetViewport(&oldViewport);
0536: 
0537:             //-------------------------------------------------------------------------
0538:             // レンダリングターゲットの変更
0539:             //--------------------------------------------------------------------------
0540:             m_pd3dDevice->SetRenderTarget(0, m_pShadowMapSurf);
0541:             m_pd3dDevice->SetDepthStencilSurface(m_pShadowMapZ);
0542:             // ビューポートの変更    x y       width         height       minz maxz
0543:             D3DVIEWPORT9 viewport = {0,0, SHADOW_MAP_SIZE,SHADOW_MAP_SIZE,0.0f,1.0f};
0544:             m_pd3dDevice->SetViewport(&viewport);
0545: 
0546:             // シャドウマップのクリア
0547:             m_pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0548:                                 0xFFFFFFFF, 1.0f, 0L);
0549: 
0550:             //-----------------------------------------------------------------------------
0551:             // 1パス目:シャドウマップの作成
0552:             //-----------------------------------------------------------------------------
0553:             m_pFx->Pass( 0 );
0554:             DrawModel( 0 );
0555: 
0556:             //-------------------------------------------------------------------------
0557:             // レンダリングターゲットを元に戻す
0558:             //--------------------------------------------------------------------------
0559:             m_pd3dDevice->SetRenderTarget(0, pOldBackBuffer);
0560:             m_pd3dDevice->SetDepthStencilSurface(pOldZBuffer);
0561:             m_pd3dDevice->SetViewport(&oldViewport);
0562:             pOldBackBuffer->Release();
0563:             pOldZBuffer->Release();
0564: 
0565:             //-----------------------------------------------------------------------------
0566:             // 2パス目:シーンの描画
0567:             //-----------------------------------------------------------------------------
0568:             // バッファのクリア
0569:             m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0570:                                 0x00404080, 1.0f, 0L );
0571: 
0572:             //-------------------------------------------------------------------------
0573:             // 描画
0574:             //--------------------------------------------------------------------------
0575:             m_pFx->SetTexture("ShadowMap", m_pShadowMap);// テクスチャの設定
0576:             m_pFx->Pass( 1 );
0577:             DrawModel( 1 );
0578: 
0579:             m_pFx->End();
0580:         }
0581: 
0582:         // ヘルプの表示
0583:         RenderText();
0584: 
0585: #if 1 // デバッグ用にテクスチャを表示する
0586:         {
0587:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0588:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0589:         m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0590:         float scale = 128.0f;
0591:         TVERTEX Vertex[4] = {
0592:             // x  y  z rhw tu tv
0593:             {    0,    0,0, 1, 0, 0,},
0594:             {scale,    0,0, 1, 1, 0,},
0595:             {scale,scale,0, 1, 1, 1,},
0596:             {    0,scale,0, 1, 0, 1,},
0597:         };
0598:         m_pd3dDevice->SetTexture( 0, m_pShadowMap );
0599:         m_pd3dDevice->SetVertexShader(NULL);
0600:         m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0601:         m_pd3dDevice->SetPixelShader(0);
0602:         m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0603:         }
0604: #endif      
0605: 
0606:         // 描画の終了
0607:         m_pd3dDevice->EndScene();
0608:     }
0609: 
0610:     return S_OK;
0611: }
0612: 
0613: 
0614: 
0615: 
0616: //-----------------------------------------------------------------------------
0617: // Name: RenderText()
0618: // Desc: Renders stats and help text to the scene.
0619: //-----------------------------------------------------------------------------
0620: HRESULT CMyD3DApplication::RenderText()
0621: {
0622:     D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
0623:     TCHAR szMsg[MAX_PATH] = TEXT("");
0624: 
0625:     // Output display stats
0626:     FLOAT fNextLine = 40.0f; 
0627: 
0628:     // Output statistics & help
0629:     fNextLine = (FLOAT) m_d3dsdBackBuffer.Height; 
0630:     lstrcpy( szMsg, TEXT("Use arrow keys to rotate camera") );
0631:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0632:     lstrcpy( szMsg, TEXT("Press 'F2' to configure display") );
0633:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0634: 
0635:     lstrcpy( szMsg, m_strDeviceStats );
0636:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0637:     lstrcpy( szMsg, m_strFrameStats );
0638:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0639:     
0640:     return S_OK;
0641: }
0642: 
0643: 
0644: 
0645: 
0646: //-----------------------------------------------------------------------------
0647: // Name: MsgProc()
0648: // Desc: Overrrides the main WndProc, so the sample can do custom message
0649: //       handling (e.g. processing mouse, keyboard, or menu commands).
0650: //-----------------------------------------------------------------------------
0651: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg, WPARAM wParam,
0652:                                     LPARAM lParam )
0653: {
0654:     switch( msg )
0655:     {
0656:         case WM_PAINT:
0657:         {
0658:             if( m_bLoadingApp )
0659:             {
0660:                 // Draw on the window tell the user that the app is loading
0661:                 // TODO: change as needed
0662:                 HDC hDC = GetDC( hWnd );
0663:                 TCHAR strMsg[MAX_PATH];
0664:                 wsprintf( strMsg, TEXT("Loading... Please wait") );
0665:                 RECT rct;
0666:                 GetClientRect( hWnd, &rct );
0667:                 DrawText( hDC, strMsg, -1, &rct, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0668:                 ReleaseDC( hWnd, hDC );
0669:             }
0670:             break;
0671:         }
0672: 
0673:     }
0674: 
0675:     return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0676: }
0677: 
0678: 
0679: 
0680: 
0681: //-----------------------------------------------------------------------------
0682: // Name: InvalidateDeviceObjects()
0683: // Desc: Invalidates device objects.  Paired with RestoreDeviceObjects()
0684: //-----------------------------------------------------------------------------
0685: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0686: {
0687:     m_pMeshCar  ->InvalidateDeviceObjects();
0688:     m_pMeshChess->InvalidateDeviceObjects();
0689: 
0690:     // TODO: Cleanup any objects created in RestoreDeviceObjects()
0691:     m_pFont->InvalidateDeviceObjects();
0692: 
0693:     // シャドウマップ
0694:     SAFE_RELEASE(m_pShadowMapSurf);
0695:     SAFE_RELEASE(m_pShadowMap);
0696:     SAFE_RELEASE(m_pShadowMapZ);
0697: 
0698:     // シェーダ
0699:     if( m_pFx != NULL ) m_pFx->OnLostDevice();
0700: 
0701:     return S_OK;
0702: }
0703: 
0704: 
0705: 
0706: 
0707: //-----------------------------------------------------------------------------
0708: // Name: DeleteDeviceObjects()
0709: // Desc: Paired with InitDeviceObjects()
0710: //       Called when the app is exiting, or the device is being changed,
0711: //       this function deletes any device dependent objects.  
0712: //-----------------------------------------------------------------------------
0713: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0714: {
0715:     // シェーダ
0716:     SAFE_RELEASE( m_pFx );
0717:     m_pMeshCar  ->Destroy();
0718:     m_pMeshChess->Destroy();
0719: 
0720:     // TODO: Cleanup any objects created in InitDeviceObjects()
0721:     m_pFont->DeleteDeviceObjects();
0722: 
0723:     return S_OK;
0724: }
0725: 
0726: 
0727: 
0728: 
0729: //-----------------------------------------------------------------------------
0730: // Name: FinalCleanup()
0731: // Desc: Paired with OneTimeSceneInit()
0732: //       Called before the app exits, this function gives the app the chance
0733: //       to cleanup after itself.
0734: //-----------------------------------------------------------------------------
0735: HRESULT CMyD3DApplication::FinalCleanup()
0736: {
0737:     SAFE_DELETE( m_pMeshChess );
0738:     SAFE_DELETE( m_pMeshCar );
0739: 
0740:     // TODO: Perform any final cleanup needed
0741:     // Cleanup D3D font
0742:     SAFE_DELETE( m_pFont );
0743: 
0744:     return S_OK;
0745: }
0746: 
0747: 
0748: 
0749: 
0750: