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