0001: //--------------------------------------------------------------------------------------
0002: // File: main.cpp
0003: //
0004: // Starting point for new Direct3D applications
0005: // 新しいDirect3Dアプリケーションのための開始点
0006: //
0007: // Copyright (c) Microsoft Corporation. All rights reserved.
0008: //--------------------------------------------------------------------------------------
0009: #include "dxstdafx.h"
0010: #include "resource.h"
0011: #include "main_fx.h"
0012: 
0013: //#define DEBUG_VS   // Uncomment this line to debug vertex shaders 
0014:                      // 頂点シェーダをデバッグするにはこの行のコメントをはずせ
0015: //#define DEBUG_PS   // Uncomment this line to debug pixel shaders 
0016:                      // ピクセルシェーダをデバッグするにはこの行のコメントをはずせ
0017: 
0018: 
0019: //--------------------------------------------------------------------------------------
0020: // Vertex format
0021: //--------------------------------------------------------------------------------------
0022: struct VERTEX 
0023: {
0024:     D3DXVECTOR3 pos;
0025:     D3DXVECTOR2 tex;
0026: 
0027:     static const DWORD FVF;
0028: };
0029: const DWORD VERTEX::FVF = D3DFVF_XYZ | D3DFVF_TEX1;
0030: 
0031: //--------------------------------------------------------------------------------------
0032: // Global variables
0033: // グローバル変数
0034: //--------------------------------------------------------------------------------------
0035: IDirect3DDevice9*       g_pd3dDevice = NULL;
0036: ID3DXFont*              g_pFont = NULL;         // Font for drawing text
0037:                                                 // テキストを描画するためのテキスト
0038: ID3DXSprite*            g_pTextSprite = NULL;   // Sprite for batching draw text calls
0039:                                                 // 
0040: ID3DXEffect*            g_pEffect = NULL;       // D3DX effect interface
0041:                                                 // D3DX エフェクトのインターフェイス
0042: CModelViewerCamera      g_Camera;               // A model viewing camera
0043:                                                 // モデルを見ているカメラ
0044: bool                    g_bShowHelp = true;     // If true, it renders the UI control text
0045:                                                 // 真の時にはUI制御のテキストを描画する
0046: CDXUTDialog             g_HUD;                  // dialog for standard controls
0047:                                                 // 標準制御のダイアログ
0048: CDXUTDialog             g_SampleUI;             // dialog for sample specific controls
0049:                                                 // サンプル特有のコントロールのダイアログ
0050: 
0051: D3DVIEWPORT9            g_ViewportFB;
0052: 
0053: VERTEX                  g_Vertex[4];
0054: LPDIRECT3DTEXTURE9      g_pWangTexture = NULL;
0055: 
0056: DWORD                   g_MapSize = 32;
0057: LPDIRECT3DTEXTURE9      g_pRandTexture = NULL;
0058: 
0059: #if 1 // @@@
0060: LPDIRECT3DTEXTURE9      g_pLODLookupTexture = NULL;
0061: LPDIRECT3DTEXTURE9      g_pSpreadWangTexture = NULL;
0062: DWORD                   g_WangTextureSize;
0063: DWORD                   g_WangLODCount;
0064: #endif
0065: 
0066: //--------------------------------------------------------------------------------------
0067: // UI control IDs
0068: // UI を制御するためのID群
0069: //--------------------------------------------------------------------------------------
0070: #define IDC_TOGGLEFULLSCREEN    1
0071: #define IDC_TOGGLEREF           2
0072: #define IDC_CHANGEDEVICE        3
0073: #define IDC_CHANGE_LEVEL_STATIC 4
0074: #define IDC_CHANGE_LEVEL        5
0075: 
0076: 
0077: 
0078: //--------------------------------------------------------------------------------------
0079: // Forward declarations 
0080: // 前宣言
0081: //--------------------------------------------------------------------------------------
0082: bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed );
0083: void    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps );
0084: HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
0085: HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
0086: void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
0087: void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime );
0088: LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing );
0089: void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown  );
0090: void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl );
0091: void    CALLBACK OnLostDevice();
0092: void    CALLBACK OnDestroyDevice();
0093: 
0094: void    InitApp();
0095: HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh );
0096: void    RenderText();
0097: 
0098: 
0099: //--------------------------------------------------------------------------------------
0100: // Entry point to the program. Initializes everything and goes into a message processing 
0101: // loop. Idle time is used to render the scene.
0102: // プログラムの開始点。全てを初期化してメッセージ処理ループに入る。待機時間はシーンの描画
0103: // に使われる
0104: //--------------------------------------------------------------------------------------
0105: INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
0106: {
0107:     // Set the callback functions. These functions allow the sample framework to notify
0108:     // the application about device changes, user input, and windows messages.  The 
0109:     // callbacks are optional so you need only set callbacks for events you're interested 
0110:     // in. However, if you don't handle the device reset/lost callbacks then the sample 
0111:     // framework won't be able to reset your device since the application must first 
0112:     // release all device resources before resetting.  Likewise, if you don't handle the 
0113:     // device created/destroyed callbacks then the sample framework won't be able to 
0114:     // recreate your device resources.
0115:     DXUTSetCallbackDeviceCreated( OnCreateDevice );
0116:     DXUTSetCallbackDeviceReset( OnResetDevice );
0117:     DXUTSetCallbackDeviceLost( OnLostDevice );
0118:     DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
0119:     DXUTSetCallbackMsgProc( MsgProc );
0120:     DXUTSetCallbackKeyboard( KeyboardProc );
0121:     DXUTSetCallbackFrameRender( OnFrameRender );
0122:     DXUTSetCallbackFrameMove( OnFrameMove );
0123: 
0124:     // Show the cursor and clip it when in full screen
0125:     DXUTSetCursorSettings( true, true );
0126: 
0127:     InitApp();
0128: 
0129:     // Initialize the sample framework and create the desired Win32 window and Direct3D 
0130:     // device for the application. Calling each of these functions is optional, but they
0131:     // allow you to set several options which control the behavior of the framework.
0132:     DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
0133:     DXUTCreateWindow( L"main" );
0134:     DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );
0135: 
0136:     // Pass control to the sample framework for handling the message pump and 
0137:     // dispatching render calls. The sample framework will call your FrameMove 
0138:     // and FrameRender callback when there is idle time between handling window messages.
0139:     DXUTMainLoop();
0140: 
0141:     // Perform any application-level cleanup here. Direct3D device resources are released within the
0142:     // appropriate callback functions and therefore don't require any cleanup code here.
0143: 
0144:     return DXUTGetExitCode();
0145: }
0146: 
0147: 
0148: //--------------------------------------------------------------------------------------
0149: // Initialize the app 
0150: // アプリケーションの初期化
0151: //--------------------------------------------------------------------------------------
0152: void InitApp()
0153: {
0154:     g_pEffect = NULL;
0155: 
0156:     g_Vertex[0].pos = D3DXVECTOR3(+1,0,-1);
0157:     g_Vertex[1].pos = D3DXVECTOR3(-1,0,-1);
0158:     g_Vertex[2].pos = D3DXVECTOR3(+1,0,+1);
0159:     g_Vertex[3].pos = D3DXVECTOR3(-1,0,+1);
0160:     g_Vertex[0].tex = D3DXVECTOR2(1,1);
0161:     g_Vertex[1].tex = D3DXVECTOR2(0,1);
0162:     g_Vertex[2].tex = D3DXVECTOR2(1,0);
0163:     g_Vertex[3].tex = D3DXVECTOR2(0,0);
0164: 
0165:     // Initialize dialogs
0166:     // ダイアログの初期化
0167:     g_HUD.SetCallback( OnGUIEvent ); int iY = 10; 
0168:     g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 35, iY, 125, 22 );
0169:     g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 35, iY += 24, 125, 22 );
0170:     g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22 );
0171: 
0172:     g_SampleUI.SetCallback( OnGUIEvent ); iY = 10; 
0173: //    g_SampleUI.AddComboBox( 19, 35, iY += 24, 125, 22 );
0174: //    g_SampleUI.GetComboBox( 19 )->AddItem( L"Text1", NULL );
0175: //    g_SampleUI.GetComboBox( 19 )->AddItem( L"Text2", NULL );
0176: //    g_SampleUI.GetComboBox( 19 )->AddItem( L"Text3", NULL );
0177: //    g_SampleUI.GetComboBox( 19 )->AddItem( L"Text4", NULL );
0178: //    g_SampleUI.AddCheckBox( 21, L"Checkbox1", 35, iY += 24, 125, 22 );
0179: //    g_SampleUI.AddCheckBox( 11, L"Checkbox2", 35, iY += 24, 125, 22 );
0180: //    g_SampleUI.AddRadioButton( 12, 1, L"Radio1G1", 35, iY += 24, 125, 22 );
0181: //    g_SampleUI.AddRadioButton( 13, 1, L"Radio2G1", 35, iY += 24, 125, 22 );
0182: //    g_SampleUI.AddRadioButton( 14, 1, L"Radio3G1", 35, iY += 24, 125, 22 );
0183: //    g_SampleUI.GetRadioButton( 14 )->SetChecked( true ); 
0184: //    g_SampleUI.AddButton( 17, L"Button1", 35, iY += 24, 125, 22 );
0185: //    g_SampleUI.AddButton( 18, L"Button2", 35, iY += 24, 125, 22 );
0186: //    g_SampleUI.AddRadioButton( 15, 2, L"Radio1G2", 35, iY += 24, 125, 22 );
0187: //    g_SampleUI.AddRadioButton( 16, 2, L"Radio2G3", 35, iY += 24, 125, 22 );
0188: //    g_SampleUI.GetRadioButton( 16 )->SetChecked( true );
0189: //    g_SampleUI.AddSlider( 20, 50, iY += 24, 100, 22 );
0190: //    g_SampleUI.GetSlider( 20 )->SetRange( 0, 100 );
0191: //    g_SampleUI.GetSlider( 20 )->SetValue( 50 );
0192: //    g_SampleUI.AddEditBox( 20, L"Test", 35, iY += 24, 125, 22 );
0193: 
0194:     WCHAR sz[100];
0195:     iY += 256;
0196:     _snwprintf( sz, 100, L"SIZE: %3d", g_MapSize ); sz[99] = 0;
0197:     g_SampleUI.AddStatic( IDC_CHANGE_LEVEL_STATIC, sz, 35, iY += 24, 125, 22 );
0198:     g_SampleUI.AddSlider( IDC_CHANGE_LEVEL, -150, iY += 24, 300, 22, 1, 256, (int)g_MapSize );
0199: }
0200: 
0201: //--------------------------------------------------------------------------------------
0202: // Called during device initialization, this code checks the device for some 
0203: // minimum set of capabilities, and rejects those that don't pass by returning false.
0204: //--------------------------------------------------------------------------------------
0205: bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
0206:                                   D3DFORMAT BackBufferFormat, bool bWindowed )
0207: {
0208:     // Skip backbuffer formats that don't support alpha blending
0209:     // アルファブレンディングをサポートしていないバックバッファフォーマットはスキップする
0210:     IDirect3D9* pD3D = DXUTGetD3DObject(); 
0211:     if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
0212:                     AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
0213:                     D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
0214:         return false;
0215: 
0216:     // Must support vertex shader 1.1
0217:     if( pCaps->VertexShaderVersion < D3DVS_VERSION( 1, 1 ) )
0218:         return false;
0219: 
0220:     // Must support pixel shader 2.0
0221:     if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )
0222:         return false;
0223: 
0224:     return true;
0225: }
0226: 
0227: 
0228: //--------------------------------------------------------------------------------------
0229: // This callback function is called immediately before a device is created to allow the 
0230: // application to modify the device settings. The supplied pDeviceSettings parameter 
0231: // contains the settings that the framework has selected for the new device, and the 
0232: // application can make any desired changes directly to this structure.  Note however that 
0233: // the sample framework will not correct invalid device settings so care must be taken 
0234: // to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail.  
0235: //--------------------------------------------------------------------------------------
0236: void CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps )
0237: {
0238:     // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 
0239:     // then switch to SWVP.
0240:     if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
0241:          pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
0242:     {
0243:         pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0244:     }
0245:     else
0246:     {
0247:         pDeviceSettings->BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
0248:     }
0249: 
0250:     // This application is designed to work on a pure device by not using 
0251:     // IDirect3D9::Get*() methods, so create a pure device if supported and using HWVP.
0252:     if ((pCaps->DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 && 
0253:         (pDeviceSettings->BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) != 0 )
0254:         pDeviceSettings->BehaviorFlags |= D3DCREATE_PUREDEVICE;
0255: 
0256:     // Debugging vertex shaders requires either REF or software vertex processing 
0257:     // and debugging pixel shaders requires REF.  
0258: #ifdef DEBUG_VS
0259:     if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
0260:     {
0261:         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
0262:         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
0263:         pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0264:     }
0265: #endif
0266: #ifdef DEBUG_PS
0267:     pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
0268: #endif
0269: }
0270: 
0271: //-------------------------------------------------------------
0272: // マップの乱数生成
0273: //-------------------------------------------------------------
0274: #define frand() ((FLOAT)rand()/(FLOAT)RAND_MAX)
0275: 
0276: #if 1 // @@@
0277: BYTE g_id[ 256 ][ 256 ];
0278: 
0279: VOID InitFillRand()
0280: {
0281:     DWORD x,y;
0282:     for( y = 0; y < g_MapSize; y++ )
0283:     {
0284:         for( x = 0; x < g_MapSize; x++ )
0285:         {
0286:             g_id[y][x] = rand() % 4;
0287:         }
0288:     }
0289: }
0290: 
0291: VOID WINAPI FillRand (D3DXVECTOR4* pOut, CONST D3DXVECTOR2* pTexCoord, 
0292: CONST D3DXVECTOR2* pTexelSize, LPVOID pData)
0293: {
0294:     UNREFERENCED_PARAMETER( pTexCoord );
0295:     UNREFERENCED_PARAMETER( pTexelSize );
0296:     UNREFERENCED_PARAMETER( pData );
0297: 
0298:     DWORD x = (DWORD)(g_MapSize * pTexCoord->x);
0299:     DWORD y = (DWORD)(g_MapSize * pTexCoord->y);
0300: 
0301:     bool left  = ( g_id[ y    % g_MapSize ][ x    % g_MapSize ] & 1 ) ? true : false; 
0302:     bool up    = ( g_id[ y    % g_MapSize ][ x    % g_MapSize ] & 2 ) ? true : false; 
0303:     bool right = ( g_id[ y    % g_MapSize ][(x+1) % g_MapSize ] & 1 ) ? true : false; 
0304:     bool down  = ( g_id[(y+1) % g_MapSize ][ x    % g_MapSize ] & 2 ) ? true : false; 
0305: 
0306:     float tx, ty;
0307:     if( !left )
0308:     {
0309:         if( !right )
0310:         {
0311: //          tx = 0.0;
0312:         }else{
0313:             tx = 0.25;
0314:         }
0315:     }else{
0316:         if( !right )
0317:         {
0318:             tx = 0.75;
0319:         }else{
0320:             tx = 0.50;
0321:         }
0322:     }
0323:     if( !down )
0324:     {
0325:         if( !up )
0326:         {
0327:             ty = 0.75;
0328:         }else{
0329:             ty = 0.50;
0330:         }
0331:     }else{
0332:         if( !up )
0333:         {
0334: //          ty = 0.0;
0335:         }else{
0336:             ty = 0.25;
0337:         }
0338:     }
0339: 
0340:     pOut->x = tx;
0341:     pOut->y = ty;
0342:     pOut->z =
0343:     pOut->w = 0;
0344: }
0345: 
0346: DWORD* GetTexelPtr( D3DLOCKED_RECT* rect, int x, int y )
0347: {
0348:     return (DWORD*)((BYTE*)rect->pBits + rect->Pitch * y) + x;
0349: }
0350: 
0351: #else
0352: 
0353: VOID WINAPI FillRand (D3DXVECTOR4* pOut, CONST D3DXVECTOR2* pTexCoord, 
0354: CONST D3DXVECTOR2* pTexelSize, LPVOID pData)
0355: {
0356:     UNREFERENCED_PARAMETER( pTexCoord );
0357:     UNREFERENCED_PARAMETER( pTexelSize );
0358:     UNREFERENCED_PARAMETER( pData );
0359: 
0360:     pOut->x = frand();
0361:     pOut->y = frand();
0362:     pOut->z = pOut->w = 0.0f;
0363: }
0364: #endif
0365: 
0366: 
0367: //--------------------------------------------------------------------------------------
0368: // This callback function will be called immediately after the Direct3D device has been 
0369: // created, which will happen during application initialization and windowed/full screen 
0370: // toggles. This is the best location to create D3DPOOL_MANAGED resources since these 
0371: // resources need to be reloaded whenever the device is destroyed. Resources created  
0372: // here should be released in the OnDestroyDevice callback. 
0373: //--------------------------------------------------------------------------------------
0374: 
0375: HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
0376: {
0377:     HRESULT hr;
0378:     WCHAR str[MAX_PATH];
0379: 
0380:     g_pd3dDevice = pd3dDevice;
0381: 
0382:     // Initialize the font
0383:     V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, 
0384:                          OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
0385:                          L"Arial", &g_pFont ) );
0386: 
0387:     // Load the textures
0388: #if 1 // @@@
0389:     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"stone.bmp" ) );
0390: #else
0391:     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"wang.bmp" ) );
0392: #endif
0393:     V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, str, &g_pWangTexture) );
0394: 
0395: #if 1 // @@@ WangTextureの各LODを格納するテクスチャを生成する
0396: {
0397:     D3DSURFACE_DESC srcDesc;
0398:     g_pWangTexture->GetLevelDesc( 0, &srcDesc );
0399:     g_WangTextureSize = srcDesc.Height;
0400:     g_WangLODCount    = g_pWangTexture->GetLevelCount() + 1;
0401:     
0402:     V_RETURN( pd3dDevice->CreateTexture( srcDesc.Width, g_WangTextureSize*2 + 2*g_WangLODCount,
0403:         1,
0404:         0,
0405:         D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &g_pSpreadWangTexture, NULL));
0406: 
0407:     D3DLOCKED_RECT dstRect;
0408:     g_pSpreadWangTexture->LockRect( 0, &dstRect, 0, 0 );
0409: 
0410:     DWORD x, y;
0411:     DWORD* pDst;
0412: 
0413:     for( y = 0; y < g_WangTextureSize*2 + 2*g_WangLODCount; y++ )
0414:     {
0415:         for( x = 0; x < srcDesc.Width; x++ )
0416:         {
0417:             pDst = GetTexelPtr( &dstRect, x, y );
0418:             *pDst++ = 0x00000000;
0419:         }
0420:     }
0421: 
0422:     DWORD level;
0423:     for( level = 0; level < g_WangLODCount; level++ )
0424:     {
0425:         g_pWangTexture->GetLevelDesc( level, &srcDesc );
0426:         int dstHeightBase = srcDesc.Height + 2 * (g_WangLODCount-1-level);
0427: 
0428:         D3DLOCKED_RECT srcRect;
0429:         g_pWangTexture->LockRect( level, &srcRect, 0, 0 );
0430:     
0431:         for( y = 0; y < srcDesc.Height + 2; y++ )
0432:         {
0433:             for( x = 0; x < srcDesc.Width; x++ )
0434:             {
0435:                 int rx = x;
0436:                 int ry = (y - 1 + srcDesc.Height) % srcDesc.Height;
0437: 
0438:                 int i;
0439:                 int max = (int)pow( 2, level );
0440:                 for( i = 0; i < max; i++ )
0441:                 {
0442:                     pDst = GetTexelPtr( &dstRect, x + i * srcDesc.Width, dstHeightBase + y );
0443:                     *pDst = *GetTexelPtr( &srcRect, rx, ry );
0444:                 }
0445:             }
0446:         }
0447:         g_pWangTexture->UnlockRect( level );
0448:     }
0449: 
0450:     g_pSpreadWangTexture->UnlockRect( 0 );
0451: }
0452: #endif
0453: 
0454:     V_RETURN( pd3dDevice->CreateTexture( g_MapSize, g_MapSize, 1
0455:                         , 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &g_pRandTexture, NULL));
0456:     InitFillRand(); // @@@
0457:     V_RETURN( D3DXFillTexture( g_pRandTexture, FillRand, NULL ));
0458: 
0459: #if 1   // @@@ LOD番号を参照するためのテクスチャを生成する
0460: {
0461:     D3DSURFACE_DESC desc;
0462:     g_pWangTexture->GetLevelDesc( 0, &desc );
0463:     
0464:     // 1タイル分のテクスチャを生成する
0465:     V_RETURN( pd3dDevice->CreateTexture( desc.Width/4, desc.Height/4, 0
0466:         , 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &g_pLODLookupTexture, NULL));
0467: 
0468:     // 各LODにLOD番号を書き込む
0469:     int level;
0470:     int maxLevel = g_pLODLookupTexture->GetLevelCount();
0471:     for( level = 0; level <= maxLevel; level++ )
0472:     {
0473:         g_pLODLookupTexture->GetLevelDesc( level, &desc );
0474: 
0475:         D3DLOCKED_RECT d3dlr;
0476:         g_pLODLookupTexture->LockRect( level, &d3dlr, 0, 0 );
0477:         DWORD* pDst;
0478:         DWORD x, y;
0479:     
0480:         for( y = 0; y < desc.Height; y++ )
0481:         {
0482:             for( x = 0; x < desc.Width; x++ )
0483:             {
0484:                 pDst = GetTexelPtr( &d3dlr, x, y );
0485:                 *pDst = (level << 24)|
0486:                         (level << 16)|
0487:                         (level <<  8)|
0488:                         (level <<  0);
0489:             }
0490:         }
0491:         g_pLODLookupTexture->UnlockRect( level );
0492:     }
0493: }
0494: #endif
0495: 
0496:     // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the 
0497:     // shader debugger. Debugging vertex shaders requires either REF or software vertex 
0498:     // processing, and debugging pixel shaders requires REF.  The 
0499:     // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the 
0500:     // shader debugger.  It enables source level debugging, prevents instruction 
0501:     // reordering, prevents dead code elimination, and forces the compiler to compile 
0502:     // against the next higher available software target, which ensures that the 
0503:     // unoptimized shaders do not exceed the shader model limitations.  Setting these 
0504:     // flags will cause slower rendering since the shaders will be unoptimized and 
0505:     // forced into software.  See the DirectX documentation for more information about 
0506:     // using the shader debugger.
0507:     DWORD dwShaderFlags = 0;
0508:     #ifdef DEBUG_VS
0509:         dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
0510:     #endif
0511:     #ifdef DEBUG_PS
0512:         dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
0513:     #endif
0514: 
0515: 
0516:     // Create the D3DX effect file
0517:     V_RETURN( D3DXCreateEffect( pd3dDevice, g_effect, sizeof(g_effect),
0518:         NULL, NULL, dwShaderFlags, NULL, &g_pEffect, NULL ) );
0519: 
0520: 
0521:     // Setup the camera's view parameters
0522:     D3DXVECTOR3 vecEye(0.0f, 3.0f, -3.0f);
0523:     D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f);
0524:     g_Camera.SetViewParams( &vecEye, &vecAt );
0525: 
0526:     return S_OK;
0527: }
0528: 
0529: 
0530: //--------------------------------------------------------------------------------------
0531: // This function loads the mesh and ensures the mesh has normals; it also optimizes the 
0532: // mesh for the graphics card's vertex cache, which improves performance by organizing 
0533: // the internal triangle list for less cache misses.
0534: //--------------------------------------------------------------------------------------
0535: HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh )
0536: {
0537:     ID3DXMesh* pMesh = NULL;
0538:     WCHAR str[MAX_PATH];
0539:     HRESULT hr;
0540: 
0541:     // Load the mesh with D3DX and get back a ID3DXMesh*.  For this
0542:     // sample we'll ignore the X file's embedded materials since we know 
0543:     // exactly the model we're loading.  See the mesh samples such as
0544:     // "OptimizedMesh" for a more generic mesh loading example.
0545:     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) );
0546: 
0547:     V_RETURN( D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh) );
0548: 
0549:     DWORD *rgdwAdjacency = NULL;
0550: 
0551:     // Make sure there are normals which are required for lighting
0552:     if( !(pMesh->GetFVF() & D3DFVF_NORMAL) )
0553:     {
0554:         ID3DXMesh* pTempMesh;
0555:         V( pMesh->CloneMeshFVF( pMesh->GetOptions(), 
0556:                                   pMesh->GetFVF() | D3DFVF_NORMAL, 
0557:                                   pd3dDevice, &pTempMesh ) );
0558:         V( D3DXComputeNormals( pTempMesh, NULL ) );
0559: 
0560:         SAFE_RELEASE( pMesh );
0561:         pMesh = pTempMesh;
0562:     }
0563: 
0564:     // Optimize the mesh for this graphics card's vertex cache 
0565:     // so when rendering the mesh's triangle list the vertices will 
0566:     // cache hit more often so it won't have to re-execute the vertex shader 
0567:     // on those vertices so it will improve perf.     
0568:     rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
0569:     if( rgdwAdjacency == NULL )
0570:         return E_OUTOFMEMORY;
0571:     V( pMesh->ConvertPointRepsToAdjacency(NULL, rgdwAdjacency) );
0572:     V( pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
0573:     delete []rgdwAdjacency;
0574: 
0575:     *ppMesh = pMesh;
0576: 
0577:     return S_OK;
0578: }
0579: 
0580: 
0581: //--------------------------------------------------------------------------------------
0582: // This callback function will be called immediately after the Direct3D device has been 
0583: // reset, which will happen after a lost device scenario. This is the best location to 
0584: // create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever 
0585: // the device is lost. Resources created here should be released in the OnLostDevice 
0586: // callback. 
0587: //--------------------------------------------------------------------------------------
0588: HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
0589:                                 const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
0590: {
0591:     HRESULT hr;
0592: 
0593:     pd3dDevice->GetViewport(&g_ViewportFB);
0594: 
0595: 
0596:     if( g_pFont )
0597:         V_RETURN( g_pFont->OnResetDevice() );
0598:     if( g_pEffect )
0599:         V_RETURN( g_pEffect->OnResetDevice() );
0600: 
0601:     // Create a sprite to help batch calls when drawing many lines of text
0602:     V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
0603: 
0604:     // Setup the camera's projection parameters
0605:     float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
0606:     g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1f, 1000.0f );
0607:     g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
0608: 
0609:     g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
0610:     g_HUD.SetSize( 170, 170 );
0611:     g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width-170, pBackBufferSurfaceDesc->Height-350 );
0612:     g_SampleUI.SetSize( 170, 300 );
0613: 
0614:     return S_OK;
0615: }
0616: 
0617: 
0618: //--------------------------------------------------------------------------------------
0619: // This callback function will be called once at the beginning of every frame. This is the
0620: // best location for your application to handle updates to the scene, but is not 
0621: // intended to contain actual rendering calls, which should instead be placed in the 
0622: // OnFrameRender callback.  
0623: //--------------------------------------------------------------------------------------
0624: void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
0625: {
0626:     // Update the camera's position based on user input 
0627:     g_Camera.FrameMove( fElapsedTime );
0628: }
0629: 
0630: 
0631: 
0632: //--------------------------------------------------------------------------------------
0633: // This callback function will be called at the end of every frame to perform all the 
0634: // rendering calls for the scene, and it will also be called if the window needs to be 
0635: // repainted. After this function has returned, the sample framework will call 
0636: // IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
0637: //--------------------------------------------------------------------------------------
0638: void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
0639: {
0640:     HRESULT hr;
0641:     UINT iPass, cPasses;
0642:     D3DXMATRIXA16 mWorld;
0643:     D3DXMATRIXA16 mCamera;
0644:     D3DXMATRIXA16 mView;
0645:     D3DXMATRIXA16 mProj;
0646:     D3DXMATRIXA16 mWorldViewProjection;
0647:     
0648:     // Clear the render target and the zbuffer 
0649:     V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );
0650: 
0651:     // Render the scene
0652:     if( SUCCEEDED( pd3dDevice->BeginScene() ) )
0653:     {
0654:         // Get the projection & view matrix from the camera class
0655:         mCamera = *g_Camera.GetWorldMatrix();
0656:         mView = *g_Camera.GetViewMatrix();
0657:         mProj = *g_Camera.GetProjMatrix();
0658: 
0659:         mWorldViewProjection = mCamera * mView * mProj;
0660: 
0661:         // Set world render technique
0662:         V( g_pEffect->SetTechnique( "WangTechnique" ) );
0663: 
0664:         // Update the effect's variables.  Instead of using strings, it would 
0665:         // be more efficient to cache a handle to the parameter by calling 
0666:         // ID3DXEffect::GetParameterByName
0667:         V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
0668: 
0669:         V( g_pEffect->SetTexture( "WangTexture", g_pWangTexture ) );
0670:         V( g_pEffect->SetTexture( "RandTexture", g_pRandTexture ) );
0671:         V( g_pEffect->SetFloat( "g_fTexSize",         (float)g_MapSize ) );
0672:         V( g_pEffect->SetFloat( "g_fInvTexSize", 1.0f/(float)g_MapSize ) );
0673: #if 1 // @@@
0674:         V( g_pEffect->SetTexture( "LODLookupTexture",  g_pLODLookupTexture ) );
0675:         V( g_pEffect->SetTexture( "SpreadWangTexture", g_pSpreadWangTexture ) );
0676:         V( g_pEffect->SetFloat( "g_fWangTextureSize",  (float)g_WangTextureSize ) );
0677:         V( g_pEffect->SetFloat( "g_fWangLODCount",     (float)g_WangLODCount ) );
0678: #endif
0679:         pd3dDevice->SetFVF( VERTEX::FVF );
0680: 
0681:         V( g_pEffect->Begin(&cPasses, 0) );
0682:         for (iPass = 0; iPass < cPasses; iPass++)
0683:         {
0684:             V( g_pEffect->BeginPass(iPass) );
0685:             pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP,2, g_Vertex, sizeof(VERTEX) );
0686:             V( g_pEffect->EndPass() );
0687:         }
0688:         V( g_pEffect->End() );
0689: 
0690: 
0691: 
0692:         DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" ); // These events are to help PIX identify what the code is doing
0693:         RenderText();
0694:         V( g_HUD.OnRender( fElapsedTime ) );
0695:         V( g_SampleUI.OnRender( fElapsedTime ) );
0696:         DXUT_EndPerfEvent();
0697: 
0698: #ifdef _DEBUG // Textures are displaying when debugging, (デバッグ用にテクスチャを表示する)
0699:         {
0700:         pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,  D3DTOP_SELECTARG1);
0701:         pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,    D3DTA_TEXTURE);
0702:         pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0703:         pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0704:         pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
0705:         pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0706:         float scale = 64.0f;
0707:         typedef struct { FLOAT p[4]; FLOAT tu, tv;} TVERTEX;
0708: 
0709: //      for(DWORD i=0; i<2; i++){
0710:         for(DWORD i=0; i<3; i++){   // @@@
0711:             TVERTEX Vertex[4] = {
0712:                 //    x                             y         z rhw tu tv
0713:                 {(i+0)*scale, (FLOAT)g_ViewportFB.Height-scale, 0, 1, 0, 0,},
0714:                 {(i+1)*scale, (FLOAT)g_ViewportFB.Height-scale, 0, 1, 1, 0,},
0715:                 {(i+1)*scale, (FLOAT)g_ViewportFB.Height-    0, 0, 1, 1, 1,},
0716:                 {(i+0)*scale, (FLOAT)g_ViewportFB.Height-    0, 0, 1, 0, 1,},
0717:             };
0718:             if(0==i) pd3dDevice->SetTexture( 0, g_pWangTexture );
0719:             if(1==i) pd3dDevice->SetTexture( 0, g_pRandTexture );
0720:             if(2==i) pd3dDevice->SetTexture( 0, g_pSpreadWangTexture ); // @@@
0721: 
0722:             pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0723:         }
0724:         }
0725: #endif      
0726: 
0727:         V( pd3dDevice->EndScene() );
0728:     }
0729: }
0730: 
0731: 
0732: //--------------------------------------------------------------------------------------
0733: // Render the help and statistics text. This function uses the ID3DXFont interface for 
0734: // efficient text rendering.
0735: //--------------------------------------------------------------------------------------
0736: void RenderText()
0737: {
0738:     // The helper object simply helps keep track of text position, and color
0739:     // and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc, DT_NOCLIP, m_clr );
0740:     // If NULL is passed in as the sprite object, then it will work however the 
0741:     // pFont->DrawText() will not be batched together.  Batching calls will improves performance.
0742:     const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
0743:     CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
0744: 
0745:     // Output statistics
0746:     txtHelper.Begin();
0747:     txtHelper.SetInsertionPos( 5, 5 );
0748:     txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
0749:     txtHelper.DrawTextLine( DXUTGetFrameStats() );
0750:     txtHelper.DrawTextLine( DXUTGetDeviceStats() );
0751: 
0752:     txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
0753:     txtHelper.DrawTextLine( L"Put whatever misc status here" );
0754:     
0755:     // Draw help
0756:     if( g_bShowHelp )
0757:     {
0758:         txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*3 );
0759:         txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );
0760:         txtHelper.DrawTextLine( L"Controls (F1 to hide):" );
0761: 
0762:         txtHelper.SetInsertionPos( 40, pd3dsdBackBuffer->Height-15*5 );
0763:         txtHelper.DrawTextLine( L"Quit: ESC" );
0764:     }
0765:     else
0766:     {
0767:         txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*2 );
0768:         txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
0769:         txtHelper.DrawTextLine( L"Press F1 for help" );
0770:     }
0771:     txtHelper.End();
0772: }
0773: 
0774: 
0775: //--------------------------------------------------------------------------------------
0776: // Before handling window messages, the sample framework passes incoming windows 
0777: // messages to the application through this callback function. If the application sets 
0778: // *pbNoFurtherProcessing to TRUE, then the sample framework will not process this message.
0779: //--------------------------------------------------------------------------------------
0780: LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing )
0781: {
0782:     // Give the dialogs a chance to handle the message first
0783:     *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
0784:     if( *pbNoFurtherProcessing )
0785:         return 0;
0786:     *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
0787:     if( *pbNoFurtherProcessing )
0788:         return 0;
0789: 
0790:     // Pass all remaining windows messages to camera so it can respond to user input
0791:     g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
0792: 
0793:     return 0;
0794: }
0795: 
0796: 
0797: //--------------------------------------------------------------------------------------
0798: // As a convenience, the sample framework inspects the incoming windows messages for
0799: // keystroke messages and decodes the message parameters to pass relevant keyboard
0800: // messages to the application.  The framework does not remove the underlying keystroke 
0801: // messages, which are still passed to the application's MsgProc callback.
0802: //--------------------------------------------------------------------------------------
0803: void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown )
0804: {
0805:     if( bKeyDown )
0806:     {
0807:         switch( nChar )
0808:         {
0809:             case VK_F1: g_bShowHelp = !g_bShowHelp; break;
0810:         }
0811:     }
0812: }
0813: 
0814: 
0815: //--------------------------------------------------------------------------------------
0816: // Handles the GUI events
0817: //--------------------------------------------------------------------------------------
0818: void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl )
0819: {
0820:     switch( nControlID )
0821:     {
0822:         case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
0823:         case IDC_TOGGLEREF:        DXUTToggleREF(); break;
0824:         case IDC_CHANGEDEVICE:     DXUTSetShowSettingsDialog( !DXUTGetShowSettingsDialog() ); break;
0825:         case IDC_CHANGE_LEVEL:
0826:         {
0827:             WCHAR sz[100];
0828:             g_MapSize = g_SampleUI.GetSlider( IDC_CHANGE_LEVEL )->GetValue();
0829:             _snwprintf( sz, 100, L"SIZE: %3d", g_MapSize ); sz[99] = 0;
0830:             g_SampleUI.GetStatic( IDC_CHANGE_LEVEL_STATIC )->SetText( sz );
0831:             
0832:             if( g_pRandTexture )
0833:             {
0834:                 SAFE_RELEASE( g_pRandTexture );
0835:                 g_pd3dDevice->CreateTexture( g_MapSize, g_MapSize, 1
0836:                                     , 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &g_pRandTexture, NULL);
0837:                 InitFillRand(); // @@@
0838:                 D3DXFillTexture( g_pRandTexture, FillRand, NULL );
0839:             }
0840: 
0841:             break;
0842:         }
0843:    }
0844: }
0845: 
0846: 
0847: //--------------------------------------------------------------------------------------
0848: // This callback function will be called immediately after the Direct3D device has 
0849: // entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
0850: // in the OnResetDevice callback should be released here, which generally includes all 
0851: // D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for 
0852: // information about lost devices.
0853: //--------------------------------------------------------------------------------------
0854: void CALLBACK OnLostDevice()
0855: {
0856:     if( g_pFont )
0857:         g_pFont->OnLostDevice();
0858:     if( g_pEffect )
0859:         g_pEffect->OnLostDevice();
0860:     SAFE_RELEASE( g_pTextSprite );
0861: }
0862: 
0863: 
0864: //--------------------------------------------------------------------------------------
0865: // This callback function will be called immediately after the Direct3D device has 
0866: // been destroyed, which generally happens as a result of application termination or 
0867: // windowed/full screen toggles. Resources created in the OnCreateDevice callback 
0868: // should be released here, which generally includes all D3DPOOL_MANAGED resources. 
0869: //--------------------------------------------------------------------------------------
0870: void CALLBACK OnDestroyDevice()
0871: {
0872:     SAFE_RELEASE( g_pEffect );
0873:     SAFE_RELEASE( g_pFont );
0874: 
0875: #if 1 // @@@
0876:     SAFE_RELEASE( g_pSpreadWangTexture );
0877:     SAFE_RELEASE( g_pLODLookupTexture );
0878: #endif
0879:     SAFE_RELEASE( g_pRandTexture );
0880:     SAFE_RELEASE( g_pWangTexture );
0881: }
0882: 
0883: 
0884: 
0885: