0001: //-------------------------------------------------------------
0002: // File: main.cpp
0003: //
0004: // Desc: Real-Time Global Illumination
0005: // Copyright (c) 2004 IMAGIRE Takashi. All rights reserved.
0006: //-------------------------------------------------------------
0007: #define STRICT
0008: #include <windows.h>
0009: #include <time.h>
0010: #include <commctrl.h>
0011: #include <commdlg.h>
0012: #include <basetsd.h>
0013: #include <math.h>
0014: #include <stdio.h>
0015: #include <d3dx9.h>
0016: #include <dxerr9.h>
0017: #include <tchar.h>
0018: #include "DXUtil.h"
0019: #include "D3DEnumeration.h"
0020: #include "D3DSettings.h"
0021: #include "D3DApp.h"
0022: #include "D3DFont.h"
0023: #include "D3DFile.h"
0024: #include "D3DUtil.h"
0025: #include "resource.h"
0026: #include "main.h"
0027: 
0028: #define MAP_SIZE            128
0029: 
0030: #define frand() ((float)rand()/(float)RAND_MAX)
0031: 
0032: //-------------------------------------------------------------
0033: // Globals variables and definitions(グローバル変数と定義)
0034: //-------------------------------------------------------------
0035: CMyD3DApplication* g_pApp  = NULL;
0036: HINSTANCE          g_hInst = NULL;
0037: 
0038: typedef struct {
0039:     FLOAT       p[4];
0040:     FLOAT       tu, tv;
0041: } TVERTEX;
0042: 
0043: //-------------------------------------------------------------
0044: // Name: WinMain()
0045: // Desc: Entry point to the program. Initializes everything, and goes into a
0046: //       message-processing loop. Idle time is used to render the scene.
0047: //       (メイン関数)
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: Application constructor.   Paired with ~CMyD3DApplication()
0069: //       Member variables should be initialized to a known state here.  
0070: //       The application window has not yet been created and no Direct3D device 
0071: //       has been created, so any initialization that depends on a window or 
0072: //       Direct3D should be deferred to a later stage. 
0073: //       (アプリケーションのコンストラクタ)
0074: //-------------------------------------------------------------
0075: CMyD3DApplication::CMyD3DApplication()
0076: {
0077:     time_t t;
0078:     
0079:     time( &t );
0080:     srand( t );
0081: 
0082:     m_bPause = false;
0083: 
0084:     m_pos = D3DXVECTOR3(0,0,0);
0085:     m_vel = D3DXVECTOR3(frand(),frand(),frand());
0086:     m_rot = D3DXVECTOR3(0,0,0);
0087:     m_omega = D3DXVECTOR3( frand(), frand(), frand() );
0088: 
0089:     m_pMesh                     = new CD3DMesh();
0090:     m_pMeshBg                   = new CD3DMesh();
0091:     m_pMeshEnv                  = new CD3DMesh();
0092: 
0093:     m_pMapZ                     = NULL;
0094:     m_pParaboloidTex[0]         = NULL;
0095:     m_pParaboloidSurf[0]        = NULL;
0096:     m_pParaboloidTex[1]         = NULL;
0097:     m_pParaboloidSurf[1]        = NULL;
0098:     m_pTetrahedronTex[0]        = NULL;
0099:     m_pTetrahedronTex[1]        = NULL;
0100:     m_pTetrahedronTex[2]        = NULL;
0101:     m_pTetrahedronTex[3]        = NULL;
0102:     m_pTetrahedronSurf[0]       = NULL;
0103:     m_pTetrahedronSurf[1]       = NULL;
0104:     m_pTetrahedronSurf[2]       = NULL;
0105:     m_pTetrahedronSurf[3]       = NULL;
0106: 
0107:     m_pEffect                   = NULL;
0108:     m_hTechnique                = NULL;
0109:     m_hmWV                      = NULL;
0110:     m_hmWVP                     = NULL;
0111:     m_htSrcTex                  = NULL;
0112:     m_fWidth                    = NULL;
0113:     m_fHeight                   = NULL;
0114: 
0115:     m_fWorldRotX                = -0.0f;
0116:     m_fWorldRotY                = D3DX_PI*0.5f;
0117:     m_fViewZoom                 = 27.0f;
0118: 
0119:     m_dwCreationWidth           = 512;
0120:     m_dwCreationHeight          = 512;
0121:     m_strWindowTitle            = TEXT( "main" );
0122:     m_d3dEnumeration.AppUsesDepthBuffer   = TRUE;
0123:     m_bStartFullscreen          = false;
0124:     m_bShowCursorWhenFullscreen = false;
0125:  
0126:     m_pFont                     = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0127:     m_bLoadingApp               = TRUE;
0128: 
0129:     ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0130: }
0131: 
0132: 
0133: 
0134: 
0135: //-------------------------------------------------------------
0136: // Name: ~CMyD3DApplication()
0137: // Desc: Application destructor.  Paired with CMyD3DApplication()
0138: //       (デストラクタ)
0139: //-------------------------------------------------------------
0140: CMyD3DApplication::~CMyD3DApplication()
0141: {
0142: }
0143: 
0144: 
0145: 
0146: 
0147: //-------------------------------------------------------------
0148: // Name: OneTimeSceneInit()
0149: // Desc: Paired with FinalCleanup().
0150: //       The window has been created and the IDirect3D9 interface has been
0151: //       created, but the device has not been created yet.  Here you can
0152: //       perform application-related initialization and cleanup that does
0153: //       not depend on a device.
0154: //      (一度だけ行う初期化
0155: //      ウィンドウの初期化やIDirect3D9の初期化は終わってます。
0156: //      ただ、LPDIRECT3DDEVICE9 の初期化は終わっていません。)
0157: //-------------------------------------------------------------
0158: HRESULT CMyD3DApplication::OneTimeSceneInit()
0159: {
0160:     // Drawing loading status message until app finishes loading
0161:     // (ローディングメッセージを表示する)
0162:     SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0163: 
0164:     m_bLoadingApp = FALSE;
0165: 
0166:     return S_OK;
0167: }
0168: 
0169: 
0170: 
0171: 
0172: //-------------------------------------------------------------
0173: // Name: ConfirmDevice()
0174: // Desc: Called during device initialization, this code checks the device
0175: //       for some minimum set of capabilities
0176: //       (初期化の時に呼ばれます。必要な能力をチェックします。)
0177: //-------------------------------------------------------------
0178: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps,
0179:                      DWORD dwBehavior,    D3DFORMAT Format )
0180: {
0181:     UNREFERENCED_PARAMETER( Format );
0182:     UNREFERENCED_PARAMETER( dwBehavior );
0183:     UNREFERENCED_PARAMETER( pCaps );
0184:     
0185: 
0186:     // No fallback, so need ps2.0
0187:     // (ピクセルシェーダバージョンチェック)
0188:     if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
0189:         return E_FAIL;
0190: 
0191:     // If device doesn't support 1.1 vertex shaders in HW, switch to SWVP.
0192:     // 頂点シェーダバージョンが上位かソフトウェア頂点処理
0193:     if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,1)
0194:     &&  0==(dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING) )
0195:             return E_FAIL;
0196: 
0197:     return S_OK;
0198: }
0199: 
0200: 
0201: //-------------------------------------------------------------
0202: // Name: InitDeviceObjects()
0203: // Desc: Paired with DeleteDeviceObjects()
0204: //       The device has been created.  Resources that are not lost on
0205: //       Reset() can be created here -- resources in D3DPOOL_MANAGED,
0206: //       D3DPOOL_SCRATCH, or D3DPOOL_SYSTEMMEM.  Image surfaces created via
0207: //       CreateImageSurface are never lost and can be created here.  Vertex
0208: //       shaders and pixel shaders can also be created here as they are not
0209: //       lost on Reset().
0210: //      (デバイスが生成された後の初期化をします。
0211: //      フレームバッファフォーマットやデバイスの種類が変わった後に通過します。
0212: //      ここで確保したメモリはDeleteDeviceObjects()で開放します)
0213: //-------------------------------------------------------------
0214: HRESULT CMyD3DApplication::InitDeviceObjects()
0215: {
0216:     HRESULT hr;
0217: 
0218:     // Load objects (モデルの読み込み)
0219:     if(FAILED(hr=m_pMesh->Create( m_pd3dDevice, _T("t-pot.x"))))
0220:         return DXTRACE_ERR( "Load Model", hr );
0221:     m_pMesh->UseMeshMaterials(FALSE);// Not set textures when rendering(レンダリング時にテクスチャの設定をしない)
0222:         
0223:     if(FAILED(hr=m_pMeshBg->Create( m_pd3dDevice, _T("map.x"))))
0224:         return DXTRACE_ERR( "Load Model", hr );
0225:     m_pMeshBg->UseMeshMaterials(FALSE);// Not set textures when rendering(レンダリング時にテクスチャの設定をしない)
0226:         
0227:     if(FAILED(hr=m_pMeshEnv->Create( m_pd3dDevice, _T("room.x"))))
0228:         return DXTRACE_ERR( "Load Model", hr );
0229:     m_pMeshEnv->UseMeshMaterials(FALSE);// Not set textures when rendering(レンダリング時にテクスチャの設定をしない)
0230:         
0231:     // Create textures
0232:     // Create the effect(シェーダの読み込み)
0233:     LPD3DXBUFFER pErr;
0234:     if( FAILED( hr = D3DXCreateEffectFromFile(
0235:                 m_pd3dDevice, "hlsl.fx", NULL, NULL, 
0236:                 D3DXSHADER_DEBUG , NULL, &m_pEffect, &pErr ))){
0237:         MessageBox( NULL, (LPCTSTR)pErr->GetBufferPointer()
0238:                     , "ERROR", MB_OK);
0239:         return DXTRACE_ERR( "CreateEffectFromFile", hr );
0240:     }
0241:     m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
0242:     m_hmWV       = m_pEffect->GetParameterByName( NULL, "mWV" );
0243:     m_hmWVP      = m_pEffect->GetParameterByName( NULL, "mWVP" );
0244:     m_htSrcTex   = m_pEffect->GetParameterByName( NULL, "SrcTex" );
0245:     m_fWidth     = m_pEffect->GetParameterByName( NULL, "MAP_WIDTH" );
0246:     m_fHeight    = m_pEffect->GetParameterByName( NULL, "MAP_HEIGHT" );
0247: 
0248:     // Init the font(フォント)
0249:     m_pFont->InitDeviceObjects( m_pd3dDevice );
0250: 
0251:     return S_OK;
0252: }
0253: 
0254: //-------------------------------------------------------------
0255: // Name: RestoreDeviceObjects()
0256: // Desc: Paired with InvalidateDeviceObjects()
0257: //       The device exists, but may have just been Reset().  Resources in
0258: //       D3DPOOL_DEFAULT and any other device state that persists during
0259: //       rendering should be set here.  Render states, matrices, textures,
0260: //       etc., that don't change during rendering can be set once here to
0261: //       avoid redundant state setting during Render() or FrameMove().
0262: //       (画面のサイズが変更された時等に呼ばれます。
0263: //       確保したメモリはInvalidateDeviceObjects()で開放します。)
0264: //-------------------------------------------------------------
0265: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0266: {
0267:     DWORD i;
0268: 
0269:     m_bPause = false;
0270: 
0271:     // Restore meshes(メッシュ)
0272:     m_pMesh->RestoreDeviceObjects( m_pd3dDevice );
0273:     m_pMeshBg->RestoreDeviceObjects( m_pd3dDevice );
0274:     m_pMeshEnv->RestoreDeviceObjects( m_pd3dDevice );
0275: 
0276:     // Setup a material (質感の設定)
0277:     D3DMATERIAL9 mtrl;
0278:     D3DUtil_InitMaterial( mtrl, 1.0f, 0.0f, 0.0f );
0279:     m_pd3dDevice->SetMaterial( &mtrl );
0280: 
0281:     // Set miscellaneous render states(レンダリング環境の設定)
0282:     m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,   FALSE );
0283:     m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
0284:     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,        TRUE );
0285:     m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,        0x000F0F0F );
0286:     
0287:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
0288:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0289:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
0290:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
0291:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
0292:     m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
0293:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0294:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0295:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
0296:     m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
0297: 
0298:     // World transform to identity (ワールド行列)
0299:     D3DXMATRIX matIdentity;
0300:     D3DXMatrixIdentity( &m_mWorld );
0301: 
0302:     // Set up the view parameters for the camera(ビュー行列)
0303:     D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
0304:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0305:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0306:     D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0307: 
0308:     // Set the camera projection matrix(射影行列)
0309:     FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0310:     D3DXMatrixPerspectiveFovLH( &m_mProj, 0.47108996f, fAspect, 1.0f, 100.0f );
0311:     
0312: 
0313:     // Tetrahedron Matrix
0314:     D3DXVECTOR3 lookat[4];
0315:     D3DXVECTOR3 center;
0316:     D3DXMATRIX mRot;
0317:     float theta = 109.0f * D3DX_PI / 180.0f;
0318:     center = D3DXVECTOR3(0,0,0);
0319:     lookat[0] = D3DXVECTOR3(0,0,1);
0320:     lookat[1] = D3DXVECTOR3(sinf(theta)*cosf(0.0*D3DX_PI/3.0f),sinf(theta)*sinf(0.0*D3DX_PI/3.0f), cosf(theta));
0321:     lookat[2] = D3DXVECTOR3(sinf(theta)*cosf(2.0*D3DX_PI/3.0f),sinf(theta)*sinf(2.0*D3DX_PI/3.0f), cosf(theta));
0322:     lookat[3] = D3DXVECTOR3(sinf(theta)*cosf(4.0*D3DX_PI/3.0f),sinf(theta)*sinf(4.0*D3DX_PI/3.0f), cosf(theta));
0323:     
0324:     D3DXMatrixRotationY( &mRot, -acosf(-1.0f/3.0f)/2.0f );
0325:     D3DXVec3TransformCoord( &lookat[0], &lookat[0], &mRot);
0326:     D3DXVec3TransformCoord( &lookat[1], &lookat[1], &mRot);
0327:     D3DXVec3TransformCoord( &lookat[2], &lookat[2], &mRot);
0328:     D3DXVec3TransformCoord( &lookat[3], &lookat[3], &mRot);
0329:     for( i = 0; i < 4; i++ )
0330:     {
0331:         D3DXMatrixLookAtLH( &m_mViewTetrahedron[i], &center, &lookat[i], &lookat[(i+1)&3] );
0332:     }
0333:     D3DXMatrixPerspectiveFovLH( &m_mProjTetrahedron, 1.27f * theta, 1.0f, 0.1f, 100.0f );
0334: 
0335:     // Create the stencil buffer to be used with the paraboloid textures(深度マップの生成)
0336:     if (FAILED(m_pd3dDevice->CreateDepthStencilSurface(MAP_SIZE, MAP_SIZE, 
0337:         D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, TRUE, &m_pMapZ, NULL)))
0338:         return E_FAIL;
0339:     // Create tetrahedron rendering targets(テトラへドロンマップ)
0340:     for( i = 0; i < 4; i++ )
0341:     {
0342:         // Create paraboloid rendering targets(放物マップ)
0343:         if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0344:             D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pTetrahedronTex[i], NULL)))
0345:             return E_FAIL;
0346:         if (FAILED(m_pTetrahedronTex[i]->GetSurfaceLevel(0, &m_pTetrahedronSurf[i])))
0347:             return E_FAIL;
0348:     }
0349:     // Create paraboloid rendering targets(放物マップ)
0350:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0351:         D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pParaboloidTex[0], NULL)))
0352:         return E_FAIL;
0353:     if (FAILED(m_pParaboloidTex[0]->GetSurfaceLevel(0, &m_pParaboloidSurf[0])))
0354:         return E_FAIL;
0355:     if (FAILED(m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1, 
0356:         D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pParaboloidTex[1], NULL)))
0357:         return E_FAIL;
0358:     if (FAILED(m_pParaboloidTex[1]->GetSurfaceLevel(0, &m_pParaboloidSurf[1])))
0359:         return E_FAIL;
0360: 
0361:     InitQuad();
0362: 
0363:     // Restore effect object
0364:     m_pEffect->OnResetDevice();
0365: 
0366:     // Restore the font(フォント)
0367:     m_pFont->RestoreDeviceObjects();
0368: 
0369:     return S_OK;
0370: }
0371: 
0372: 
0373: //-------------------------------------------------------------
0374: // Name: FrameMove()
0375: // Desc: Called once per frame, the call is the entry point for animating
0376: //       the scene.
0377: //       (毎フレーム呼ばれます。アニメの処理などを行います。)
0378: //-------------------------------------------------------------
0379: HRESULT CMyD3DApplication::FrameMove()
0380: {
0381:     // Update user input state(入力データの更新)
0382:     UpdateInput( &m_UserInput );
0383: 
0384:     //---------------------------------------------------------
0385:     // Update the world state according to user input(入力に応じて座標系を更新する)
0386:     //---------------------------------------------------------
0387:     // Rotation(回転)
0388:     D3DXMATRIX matRotY;
0389:     D3DXMATRIX matRotX;
0390: 
0391:     if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0392:         m_fWorldRotY += m_fElapsedTime;
0393:     else
0394:     if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0395:         m_fWorldRotY -= m_fElapsedTime;
0396: 
0397:     if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0398:         m_fWorldRotX += m_fElapsedTime;
0399:     else
0400:     if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0401:         m_fWorldRotX -= m_fElapsedTime;
0402: 
0403:     D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0404:     D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0405: 
0406:     D3DXMatrixMultiply( &m_mWorld, &matRotY, &matRotX );
0407:     
0408:     //---------------------------------------------------------
0409:     // Update view matrix(ビュー行列の設定)
0410:     //---------------------------------------------------------
0411:     // Zoom(ズーム)
0412:     if( m_UserInput.bZoomIn && !m_UserInput.bZoomOut )
0413:         m_fViewZoom += m_fElapsedTime;
0414:     else if( m_UserInput.bZoomOut && !m_UserInput.bZoomIn )
0415:         m_fViewZoom -= m_fElapsedTime;
0416: 
0417:     D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -m_fViewZoom );
0418:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.3f, 0.0f );
0419:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0420:     D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );
0421: 
0422:     //---------------------------------------------------------
0423:     // Pause(ポーズ)
0424:     //---------------------------------------------------------
0425:     if( m_UserInput.bPause ) m_bPause = !m_bPause;
0426: 
0427:     //---------------------------------------------------------
0428:     // Move the ball (玉の移動)
0429:     //---------------------------------------------------------
0430:     if( !m_bPause )
0431:     {
0432:         D3DXVec3Normalize( &m_vel, &m_vel );
0433:         D3DXVec3Scale( &m_vel, &m_vel, 10 );
0434:         m_pos += m_vel * this->m_fElapsedTime;
0435:         m_rot += m_omega * this->m_fElapsedTime;
0436:         m_rot.x = (float)fmod(m_rot.x, 2.0f*D3DX_PI);
0437:         m_rot.y = (float)fmod(m_rot.y, 2.0f*D3DX_PI);
0438:         m_rot.z = (float)fmod(m_rot.z, 2.0f*D3DX_PI);
0439: 
0440:         float size = 5.0f - 1.0f;
0441: 
0442:         if( m_pos.x < -size )
0443:         {
0444:             m_pos.x = -size;
0445:             m_vel.x *= -1;
0446:         }
0447:         if( size < m_pos.x )
0448:         {
0449:             m_pos.x = size;
0450:             m_vel.x *= -1;
0451:         }
0452:         if( m_pos.y < -size )
0453:         {
0454:             m_pos.y = -size;
0455:             m_vel.y *= -1;
0456:         }
0457:         if( size < m_pos.y )
0458:         {
0459:             m_pos.y = size;
0460:             m_vel.y *= -1;
0461:         }
0462:         if( m_pos.z < -size )
0463:         {
0464:             m_pos.z = -size;
0465:             m_vel.z *= -1;
0466:         }
0467:         if( size < m_pos.z )
0468:         {
0469:             m_pos.z = size;
0470:             m_vel.z *= -1;
0471:         }
0472:     }
0473: 
0474:     return S_OK;
0475: }
0476: //-------------------------------------------------------------
0477: // Name: UpdateInput()
0478: // Desc: Update the user input.  Called once per frame 
0479: //       (入力データを更新する)
0480: //-------------------------------------------------------------
0481: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0482: {
0483:     pUserInput->bRotateUp    = ( m_bActive && (GetAsyncKeyState( VK_UP )    & 0x8000) == 0x8000 );
0484:     pUserInput->bRotateDown  = ( m_bActive && (GetAsyncKeyState( VK_DOWN )  & 0x8000) == 0x8000 );
0485:     pUserInput->bRotateLeft  = ( m_bActive && (GetAsyncKeyState( VK_LEFT )  & 0x8000) == 0x8000 );
0486:     pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0487:     
0488:     pUserInput->bZoomIn      = ( m_bActive && (GetAsyncKeyState( 'Z'     )  & 0x8000) == 0x8000 );
0489:     pUserInput->bZoomOut     = ( m_bActive && (GetAsyncKeyState( 'X'      ) & 0x8000) == 0x8000 );
0490:     
0491:     pUserInput->bChangeShader= ( m_bActive && (GetAsyncKeyState( 'A'      ) & 0x8001) == 0x8001 );
0492:     pUserInput->bPause       = ( m_bActive && (GetAsyncKeyState( 'P'      ) & 0x8001) == 0x8001 );
0493: }
0494: 
0495: 
0496: 
0497: 
0498: 
0499: //-------------------------------------------------------------
0500: // Name: RenderParaboloidMap()
0501: //-------------------------------------------------------------
0502: void CMyD3DApplication::RenderParaboloidMap()
0503: {
0504:     LPDIRECT3DSURFACE9 pOldBackBuffer, pOldZBuffer;
0505:     D3DVIEWPORT9 oldViewport;
0506:     D3DMATERIAL9 *pMtrl;
0507:     int i, j, pass;
0508:     D3DXMATRIX m, mT, mR, mWI, mView, mProj, mW, mWVP;
0509:     D3DXVECTOR3 vFrom;
0510:     D3DXVECTOR3 vLookat;
0511:     D3DXVECTOR3 vUpVec;
0512: 
0513:     D3DVIEWPORT9 viewport = {0, 0   // x,y(左上の座標)
0514:                     , 1, 1          // width, height(幅,高さ)
0515:                     , 0.0f,1.0f};   // near, far(前面、後面)
0516: 
0517:     //-------------------------------------------------
0518:     // Backup rendering target(レンダリングターゲットの保存)
0519:     //-------------------------------------------------
0520:     m_pd3dDevice->GetRenderTarget( 0, &pOldBackBuffer );
0521:     m_pd3dDevice->GetDepthStencilSurface( &pOldZBuffer );
0522:     m_pd3dDevice->GetViewport( &oldViewport );
0523:     
0524:     //-------------------------------------------------
0525:     // Create environment map(環境マップの作成)
0526:     //-------------------------------------------------
0527:     if( m_pEffect != NULL ) 
0528:     {
0529:         D3DXMatrixRotationX( &mWI, m_rot.x );
0530:         D3DXMatrixRotationY( &mR, m_rot.y );
0531:         mWI = mWI * mR;
0532:         D3DXMatrixRotationZ( &mR, m_rot.z );
0533:         mWI = mWI * mR;
0534:         D3DXMatrixTranslation( &mT, m_pos.x, m_pos.y, m_pos.z );
0535:         mWI = mWI * mT;
0536: 
0537:         for( pass = 0; pass < 4; pass++ )
0538:         {
0539:             mWVP = m_mWorld * m_mViewTetrahedron[pass] * m_mProjTetrahedron;
0540: 
0541:             m_pd3dDevice->SetRenderTarget( 0, m_pTetrahedronSurf[pass] );
0542:             m_pd3dDevice->SetDepthStencilSurface( m_pMapZ );
0543:             viewport.Width  = viewport.Height = MAP_SIZE;
0544:             m_pd3dDevice->SetViewport( &viewport );
0545: 
0546:             // Clear the scene
0547:             m_pd3dDevice->Clear(0L, NULL
0548:                 , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0549:                 , 0xff000000, 1.0f, 0L);
0550:             
0551:             //-------------------------------------------------
0552:             // Render ground(地形の描画)
0553:             //-------------------------------------------------
0554:             m_pEffect->SetTechnique( m_hTechnique );
0555:             m_pEffect->Begin( NULL, 0 );
0556:             // Set shader(シェーダの設定)
0557:             m_pEffect->Pass( 0 );
0558: 
0559:             // World+view+projection matrix(ローカル-射影行列)
0560:             D3DXMatrixTranslation( &mT, 0, -5, 0 );
0561:             m = mT * mWVP;
0562:             m_pEffect->SetMatrix( m_hmWVP, &m );
0563:             
0564:             // Set the texture and render(テクスチャを設定して描画)
0565:             pMtrl = m_pMeshBg->m_pMaterials;
0566:             for( i=0; i<m_pMeshBg->m_dwNumMaterials; i++ ) {
0567:                 m_pEffect->SetTexture(m_htSrcTex, m_pMeshBg->m_pTextures[i] );
0568:                 m_pMeshBg->m_pLocalMesh->DrawSubset( i );
0569:                 pMtrl++;
0570:             }
0571: 
0572:             // Render back sphere(天球の描画)
0573:             D3DXMatrixScaling ( &m, 10, 10, 10 );
0574:             m = m * mWVP;
0575:             m_pEffect->SetMatrix( m_hmWVP, &m );
0576:             
0577:             pMtrl = m_pMeshEnv->m_pMaterials;
0578:             for( i=0; i<m_pMeshEnv->m_dwNumMaterials; i++ ) {
0579:                 m_pEffect->SetTexture(m_htSrcTex, m_pMeshEnv->m_pTextures[i] );
0580:                 m_pMeshEnv->m_pLocalMesh->DrawSubset( i );
0581:                 pMtrl++;
0582:             }
0583: //          m_pd3dDevice->Clear(0L, NULL
0584: //          , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0585: //          , 0xffffff, 1.0f, 0L);
0586:         }
0587:         m_pEffect->End();
0588: 
0589:         // Set shader
0590:         m_pEffect->SetTechnique( m_hTechnique );
0591:         m_pEffect->Begin( NULL, 0 );
0592:         m_pEffect->Pass( 1 );
0593: 
0594:         for( i = 0; i < 2; i++ )
0595:         {
0596:             // Chenge rendering target
0597:             m_pd3dDevice->SetRenderTarget( 0, m_pParaboloidSurf[i] );
0598:             m_pd3dDevice->SetDepthStencilSurface( m_pMapZ );
0599:             viewport.Width  = viewport.Height = MAP_SIZE;
0600:             m_pd3dDevice->SetViewport( &viewport );
0601:             
0602:             // Clear the scene
0603:             m_pd3dDevice->Clear(0L, NULL
0604:                 , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0605:                 , 0xff000000, 1.0f, 0L);
0606:             
0607:             // Set matrixs(行列の設定)
0608:             switch(i)
0609:             {
0610:             case 0:
0611:                 // Front of view(前面)
0612:                 vLookat = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
0613:                 break;
0614:             case 1:
0615:                 // Back of view(後面)
0616:                 vLookat = D3DXVECTOR3( 0.0f, 0.0f, -1.0f );
0617:                 break;
0618:             }
0619:             vFrom   = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0620:             vUpVec  = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0621:             vUpVec -= vFrom;
0622:             D3DXMatrixLookAtLH( &mView, &vFrom, &vLookat, &vUpVec );
0623:             
0624: //m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME );
0625:             for( j = 0; j < 4; j++ )
0626:             {
0627:                 m = m_mViewTetrahedron[j] * m_mProjTetrahedron;
0628:                 D3DXMatrixInverse( &m, NULL, &m );
0629:                 m = m * mView;
0630:                 m_pEffect->SetMatrix( m_hmWV, &m );
0631: 
0632:                 m_pEffect->SetTexture(m_htSrcTex, m_pTetrahedronTex[j] );
0633: 
0634:                 RenderQuad();
0635:             }
0636: //m_pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID );
0637:         }
0638: 
0639:         m_pEffect->End();
0640:     }
0641: 
0642: 
0643:     //-----------------------------------------------------
0644:     // Restore render target
0645:     // (レンダリングターゲットを元に戻す)
0646:     //-----------------------------------------------------
0647:     m_pd3dDevice->SetRenderTarget(0, pOldBackBuffer);
0648:     m_pd3dDevice->SetRenderTarget(1, NULL);
0649:     m_pd3dDevice->SetDepthStencilSurface(pOldZBuffer);
0650:     m_pd3dDevice->SetViewport(&oldViewport);
0651:     pOldBackBuffer->Release();
0652:     pOldZBuffer->Release();
0653: 
0654: }
0655: //-------------------------------------------------------------
0656: // Name: Render()
0657: // Desc: Called once per frame, the call is the entry point for 3d
0658: //       rendering. This function sets up render states, clears the
0659: //       viewport, and renders the scene.
0660: //       (画面を描画する)
0661: //-------------------------------------------------------------
0662: HRESULT CMyD3DApplication::Render()
0663: {
0664:     D3DXMATRIX m, mT, mR, mW, mView, mProj;
0665:     DWORD i;
0666:     D3DXVECTOR4 v;
0667:     D3DMATERIAL9 *pMtrl;
0668: 
0669:     // Begin the scene(描画開始)
0670:     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0671:     {
0672:         //---------------------------------------------------------
0673:         // Create maps(テクスチャの生成)
0674:         //---------------------------------------------------------
0675:         RenderParaboloidMap();
0676: 
0677:         // Clear the render buffers(フレームバッファのクリア)
0678:         m_pd3dDevice->Clear(0L, NULL
0679:                         , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0680:                         , 0xff000000, 1.0f, 0L);
0681: 
0682:         if( m_pEffect != NULL ) 
0683:         {
0684:             //-------------------------------------------------
0685:             // Set effect(シェーダの設定)
0686:             //-------------------------------------------------
0687:             m_pEffect->SetTechnique( m_hTechnique );
0688:             m_pEffect->Begin( NULL, 0 );
0689: 
0690:             //-------------------------------------------------
0691:             // Render model (モデルの描画)
0692:             //-------------------------------------------------
0693:             m_pEffect->Pass( 2 );
0694: 
0695:             // Set matrixs(行列の設定)
0696:             D3DXMatrixRotationX( &mR, m_rot.x );
0697:             D3DXMatrixRotationY( &m, m_rot.y );
0698:             mR = mR * m;
0699:             D3DXMatrixRotationZ( &m, m_rot.z );
0700:             mR = mR * m;
0701:             D3DXMatrixTranslation( &mT, m_pos.x, m_pos.y, m_pos.z );
0702:             mW = mR * mT;
0703:             m = mW * m_mWorld;
0704:             m_pEffect->SetMatrix( "mW", &m );
0705:             m = m * m_mView;
0706:             m_pEffect->SetMatrix( m_hmWV, &m );
0707:             m = m * m_mProj;
0708:             m_pEffect->SetMatrix( m_hmWVP, &m );
0709: 
0710:             // View point in the local coordinate system(ローカルでの視点)
0711:             m = mW * m_mWorld * m_mView;
0712:             D3DXMatrixInverse( &m, NULL, &m );
0713:             v = D3DXVECTOR4( 0, 0, 0, 1 );
0714:             D3DXVec4Transform( &v, &v, &m);
0715:             m_pEffect->SetVector( "vEye", &v );
0716: 
0717:             // Set the texture and render
0718:             m_pEffect->SetTexture( "ParaboloidFrontTex", m_pParaboloidTex[0] );
0719:             m_pEffect->SetTexture( "ParaboloidBackTex",  m_pParaboloidTex[1] );
0720:             
0721:             m_pEffect->SetTexture( "DecaleTex",  m_pMesh->m_pTextures[0] );
0722:             m_pMesh->Render( m_pd3dDevice );
0723: 
0724:             //-------------------------------------------------
0725:             // Render ground(地形の描画)
0726:             //-------------------------------------------------
0727:             // Set shader(シェーダの設定)
0728:             m_pEffect->Pass( 0 );
0729: 
0730:             // World+view+projection matrix(ローカル-射影行列)
0731:             m = m_mWorld * m_mView * m_mProj;
0732:             D3DXMatrixTranslation( &mT, 0, -5, 0 );
0733:             m = mT * m;
0734:             m_pEffect->SetMatrix( m_hmWVP, &m );
0735:             
0736:             // Set the texture and render(テクスチャを設定して描画)
0737:             pMtrl = m_pMeshBg->m_pMaterials;
0738:             for( i=0; i<m_pMeshBg->m_dwNumMaterials; i++ ) {
0739:                 m_pEffect->SetTexture(m_htSrcTex, m_pMeshBg->m_pTextures[i] );
0740:                 m_pMeshBg->m_pLocalMesh->DrawSubset( i );
0741:                 pMtrl++;
0742:             }
0743: 
0744:             //-------------------------------------------------
0745:             // Render back sphere(天球の描画)
0746:             //-------------------------------------------------
0747:             // World+view+projection matrix(ローカル-射影行列)
0748:             D3DXMatrixScaling ( &m, 10, 10, 10 );
0749:             m = m * m_mWorld * m_mView * m_mProj;
0750:             m_pEffect->SetMatrix( m_hmWVP, &m );
0751:             
0752:             // Set the texture and render(テクスチャを設定して描画)
0753:             pMtrl = m_pMeshEnv->m_pMaterials;
0754:             for( i=0; i<m_pMeshBg->m_dwNumMaterials; i++ ) {
0755:                 m_pEffect->SetTexture(m_htSrcTex, m_pMeshEnv->m_pTextures[i] );
0756:                 m_pMeshEnv->m_pLocalMesh->DrawSubset( i );
0757:                 pMtrl++;
0758:             }
0759: 
0760:             m_pEffect->End();
0761:         }
0762: 
0763:         // Render stats and help text(ヘルプの表示)
0764:         RenderText();
0765: 
0766: #ifdef _DEBUG // Textures are displaying when debugging, (デバッグ用にテクスチャを表示する)
0767:         {
0768:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0769:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0770:         m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0771:         m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0772:         m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
0773:         m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0774:         float scale = 64.0f;
0775:         for(DWORD i=0; i<6; i++){
0776:             TVERTEX Vertex[4] = {
0777:                 //    x                             y         z rhw tu tv
0778:                 {(i+0)*scale, (FLOAT)m_d3dsdBackBuffer.Height-scale, 0, 1, 0, 0,},
0779:                 {(i+1)*scale, (FLOAT)m_d3dsdBackBuffer.Height-scale, 0, 1, 1, 0,},
0780:                 {(i+1)*scale, (FLOAT)m_d3dsdBackBuffer.Height-    0, 0, 1, 1, 1,},
0781:                 {(i+0)*scale, (FLOAT)m_d3dsdBackBuffer.Height-    0, 0, 1, 0, 1,},
0782:             };
0783:             if(0==i) m_pd3dDevice->SetTexture( 0, m_pTetrahedronTex[0] );
0784:             if(1==i) m_pd3dDevice->SetTexture( 0, m_pTetrahedronTex[1] );
0785:             if(2==i) m_pd3dDevice->SetTexture( 0, m_pTetrahedronTex[2] );
0786:             if(3==i) m_pd3dDevice->SetTexture( 0, m_pTetrahedronTex[3] );
0787:             if(4==i) m_pd3dDevice->SetTexture( 0, m_pParaboloidTex[0] );
0788:             if(5==i) m_pd3dDevice->SetTexture( 0, m_pParaboloidTex[1] );
0789: 
0790:             m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0791:         }
0792:         }
0793: #endif      
0794: 
0795:         // End the scene.(描画の終了)
0796:         m_pd3dDevice->EndScene();
0797:     }
0798: 
0799:     return S_OK;
0800: }
0801: 
0802: 
0803: 
0804: 
0805: //-------------------------------------------------------------
0806: // Name: RenderText()
0807: // Desc: Draw the help & statistics for running sample
0808: //       (状態やヘルプを画面に表示する)
0809: //-------------------------------------------------------------
0810: HRESULT CMyD3DApplication::RenderText()
0811: {
0812:     D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
0813:     TCHAR szMsg[MAX_PATH] = TEXT("");
0814:     FLOAT fNextLine;
0815: 
0816:     // Draw help
0817:     fNextLine = 0; 
0818: 
0819:     lstrcpy( szMsg, TEXT("Press 'F2' to configure display") );
0820:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0821:     fNextLine += 20.0f;
0822: 
0823:     lstrcpy( szMsg, TEXT("Press 'A' to change shader") );
0824:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0825:     fNextLine += 20.0f;
0826: 
0827:     // Output statistics
0828:     lstrcpy( szMsg, m_strDeviceStats );
0829:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0830:     fNextLine += 20.0f;
0831:     lstrcpy( szMsg, m_strFrameStats );
0832:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0833:     fNextLine += 20.0f;
0834:     
0835:     return S_OK;
0836: }
0837: 
0838: 
0839: 
0840: 
0841: //-------------------------------------------------------------
0842: // Name: MsgProc()
0843: // Desc: Overrrides the main WndProc, so the sample can do custom message
0844: //       handling (e.g. processing mouse, keyboard, or menu commands).
0845: //       (WndProc をオーバーライドしたもの)
0846: //-------------------------------------------------------------
0847: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg,
0848:                                  WPARAM wParam, LPARAM lParam )
0849: {
0850:     switch( msg )
0851:     {
0852:         case WM_PAINT:
0853:         {
0854:             if( m_bLoadingApp )
0855:             {
0856:                 // Loading message(ロード中)
0857:                 HDC hDC = GetDC( hWnd );
0858:                 TCHAR strMsg[MAX_PATH];
0859:                 wsprintf(strMsg, TEXT("Loading... Please wait"));
0860:                 RECT rct;
0861:                 GetClientRect( hWnd, &rct );
0862:                 DrawText( hDC, strMsg, -1, &rct
0863:                         , DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0864:                 ReleaseDC( hWnd, hDC );
0865:             }
0866:             break;
0867:         }
0868: 
0869:     }
0870: 
0871:     return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0872: }
0873: 
0874: 
0875: 
0876: 
0877: //-------------------------------------------------------------
0878: // Name: InvalidateDeviceObjects()
0879: // Desc: Invalidates device objects.  Paired with RestoreDeviceObjects()
0880: //       (RestoreDeviceObjects() で作成したオブジェクトの開放)
0881: //-------------------------------------------------------------
0882: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0883: {
0884:     DeleteQuad( );
0885: 
0886:     // font(フォント)
0887:     m_pFont->InvalidateDeviceObjects();
0888: 
0889:     SAFE_RELEASE(m_pTetrahedronSurf[3]);
0890:     SAFE_RELEASE(m_pTetrahedronSurf[2]);
0891:     SAFE_RELEASE(m_pTetrahedronSurf[1]);
0892:     SAFE_RELEASE(m_pTetrahedronSurf[0]);
0893:     SAFE_RELEASE(m_pTetrahedronTex[3]);
0894:     SAFE_RELEASE(m_pTetrahedronTex[2]);
0895:     SAFE_RELEASE(m_pTetrahedronTex[1]);
0896:     SAFE_RELEASE(m_pTetrahedronTex[0]);
0897: 
0898:     SAFE_RELEASE(m_pParaboloidSurf[1]);
0899:     SAFE_RELEASE(m_pParaboloidTex[1]);
0900:     SAFE_RELEASE(m_pParaboloidSurf[0]);
0901:     SAFE_RELEASE(m_pParaboloidTex[0]);
0902:     SAFE_RELEASE(m_pMapZ);
0903: 
0904:     // Models(モデル)
0905:     m_pMeshEnv->InvalidateDeviceObjects();
0906:     m_pMeshBg->InvalidateDeviceObjects();
0907:     m_pMesh->InvalidateDeviceObjects();
0908:     
0909:     // Shaders(シェーダ)
0910:     if( m_pEffect    != NULL ) m_pEffect   ->OnLostDevice();
0911: 
0912:     return S_OK;
0913: }
0914: 
0915: 
0916: 
0917: 
0918: //-------------------------------------------------------------
0919: // Name: DeleteDeviceObjects()
0920: // Desc: Paired with InitDeviceObjects()
0921: //       Called when the app is exiting, or the device is being changed,
0922: //       this function deletes any device dependent objects.  
0923: //       (InitDeviceObjects() で作成したオブジェクトを開放する)
0924: //-------------------------------------------------------------
0925: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0926: {
0927:     // font(フォント)
0928:     m_pFont->DeleteDeviceObjects();
0929: 
0930:     // Shaders(シェーダ)
0931:     SAFE_RELEASE( m_pEffect );
0932:     
0933:     // Models(モデル)
0934:     m_pMeshEnv->Destroy();
0935:     m_pMeshBg->Destroy();
0936:     m_pMesh->Destroy();
0937: 
0938:     return S_OK;
0939: }
0940: 
0941: 
0942: 
0943: 
0944: //-------------------------------------------------------------
0945: // Name: FinalCleanup()
0946: // Desc: Paired with OneTimeSceneInit()
0947: //       Called before the app exits, this function gives the app the chance
0948: //       to cleanup after itself.
0949: //       (終了する直前に呼ばれる)
0950: //-------------------------------------------------------------
0951: HRESULT CMyD3DApplication::FinalCleanup()
0952: {
0953:     // font(フォント)
0954:     SAFE_DELETE( m_pFont );
0955: 
0956:     // Models(モデル)
0957:     SAFE_DELETE( m_pMeshEnv );
0958:     SAFE_DELETE( m_pMeshBg );
0959:     SAFE_DELETE( m_pMesh );
0960: 
0961:     return S_OK;
0962: }
0963: 
0964: 
0965: 
0966: 
0967: