0001: //-----------------------------------------------------------------------------
0002: // File: main.cpp
0003: //
0004: // Desc: HSV変換
0005: //-----------------------------------------------------------------------------
0006: #define STRICT
0007: #include <windows.h>
0008: #include <commctrl.h>
0009: #include <commdlg.h>
0010: #include <basetsd.h>
0011: #include <math.h>
0012: #include <stdio.h>
0013: #include <d3dx9.h>
0014: #include <dxerr9.h>
0015: #include <tchar.h>
0016: #include "DXUtil.h"
0017: #include "D3DEnumeration.h"
0018: #include "D3DSettings.h"
0019: #include "D3DApp.h"
0020: #include "D3DFont.h"
0021: #include "D3DFile.h"
0022: #include "D3DUtil.h"
0023: #include "resource.h"
0024: #include "main.h"
0025: 
0026: 
0027: 
0028: //-----------------------------------------------------------------------------
0029: // グローバル変数
0030: //-----------------------------------------------------------------------------
0031: CMyD3DApplication* g_pApp  = NULL;
0032: HINSTANCE          g_hInst = NULL;
0033: 
0034: 
0035: //-----------------------------------------------------------------------------
0036: // Name: WinMain()
0037: // Desc: メイン関数
0038: //-----------------------------------------------------------------------------
0039: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0040: {
0041:     CMyD3DApplication d3dApp;
0042: 
0043:     g_pApp  = &d3dApp;
0044:     g_hInst = hInst;
0045: 
0046:     InitCommonControls();
0047:     if( FAILED( d3dApp.Create( hInst ) ) )
0048:         return 0;
0049: 
0050:     return d3dApp.Run();
0051: }
0052: 
0053: 
0054: 
0055: 
0056: //-----------------------------------------------------------------------------
0057: // Name: CMyD3DApplication()
0058: // Desc: アプリケーションのコンストラクタ
0059: //-----------------------------------------------------------------------------
0060: CMyD3DApplication::CMyD3DApplication()
0061: {
0062:     m_pMesh                     = new CD3DMesh();
0063: 
0064:     m_pEffect = NULL;
0065: 
0066:     m_dwCreationWidth           = 500;
0067:     m_dwCreationHeight          = 375;
0068:     m_strWindowTitle            = TEXT( "main" );
0069:     m_d3dEnumeration.AppUsesDepthBuffer   = TRUE;
0070:     m_bStartFullscreen          = false;
0071:     m_bShowCursorWhenFullscreen = false;
0072: 
0073:     m_pFont                     = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0074:     m_bLoadingApp               = TRUE;
0075: 
0076:     ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0077:     m_fWorldRotX                = -0.437504f;
0078:     m_fWorldRotY                = 1.0f;
0079: 
0080:     m_fLightRotX                = 0.344792f;
0081:     m_fLightRotY                =-0.722427f;
0082: }
0083: 
0084: 
0085: 
0086: 
0087: //-----------------------------------------------------------------------------
0088: // Name: ~CMyD3DApplication()
0089: // Desc: デストラクタ
0090: //-----------------------------------------------------------------------------
0091: CMyD3DApplication::~CMyD3DApplication()
0092: {
0093: }
0094: 
0095: 
0096: 
0097: 
0098: //-------------------------------------------------------------
0099: // Name: OneTimeSceneInit()
0100: // Desc: 一度だけ行う初期化
0101: //      ウィンドウの初期化やIDirect3D9の初期化は終わってます。
0102: //      ただ、LPDIRECT3DDEVICE9 の初期化は終わっていません。
0103: //-------------------------------------------------------------
0104: HRESULT CMyD3DApplication::OneTimeSceneInit()
0105: {
0106:     // ローディングメッセージを表示する
0107:     SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0108: 
0109:     m_bLoadingApp = FALSE;
0110: 
0111:     return S_OK;
0112: }
0113: 
0114: 
0115: 
0116: 
0117: 
0118: 
0119: 
0120: 
0121: 
0122: 
0123: //-----------------------------------------------------------------------------
0124: // Name: ConfirmDevice()
0125: // Desc: 初期化の時に呼ばれます。必要な能力をチェックします。
0126: //-----------------------------------------------------------------------------
0127: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
0128:                                           D3DFORMAT Format )
0129: {
0130:     UNREFERENCED_PARAMETER( Format );
0131:     
0132: 
0133:     // ピクセルシェーダバージョンチェック
0134:     if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
0135:         return E_FAIL;
0136: 
0137:     // 頂点シェーダバージョンが上位かソフトウェア頂点処理
0138:     if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,1)
0139:     &&  0==(dwBehavior & D3DCREATE_SOFTWARE_VERTEXPROCESSING) )
0140:             return E_FAIL;
0141: 
0142:     return S_OK;
0143: }
0144: 
0145: 
0146: 
0147: //-----------------------------------------------------------------------------
0148: // Name: InitDeviceObjects()
0149: // Desc: デバイスが生成された後の初期化をします。
0150: //      フレームバッファフォーマットやデバイスの種類が変わった
0151: //      後に通過します。
0152: //      ここで確保したメモリはDeleteDeviceObjects()で開放します
0153: //-----------------------------------------------------------------------------
0154: HRESULT CMyD3DApplication::InitDeviceObjects()
0155: {
0156:     HRESULT hr;
0157: 
0158:     // ティーポットの読み込み
0159:     if(FAILED(hr=m_pMesh  ->Create( m_pd3dDevice, _T("t-pot.x"))))
0160:         return DXTRACE_ERR( "Load Object", hr );
0161:     m_pMesh->UseMeshMaterials(FALSE);
0162: 
0163:     // シェーダの読み込み
0164:     LPD3DXBUFFER pErr;
0165:     if( FAILED( hr = D3DXCreateEffectFromFile(
0166:                 m_pd3dDevice, "hlsl.fx", NULL, NULL, 
0167:                 D3DXSHADER_DEBUG , NULL, &m_pEffect, &pErr ))){
0168:         MessageBox( NULL, (LPCTSTR)pErr->GetBufferPointer()
0169:                     , "ERROR", MB_OK);
0170:         return DXTRACE_ERR( "CreateEffectFromFile", hr );
0171:     }
0172: 
0173:     // フォント
0174:     hr = m_pFont->InitDeviceObjects( m_pd3dDevice );
0175:     if( FAILED( hr ) )
0176:         return DXTRACE_ERR( "m_pFont->InitDeviceObjects", hr );
0177: 
0178:     return S_OK;
0179: }
0180: 
0181: 
0182: 
0183: 
0184: //-----------------------------------------------------------------------------
0185: // Name: RestoreDeviceObjects()
0186: // Desc: 画面のサイズが変更された時等に呼ばれます。
0187: //      確保したメモリはInvalidateDeviceObjects()で開放します。
0188: //-----------------------------------------------------------------------------
0189: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0190: {
0191:     // シェーダ
0192:     m_pEffect->OnResetDevice();
0193: 
0194:     // メッシュ
0195:     m_pMesh->RestoreDeviceObjects( m_pd3dDevice );
0196: 
0197:     // レンダリング状態の設定
0198:     m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,        TRUE );
0199:     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
0200: 
0201:     // ワールド行列
0202:     D3DXMATRIX matIdentity;
0203:     D3DXMatrixIdentity( &matIdentity );
0204:     m_pd3dDevice->SetTransform( D3DTS_WORLD,  &matIdentity );
0205: 
0206:     // ビュー行列
0207:     D3DXMATRIX matView;
0208:     D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -4.0f );
0209:     D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
0210:     D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0211:     D3DXMatrixLookAtLH( &m_mV, &vFromPt, &vLookatPt, &vUpVec );
0212: 
0213:     // 射影行列
0214:     D3DXMATRIX matProj;
0215:     FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
0216:     D3DXMatrixPerspectiveFovLH( &m_mP, D3DX_PI/4, fAspect, 1.0f, 100.0f );
0217: 
0218:     // フォント
0219:     m_pFont->RestoreDeviceObjects();
0220: 
0221:     return S_OK;
0222: }
0223: 
0224: 
0225: 
0226: 
0227: //-----------------------------------------------------------------------------
0228: // Name: FrameMove()
0229: // Desc: 毎フレーム呼ばれます。アニメの処理などを行います。
0230: //-----------------------------------------------------------------------------
0231: HRESULT CMyD3DApplication::FrameMove()
0232: {
0233:     // 入力データの更新
0234:     UpdateInput( &m_UserInput );
0235: 
0236:     //---------------------------------------------------------
0237:     // 入力に応じて座標系を更新する
0238:     //---------------------------------------------------------
0239:     D3DXMATRIX matRotY;
0240:     D3DXMATRIX matRotX;
0241:     
0242:     if(m_UserInput.bShift){
0243:         // ライトの回転
0244:         if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0245:             m_fLightRotY += m_fElapsedTime;
0246:         else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0247:             m_fLightRotY -= m_fElapsedTime;
0248: 
0249:         if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0250:             m_fLightRotX += m_fElapsedTime;
0251:         else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0252:             m_fLightRotX -= m_fElapsedTime;
0253:     }else{
0254:         // オブジェクトの回転
0255:         if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
0256:             m_fWorldRotY += m_fElapsedTime;
0257:         else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
0258:             m_fWorldRotY -= m_fElapsedTime;
0259: 
0260:         if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
0261:             m_fWorldRotX += m_fElapsedTime;
0262:         else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
0263:             m_fWorldRotX -= m_fElapsedTime;
0264:     }
0265: 
0266:     // 行列の作成
0267:     D3DXMatrixRotationX( &matRotX, m_fLightRotX );
0268:     D3DXMatrixRotationY( &matRotY, m_fLightRotY );
0269:     D3DXMatrixMultiply( &m_mLight, &matRotY, &matRotX );
0270: 
0271:     D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
0272:     D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
0273:     D3DXMatrixMultiply( &m_mW, &matRotY, &matRotX );
0274: 
0275:     m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_mW );
0276: 
0277:     return S_OK;
0278: }
0279: 
0280: 
0281: 
0282: 
0283: //-----------------------------------------------------------------------------
0284: // Name: UpdateInput()
0285: // Desc: 入力データを更新する
0286: //-----------------------------------------------------------------------------
0287: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0288: {
0289:     pUserInput->bRotateUp    = ( m_bActive && (GetAsyncKeyState( VK_UP )    & 0x8000) == 0x8000 );
0290:     pUserInput->bRotateDown  = ( m_bActive && (GetAsyncKeyState( VK_DOWN )  & 0x8000) == 0x8000 );
0291:     pUserInput->bRotateLeft  = ( m_bActive && (GetAsyncKeyState( VK_LEFT )  & 0x8000) == 0x8000 );
0292:     pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );
0293: 
0294:     pUserInput->bShift = ((GetAsyncKeyState( VK_SHIFT )    & 0x8000) == 0x8000);
0295: }
0296: 
0297: 
0298: 
0299: 
0300: //-----------------------------------------------------------------------------
0301: // Name: Render()
0302: // Desc: 画面を描画する.
0303: //-----------------------------------------------------------------------------
0304: HRESULT CMyD3DApplication::Render()
0305: {
0306:     D3DXMATRIX m, mX, mY;
0307:     D3DXVECTOR4 v;
0308:     DWORD i;
0309: 
0310:     D3DXVECTOR4 LightPos = D3DXVECTOR4(0.0f, 0.0f, -3.0f, 0.0f);
0311:     D3DXVec4Transform( &LightPos, &LightPos, &m_mLight );
0312: 
0313:     // レンダリングターゲットのクリア
0314:     m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0315:                          0x000000ff, 1.0f, 0L );
0316: 
0317:     //---------------------------------------------------------
0318:     // 描画
0319:     //---------------------------------------------------------
0320:     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0321:     {
0322:         if(m_pEffect){
0323:             m_pEffect->SetTechnique( "TShader" );
0324:             m_pEffect->Begin( NULL, 0 );
0325:             m_pEffect->Pass( 0 );
0326: 
0327:             // 変換行列の設定
0328:             D3DXMATRIX mWVP = m_mW * m_mV * m_mP;
0329:             m_pEffect->SetMatrix("mWVP", &mWVP);
0330:             
0331:             // ライトの向き
0332:             m = m_mW;
0333:             D3DXMatrixInverse( &m, NULL, &m );
0334:             D3DXVec4Transform( &v, &LightPos, &m );
0335:             m_pEffect->SetVector("LightPos", &v);
0336: 
0337:             float shift = fmod( 0.1f*this->m_fTime, 1.0f );
0338:             m_pEffect->SetFloat( "fShift", shift );
0339:             
0340:             // Render the teapot mesh
0341:             D3DMATERIAL9 *pMtrl = m_pMesh->m_pMaterials;
0342:             for( i=0; i<m_pMesh->m_dwNumMaterials; i++ ) {
0343:                 m_pEffect->SetTexture( "DecaleTex", m_pMesh->m_pTextures[i] );
0344:                 m_pMesh->m_pLocalMesh->DrawSubset( i );  // 描画
0345:                 pMtrl++;
0346:             }
0347: 
0348:             m_pEffect->End();
0349:         }
0350: 
0351:         {// ライトの位置の表示
0352:         m = m_mV * m_mP;
0353:         v = LightPos;
0354:         v.w = 1;
0355:         D3DXVec4Transform( &v, &v, &m );
0356:         float x = (this->m_rcWindowClient.right-this->m_rcWindowClient.left)*( 0.5f*v.x/v.w+0.5f);
0357:         float y = (this->m_rcWindowClient.bottom-this->m_rcWindowClient.top)*(-0.5f*v.y/v.w+0.5f);
0358: 
0359:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0360:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_DIFFUSE);
0361:         m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0362:         m_pd3dDevice->SetVertexShader(NULL);
0363:         m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_DIFFUSE );
0364:         m_pd3dDevice->SetPixelShader(0);
0365: 
0366:         typedef struct {FLOAT p[4]; DWORD color;} LVERTEX;
0367:         for(DWORD i=0; i<2; i++){
0368:             LVERTEX Vertex[4] = {
0369:                 // x  y   z rhw tu tv
0370:                 {x-3,y-3, v.z/v.w, 1, 0xffffc0,},
0371:                 {x+3,y-3, v.z/v.w, 1, 0xffffc0,},
0372:                 {x+3,y+3, v.z/v.w, 1, 0xffffc0,},
0373:                 {x-3,y+3, v.z/v.w, 1, 0xffffc0,},
0374:             };
0375:             m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( LVERTEX ) );
0376:         }
0377:         }
0378: 
0379: #if 0 // デバッグ用にテクスチャを表示する
0380:         {
0381:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0382:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0383:         m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0384:         m_pd3dDevice->SetVertexShader(NULL);
0385:         m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0386:         m_pd3dDevice->SetPixelShader(0);
0387:         float scale = 128.0f;
0388:         typedef struct {FLOAT p[4]; FLOAT tu, tv;} TVERTEX;
0389:         for(DWORD i=0; i<1; i++){
0390:             TVERTEX Vertex[4] = {
0391:                 // x  y  z rhw tu tv
0392:                 {    0,(i+0)*scale,0, 1, 0, 0,},
0393:                 {scale,(i+0)*scale,0, 1, 1, 0,},
0394:                 {scale,(i+1)*scale,0, 1, 1, 1,},
0395:                 {    0,(i+1)*scale,0, 1, 0, 1,},
0396:             };
0397: //          if(0==i) m_pd3dDevice->SetTexture( 0, m_pTex );
0398:             m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0399:         }
0400:         }
0401: #endif      
0402:         
0403:         // ヘルプの表示
0404:         RenderText();
0405: 
0406:         // 描画の終了
0407:         m_pd3dDevice->EndScene();
0408:     }
0409: 
0410:     return S_OK;
0411: }
0412: 
0413: 
0414: 
0415: 
0416: //-----------------------------------------------------------------------------
0417: // Name: RenderText()
0418: // Desc: 状態やヘルプを画面に表示する
0419: //-----------------------------------------------------------------------------
0420: HRESULT CMyD3DApplication::RenderText()
0421: {
0422:     D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
0423:     TCHAR szMsg[MAX_PATH] = TEXT("");
0424: 
0425:      FLOAT fNextLine = 40.0f; // 表示する高さ
0426: 
0427:     lstrcpy( szMsg, m_strDeviceStats );
0428:     fNextLine -= 20.0f;
0429:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0430: 
0431:     lstrcpy( szMsg, m_strFrameStats );
0432:     fNextLine -= 20.0f;
0433:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0434: 
0435:     // 操作法やパラメータを表示する
0436:     fNextLine = (FLOAT) m_d3dsdBackBuffer.Height; 
0437: 
0438:     wsprintf( szMsg, TEXT("Arrow keys: Up=%d Down=%d Left=%d Right=%d"), 
0439:               m_UserInput.bRotateUp, m_UserInput.bRotateDown, m_UserInput.bRotateLeft, m_UserInput.bRotateRight );
0440:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0441: 
0442:     lstrcpy( szMsg, TEXT("Use arrow keys to rotate object") );
0443:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0444: 
0445:     lstrcpy( szMsg, TEXT("Press 'F2' to configure display") );
0446:     fNextLine -= 20.0f; m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0447: 
0448:     return S_OK;
0449: }
0450: 
0451: 
0452: 
0453: 
0454: //-----------------------------------------------------------------------------
0455: // Name: MsgProc()
0456: // Desc: WndProc をオーバーライドしたもの
0457: //-----------------------------------------------------------------------------
0458: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg, WPARAM wParam,
0459:                                     LPARAM lParam )
0460: {
0461:     switch( msg )
0462:     {
0463:         case WM_PAINT:
0464:         {
0465:             if( m_bLoadingApp )
0466:             {
0467:                 // ロード中
0468:                 HDC hDC = GetDC( hWnd );
0469:                 TCHAR strMsg[MAX_PATH];
0470:                 wsprintf( strMsg, TEXT("Loading... Please wait") );
0471:                 RECT rct;
0472:                 GetClientRect( hWnd, &rct );
0473:                 DrawText( hDC, strMsg, -1, &rct, DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0474:                 ReleaseDC( hWnd, hDC );
0475:             }
0476:             break;
0477:         }
0478: 
0479:     }
0480: 
0481:     return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0482: }
0483: 
0484: 
0485: 
0486: 
0487: //-----------------------------------------------------------------------------
0488: // Name: InvalidateDeviceObjects()
0489: // Desc: RestoreDeviceObjects() で作成したオブジェクトの開放
0490: //-----------------------------------------------------------------------------
0491: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0492: {
0493:     if( m_pEffect ) m_pEffect->OnLostDevice();    // シェーダ
0494: 
0495:     if( m_pMesh ) m_pMesh  ->InvalidateDeviceObjects(); // メッシュ
0496: 
0497:     m_pFont->InvalidateDeviceObjects();    // フォント
0498: 
0499:     return S_OK;
0500: }
0501: 
0502: 
0503: 
0504: 
0505: //-----------------------------------------------------------------------------
0506: // Name: DeleteDeviceObjects()
0507: // Desc: InitDeviceObjects() で作成したオブジェクトを開放する
0508: //-----------------------------------------------------------------------------
0509: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0510: {
0511:     // メッシュ
0512:     m_pMesh  ->Destroy();
0513: 
0514:     // シェーダ
0515:     SAFE_RELEASE( m_pEffect );
0516: 
0517:     // フォント
0518:     m_pFont->DeleteDeviceObjects();
0519: 
0520:     return S_OK;
0521: }
0522: 
0523: 
0524: 
0525: 
0526: //-----------------------------------------------------------------------------
0527: // Name: FinalCleanup()
0528: // Desc: 終了する直前に呼ばれる
0529: //-----------------------------------------------------------------------------
0530: HRESULT CMyD3DApplication::FinalCleanup()
0531: {
0532:     SAFE_DELETE( m_pMesh ); // メッシュ
0533:     SAFE_DELETE( m_pFont ); // フォント
0534: 
0535:     return S_OK;
0536: }
0537: 
0538: 
0539: 
0540: 
0541: