0001: //-------------------------------------------------------------
0002: // File: main.cpp
0003: //
0004: // Desc: Silhouette Map Filtering
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: #define MAP_SIZE    5
0027: 
0028: // 長いから短縮形を作ってみた
0029: #define RS   m_pd3dDevice->SetRenderState
0030: #define TSS  m_pd3dDevice->SetTextureStageState
0031: #define SAMP m_pd3dDevice->SetSamplerState
0032: 
0033: 
0034: //-------------------------------------------------------------
0035: // 頂点の構造体
0036: //-------------------------------------------------------------
0037: typedef struct {
0038:     FLOAT       p[4];
0039:     FLOAT       tu, tv;
0040: } TVERTEX;
0041: 
0042: //-------------------------------------------------------------
0043: // グローバル変数
0044: //-------------------------------------------------------------
0045: CMyD3DApplication* g_pApp  = NULL;
0046: HINSTANCE          g_hInst = NULL;
0047: 
0048: 
0049: //-------------------------------------------------------------
0050: // Name: WinMain()
0051: // Desc: メイン関数
0052: //-------------------------------------------------------------
0053: INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
0054: {
0055:     CMyD3DApplication d3dApp;
0056: 
0057:     g_pApp  = &d3dApp;
0058:     g_hInst = hInst;
0059: 
0060:     InitCommonControls();
0061:     if( FAILED( d3dApp.Create( hInst ) ) )
0062:         return 0;
0063: 
0064:     return d3dApp.Run();
0065: }
0066: 
0067: 
0068: 
0069: 
0070: //-------------------------------------------------------------
0071: // Name: FillTex()
0072: // Desc: テクスチャの作成
0073: //-------------------------------------------------------------
0074: VOID WINAPI FillTex (D3DXVECTOR4* pOut, CONST D3DXVECTOR2* pTexCoord, 
0075: CONST D3DXVECTOR2* pTexelSize, LPVOID pData)
0076: {
0077:     FLOAT cx = 0.4f;
0078:     FLOAT cy = 0.4f;
0079:     FLOAT r  = 0.4f-0.0000001f;
0080:         
0081:     // 色成分を求める
0082:     FLOAT x = pTexCoord->x-0.5f*pTexelSize->x - cx;
0083:     FLOAT y = pTexCoord->y-0.5f*pTexelSize->y - cy;
0084:     FLOAT col = (x*x+y*y<r*r) ? 0.0 : 1.0;
0085:     
0086:     // シルエットマップを求める
0087:     FLOAT Dx = cx - pTexCoord->x;
0088:     FLOAT Dy = cy - pTexCoord->y;
0089:     FLOAT D0 = 2*r*r+2*Dx*Dy-Dx*Dx-Dy*Dy;// 判別式 y=+(x-px)+py
0090:     FLOAT D1 = 2*r*r-2*Dx*Dy-Dx*Dx-Dy*Dy;// 判別式 y=-(x-px)+py
0091: 
0092:     FLOAT U = 0.5f;
0093:     FLOAT V = 0.5f;
0094:     int   hit0=FALSE;
0095:     if(0<=D0){
0096:         FLOAT tp = 0.5f*((Dx+Dy)+sqrt(D0));
0097:         FLOAT tn = 0.5f*((Dx+Dy)-sqrt(D0));
0098:         if(-0.5f/MAP_SIZE <= tp && tp <= +0.5f/MAP_SIZE){
0099:             U=0.5f+MAP_SIZE*tp;
0100:             V=0.5f+MAP_SIZE*tp;
0101:             hit0=TRUE;
0102:         }else
0103:         if(-0.5f/MAP_SIZE <= tn && tn <= +0.5f/MAP_SIZE){
0104:             U=0.5f+MAP_SIZE*tn;
0105:             V=0.5f+MAP_SIZE*tn;
0106:             hit0=TRUE;
0107:         }
0108:     }
0109:     if(0<=D1){
0110:         FLOAT tp = 0.5f*((Dx-Dy)+sqrt(D1));
0111:         FLOAT tn = 0.5f*((Dx-Dy)-sqrt(D1));
0112:         if(-0.5f/MAP_SIZE <= tp && tp <= +0.5f/MAP_SIZE){
0113:             if(hit0){
0114:                 U=0.5f*(U + 0.5f+MAP_SIZE*tp);
0115:                 V=0.5f*(V + 0.5f-MAP_SIZE*tp);
0116:             }else{
0117:                 U=0.5f+MAP_SIZE*tp;
0118:                 V=0.5f-MAP_SIZE*tp;
0119:             }
0120:         }else
0121:         if(-0.5f/MAP_SIZE <= tn && tn <= +0.5f/MAP_SIZE){
0122:             if(hit0){
0123:                 U=0.5f*(U + 0.5f+MAP_SIZE*tn);
0124:                 V=0.5f*(V + 0.5f-MAP_SIZE*tn);
0125:             }else{
0126:                 U=0.5f+MAP_SIZE*tn;
0127:                 V=0.5f-MAP_SIZE*tn;
0128:             }
0129:         }
0130:     }
0131: //U = 0.5f;
0132: //V = 0.5f;
0133:     
0134:     // シルエットマップをアルファ成分に格納する
0135:     int iu = 16.0f*U;
0136:     int iv = 16.0f*V;
0137:     int alpha = iv+iu*16;
0138: 
0139:     pOut->x = pOut->y = pOut->z = col;
0140:     pOut->w = (1.0f/256.0f)*(FLOAT)alpha;
0141: //pOut->x=U;
0142: //pOut->y=V;
0143: //pOut->z=0;
0144: }
0145: 
0146: 
0147: 
0148: 
0149: //-------------------------------------------------------------
0150: // Name: CMyD3DApplication()
0151: // Desc: アプリケーションのコンストラクタ
0152: //-------------------------------------------------------------
0153: CMyD3DApplication::CMyD3DApplication()
0154: {
0155:     m_pTex                      = NULL;
0156: 
0157:     m_pEffect                   = NULL;
0158:     m_hTechnique                = NULL;
0159: 
0160:     m_dwCreationWidth           = 1024;
0161:     m_dwCreationHeight          = 378;
0162:     m_strWindowTitle            = TEXT( "main" );
0163:     m_d3dEnumeration.AppUsesDepthBuffer   = TRUE;
0164:     m_bStartFullscreen          = false;
0165:     m_bShowCursorWhenFullscreen = false;
0166: 
0167:     m_pFont                     = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
0168:     m_bLoadingApp               = TRUE;
0169: 
0170:     ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
0171: }
0172: 
0173: 
0174: 
0175: 
0176: //-------------------------------------------------------------
0177: // Name: ~CMyD3DApplication()
0178: // Desc: デストラクタ
0179: //-------------------------------------------------------------
0180: CMyD3DApplication::~CMyD3DApplication()
0181: {
0182: }
0183: 
0184: 
0185: 
0186: 
0187: //-------------------------------------------------------------
0188: // Name: OneTimeSceneInit()
0189: // Desc: 一度だけ行う初期化
0190: //      ウィンドウの初期化やIDirect3D9の初期化は終わってます。
0191: //      ただ、LPDIRECT3DDEVICE9 の初期化は終わっていません。
0192: //-------------------------------------------------------------
0193: HRESULT CMyD3DApplication::OneTimeSceneInit()
0194: {
0195:     // ローディングメッセージを表示する
0196:     SendMessage( m_hWnd, WM_PAINT, 0, 0 );
0197: 
0198:     m_bLoadingApp = FALSE;
0199: 
0200:     return S_OK;
0201: }
0202: 
0203: 
0204: 
0205: 
0206: //-------------------------------------------------------------
0207: // Name: ConfirmDevice()
0208: // Desc: 初期化の時に呼ばれます。必要な能力をチェックします。
0209: //-------------------------------------------------------------
0210: HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps,
0211:                      DWORD dwBehavior,    D3DFORMAT Format )
0212: {
0213:     UNREFERENCED_PARAMETER( Format );
0214:     UNREFERENCED_PARAMETER( dwBehavior );
0215:     UNREFERENCED_PARAMETER( pCaps );
0216:     
0217: 
0218:     // ピクセルシェーダバージョンチェック
0219:     if( pCaps->PixelShaderVersion < D3DPS_VERSION(2,0) )
0220:         return E_FAIL;
0221: 
0222:     return S_OK;
0223: }
0224: 
0225: 
0226: 
0227: 
0228: //-------------------------------------------------------------
0229: // Name: InitDeviceObjects()
0230: // Desc: デバイスが生成された後の初期化をします。
0231: //      フレームバッファフォーマットやデバイスの種類が変わった
0232: //      後に通過します。
0233: //      ここで確保したメモリはDeleteDeviceObjects()で開放します
0234: //-------------------------------------------------------------
0235: HRESULT CMyD3DApplication::InitDeviceObjects()
0236: {
0237:     HRESULT hr;
0238:     D3DXVECTOR4 offset;
0239: 
0240:     // シェーダの読み込み
0241:     LPD3DXBUFFER pErr;
0242:     if( FAILED( hr = D3DXCreateEffectFromFile(
0243:                 m_pd3dDevice, "hlsl.fx", NULL, NULL, 
0244:                 D3DXSHADER_DEBUG , NULL, &m_pEffect, &pErr ))){
0245:         MessageBox( NULL, (LPCTSTR)pErr->GetBufferPointer()
0246:                     , "ERROR", MB_OK);
0247:         return DXTRACE_ERR( "CreateEffectFromFile", hr );
0248:     }
0249:     m_hTechnique = m_pEffect->GetTechniqueByName( "TShader" );
0250:     
0251:     // フォント
0252:     m_pFont->InitDeviceObjects( m_pd3dDevice );
0253: 
0254:     return S_OK;
0255: }
0256: 
0257: //-------------------------------------------------------------
0258: // Name: RestoreDeviceObjects()
0259: // Desc: 画面のサイズが変更された時等に呼ばれます。
0260: //      確保したメモリはInvalidateDeviceObjects()で開放します。
0261: //-------------------------------------------------------------
0262: HRESULT CMyD3DApplication::RestoreDeviceObjects()
0263: {
0264:     HRESULT hr;
0265: 
0266:     if( FAILED(hr = m_pd3dDevice->CreateTexture(MAP_SIZE, MAP_SIZE, 1
0267:                           , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8
0268:                           , D3DPOOL_DEFAULT, &m_pTex, NULL)))
0269:         return hr;
0270:     if( FAILED(hr = D3DXFillTexture(m_pTex, FillTex, NULL)))
0271:         return hr;
0272:     m_pEffect->SetTexture( "tSrc", m_pTex );
0273: 
0274: 
0275:     // 質感の設定
0276:     D3DMATERIAL9 mtrl;
0277:     D3DUtil_InitMaterial( mtrl, 0.0f, 0.0f, 0.0f );
0278:     m_pd3dDevice->SetMaterial( &mtrl );
0279: 
0280:     // ライトの設定
0281:     D3DLIGHT9 light;
0282:     D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, -0.5f, -2.0f, 1.0f );
0283:     m_pd3dDevice->SetLight( 0, &light );
0284:     m_pd3dDevice->LightEnable( 0, FALSE );
0285:     m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
0286: 
0287:     // レンダリング状態の設定
0288:     RS( D3DRS_DITHERENABLE,   FALSE );
0289:     RS( D3DRS_SPECULARENABLE, FALSE );
0290:     RS( D3DRS_ZENABLE,        TRUE );
0291:     RS( D3DRS_AMBIENT,        0x000F0F0F );
0292:     
0293:     TSS( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
0294:     TSS( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0295:     TSS( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
0296:     TSS( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
0297:     TSS( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
0298: 
0299:     // フォント
0300:     m_pFont->RestoreDeviceObjects();
0301: 
0302:     m_pEffect->OnResetDevice();
0303: 
0304:     return S_OK;
0305: }
0306: 
0307: 
0308: 
0309: 
0310: //-------------------------------------------------------------
0311: // Name: FrameMove()
0312: // Desc: 毎フレーム呼ばれます。アニメの処理などを行います。
0313: //-------------------------------------------------------------
0314: HRESULT CMyD3DApplication::FrameMove()
0315: {
0316:     return S_OK;
0317: }
0318: //-------------------------------------------------------------
0319: // Name: UpdateInput()
0320: // Desc: 入力データを更新する
0321: //-------------------------------------------------------------
0322: void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
0323: {
0324: }
0325: 
0326: 
0327: //-------------------------------------------------------------
0328: // Name: Render()
0329: // Desc: 画面を描画する.
0330: //-------------------------------------------------------------
0331: HRESULT CMyD3DApplication::Render()
0332: {
0333:     //---------------------------------------------------------
0334:     // 描画
0335:     //---------------------------------------------------------
0336:     if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
0337:     {
0338:         m_pd3dDevice->Clear(0L, NULL
0339:                         , D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER
0340:                         , 0x202040, 1.0f, 0L);
0341: 
0342:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0343:         m_pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0344:         m_pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0345:         m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
0346:         m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
0347:         m_pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0348: 
0349:         for(DWORD loop = 0; loop < 3; loop++){
0350:             const float scale =256.0f;
0351:             typedef struct {FLOAT p[4]; FLOAT tu, tv;} TVERTEX;
0352:             FLOAT X = loop*(scale+64.0f)+64.0f;
0353:             FLOAT Y = 64.0f;
0354:             TVERTEX Vertex[4] = {
0355:                 //  x       y    z rhw tu tv
0356:                 {X      ,Y      ,0, 1, 0.0f, 0.0f,},
0357:                 {X+scale,Y      ,0, 1, 1.0f, 0.0f,},
0358:                 {X+scale,Y+scale,0, 1, 1.0f, 1.0f,},
0359:                 {X      ,Y+scale,0, 1, 0.0f, 1.0f,},
0360:             };
0361:             switch(loop){
0362:             case 0:
0363:                 m_pd3dDevice->SetTexture( 0, m_pTex );
0364:                 m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0365:                 m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
0366:                 m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0367:                 break;
0368:             case 1:
0369:                 m_pd3dDevice->SetTexture( 0, m_pTex );
0370:                 m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
0371:                 m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
0372:                 m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0373:                 break;
0374:             case 2:
0375:                 if(m_pEffect != NULL)
0376:                 {
0377:                     m_pEffect->SetTechnique( m_hTechnique );
0378:                     m_pEffect->Begin( NULL, 0 );
0379:                     m_pEffect->Pass( 0 );
0380:                     m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0381:                     m_pEffect->End();
0382:                 }
0383:                 break;
0384:             }
0385:         }
0386: 
0387: 
0388:         // ヘルプの表示
0389:         RenderText();
0390: 
0391:         // 描画の終了
0392:         m_pd3dDevice->EndScene();
0393:     }
0394: 
0395:     return S_OK;
0396: }
0397: 
0398: 
0399: 
0400: 
0401: //-------------------------------------------------------------
0402: // Name: RenderText()
0403: // Desc: 状態やヘルプを画面に表示する
0404: //-------------------------------------------------------------
0405: HRESULT CMyD3DApplication::RenderText()
0406: {
0407:     D3DCOLOR fontColor        = D3DCOLOR_ARGB(255,255,255,0);
0408:     TCHAR szMsg[MAX_PATH] = TEXT("");
0409: 
0410:     FLOAT fNextLine = 40.0f; // 表示する高さ
0411: 
0412:     lstrcpy( szMsg, TEXT("                          "
0413:                          "Linear Texture Filtering"
0414:                          "                                  "
0415:                          "Nearest-Point Sampling "
0416:                          "                                  "
0417:                          "Silhouette Map Filtering"
0418:                          ) );
0419:     fNextLine -= 20.0f;
0420:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0421: 
0422:     // 操作法やパラメータを表示する
0423:     fNextLine = (FLOAT) m_d3dsdBackBuffer.Height; 
0424:     lstrcpy( szMsg, m_strDeviceStats );
0425:     fNextLine -= 20.0f;
0426:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0427:     lstrcpy( szMsg, m_strFrameStats );
0428:     fNextLine -= 20.0f;
0429:     m_pFont->DrawText( 2, fNextLine, fontColor, szMsg );
0430:     
0431:     return S_OK;
0432: }
0433: 
0434: 
0435: 
0436: 
0437: //-------------------------------------------------------------
0438: // Name: MsgProc()
0439: // Desc: WndProc をオーバーライドしたもの
0440: //-------------------------------------------------------------
0441: LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT msg,
0442:                                  WPARAM wParam, LPARAM lParam )
0443: {
0444:     switch( msg )
0445:     {
0446:         case WM_PAINT:
0447:         {
0448:             if( m_bLoadingApp )
0449:             {
0450:                 // ロード中
0451:                 HDC hDC = GetDC( hWnd );
0452:                 TCHAR strMsg[MAX_PATH];
0453:                 wsprintf(strMsg, TEXT("Loading... Please wait"));
0454:                 RECT rct;
0455:                 GetClientRect( hWnd, &rct );
0456:                 DrawText( hDC, strMsg, -1, &rct
0457:                         , DT_CENTER|DT_VCENTER|DT_SINGLELINE );
0458:                 ReleaseDC( hWnd, hDC );
0459:             }
0460:             break;
0461:         }
0462: 
0463:     }
0464: 
0465:     return CD3DApplication::MsgProc( hWnd, msg, wParam, lParam );
0466: }
0467: 
0468: 
0469: 
0470: 
0471: //-------------------------------------------------------------
0472: // Name: InvalidateDeviceObjects()
0473: // Desc: RestoreDeviceObjects() で作成したオブジェクトの開放
0474: //-------------------------------------------------------------
0475: HRESULT CMyD3DApplication::InvalidateDeviceObjects()
0476: {
0477:     SAFE_RELEASE(m_pTex);
0478: 
0479:     m_pFont->InvalidateDeviceObjects(); // フォント
0480: 
0481:     // シェーダ
0482:     if( m_pEffect != NULL ) m_pEffect->OnLostDevice();
0483: 
0484:     return S_OK;
0485: }
0486: 
0487: 
0488: 
0489: 
0490: //-------------------------------------------------------------
0491: // Name: DeleteDeviceObjects()
0492: // Desc: InitDeviceObjects() で作成したオブジェクトを開放する
0493: //-------------------------------------------------------------
0494: HRESULT CMyD3DApplication::DeleteDeviceObjects()
0495: {
0496:     // シェーダ
0497:     SAFE_RELEASE( m_pEffect );
0498:     
0499:     // フォント
0500:     m_pFont->DeleteDeviceObjects();
0501: 
0502:     return S_OK;
0503: }
0504: 
0505: 
0506: 
0507: 
0508: //-------------------------------------------------------------
0509: // Name: FinalCleanup()
0510: // Desc: 終了する直線に呼ばれる
0511: //-------------------------------------------------------------
0512: HRESULT CMyD3DApplication::FinalCleanup()
0513: {
0514:     SAFE_DELETE( m_pFont ); // フォント
0515: 
0516:     return S_OK;
0517: }
0518: 
0519: 
0520: 
0521: 
0522: