0001: //--------------------------------------------------------------------------------------
0002: // File: main.cpp
0003: //--------------------------------------------------------------------------------------
0004: #include "dxstdafx.h"
0005: #include "resource.h"
0006: #include "rendertarget.h"
0007: 
0008: #undef FAST_RENDERING
0009: //#define FAST_RENDERING
0010: 
0011: //#define DEBUG_VS   // Uncomment this line to debug vertex shaders 
0012: //#define DEBUG_PS   // Uncomment this line to debug pixel shaders 
0013: 
0014: #define ORIGINAL_WIDTH   1024.0f
0015: #define ORIGINAL_HEIGHT  1024.0f
0016: 
0017: #define SCREEN_WIDTH   512.0f
0018: #define SCREEN_HEIGHT  512.0f
0019: //#define SCREEN_WIDTH   1024.0f
0020: //#define SCREEN_HEIGHT  1024.0f
0021: //#define SCREEN_WIDTH  1280.0f
0022: //#define SCREEN_HEIGHT  720.0f
0023: 
0024: #define SCREEN_FORMAT   RTF_RGBA
0025: //#define SCREEN_FORMAT     RTF_RGBA16F
0026: 
0027: 
0028: //--------------------------------------------------------------------------------------
0029: // Vertex format
0030: //--------------------------------------------------------------------------------------
0031: struct VERTEX 
0032: {
0033:     D3DXVECTOR4 pos;
0034:     D3DXVECTOR2 tex1;
0035: 
0036:     static const DWORD FVF;
0037: };
0038: const DWORD VERTEX::FVF = D3DFVF_XYZRHW | D3DFVF_TEX1;
0039: 
0040: 
0041: 
0042: 
0043: 
0044: //--------------------------------------------------------------------------------------
0045: // UI control IDs
0046: //--------------------------------------------------------------------------------------
0047: #define IDC_TOGGLEFULLSCREEN     1
0048: #define IDC_TOGGLEREF            2
0049: #define IDC_CHANGEDEVICE         3
0050: #define IDC_CHANGE_SCENE         4
0051: #define IDC_PAUSE                10
0052: #define IDC_SCALE_STATIC         11
0053: #define IDC_SCALE                12
0054: 
0055: //--------------------------------------------------------------------------------------
0056: // Global variables
0057: //--------------------------------------------------------------------------------------
0058: HWND g_hWnd;
0059: ID3DXFont*              g_pFont = NULL;         // Font for drawing text
0060: ID3DXSprite*            g_pTextSprite = NULL;   // Sprite for batching draw text calls
0061: CFirstPersonCamera      g_Camera;               // A model viewing camera
0062: bool                    g_bShowHelp = true;     // If true, it renders the UI control text
0063: CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs
0064: CD3DSettingsDlg         g_SettingsDlg;          // Device settings dialog
0065: CDXUTDialog             g_HUD;                  // dialog for standard controls
0066: CDXUTDialog             g_SampleUI;             // dialog for sample specific controls
0067: bool                    g_bPause = false;
0068: //bool                    g_bPause = true;
0069: float                   g_fPhase = D3DX_PI * 0.8f;
0070: 
0071: VERTEX                  g_Vertex[4];
0072: 
0073: // Render target
0074: CRenderTarget          *g_pRT_FullScreen;
0075: D3DVIEWPORT9            g_ViewportFB;
0076: CRenderTarget          *g_pRT_TexCoord=0;
0077: 
0078: // BG object
0079: bool                    g_bObj = true;
0080: LPD3DXMESH              g_pObjMesh=0;
0081: LPDIRECT3DTEXTURE9      g_pObjMeshTexture=0;
0082: D3DXMATRIXA16           g_matObjWorld;
0083: 
0084: // Map object
0085: bool                    g_bMap = true;
0086: LPD3DXMESH              g_pMapMesh=0;
0087: LPDIRECT3DTEXTURE9      g_pMapMeshTexture=0;
0088: D3DXMATRIXA16           g_matMapWorld;
0089: 
0090: // Scene management
0091: DWORD                   g_dwBackgroundColor;
0092: float                   g_fCurvature = 1.0f;
0093: 
0094: 
0095: // Effect system
0096: LPD3DXEFFECT            g_pEffect;
0097: D3DXHANDLE              g_hWorld = NULL;
0098: D3DXHANDLE              g_hWorldViewProjection = NULL;
0099: 
0100: D3DXHANDLE              g_hMeshTexture = NULL;
0101: 
0102: D3DXHANDLE              g_hTechScene           = NULL;
0103: D3DXHANDLE              g_hTechFishEye         = NULL;
0104: 
0105: 
0106: //--------------------------------------------------------------------------------------
0107: // Forward declarations 
0108: //--------------------------------------------------------------------------------------
0109: bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
0110: bool    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
0111: HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
0112: HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
0113: void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
0114: void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
0115: LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );
0116: void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
0117: void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
0118: void    CALLBACK OnLostDevice( void* pUserContext );
0119: void    CALLBACK OnDestroyDevice( void* pUserContext );
0120: 
0121: void    InitApp();
0122: HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh );
0123: void    RenderText(bool bFast);
0124: void    SetupQuad( const D3DSURFACE_DESC* pBackBufferSurfaceDesc );
0125: 
0126: 
0127: //--------------------------------------------------------------------------------------
0128: // Entry point to the program. Initializes everything and goes into a message processing 
0129: // loop. Idle time is used to render the scene.
0130: //--------------------------------------------------------------------------------------
0131: INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
0132: {
0133:     // Enable run-time memory check for debug builds.
0134: #if defined(DEBUG) | defined(_DEBUG)
0135:     _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
0136: #endif
0137: 
0138:     // Set the callback functions. These functions allow DXUT to notify
0139:     // the application about device changes, user input, and windows messages.  The 
0140:     // callbacks are optional so you need only set callbacks for events you're interested 
0141:     // in. However, if you don't handle the device reset/lost callbacks then the sample 
0142:     // framework won't be able to reset your device since the application must first 
0143:     // release all device resources before resetting.  Likewise, if you don't handle the 
0144:     // device created/destroyed callbacks then DXUT won't be able to 
0145:     // recreate your device resources.
0146:     DXUTSetCallbackDeviceCreated( OnCreateDevice );
0147:     DXUTSetCallbackDeviceReset( OnResetDevice );
0148:     DXUTSetCallbackDeviceLost( OnLostDevice );
0149:     DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
0150:     DXUTSetCallbackMsgProc( MsgProc );
0151:     DXUTSetCallbackKeyboard( KeyboardProc );
0152:     DXUTSetCallbackFrameRender( OnFrameRender );
0153:     DXUTSetCallbackFrameMove( OnFrameMove );
0154: 
0155:     // Show the cursor and clip it when in full screen
0156:     DXUTSetCursorSettings( true, true );
0157: 
0158:     InitApp();
0159: 
0160:     // Initialize DXUT and create the desired Win32 window and Direct3D 
0161:     // device for the application. Calling each of these functions is optional, but they
0162:     // allow you to set several options which control the behavior of the framework.
0163:     DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
0164:     DXUTCreateWindow( L"Fish Eye" );
0165:     DXUTCreateDevice( D3DADAPTER_DEFAULT, true, (DWORD)SCREEN_WIDTH, (DWORD)SCREEN_HEIGHT, IsDeviceAcceptable, ModifyDeviceSettings );
0166: //    DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );
0167: 
0168:     // Pass control to DXUT for handling the message pump and 
0169:     // dispatching render calls. DXUT will call your FrameMove 
0170:     // and FrameRender callback when there is idle time between handling window messages.
0171:     DXUTMainLoop();
0172: 
0173:     // Perform any application-level cleanup here. Direct3D device resources are released within the
0174:     // appropriate callback functions and therefore don't require any cleanup code here.
0175: 
0176:     return DXUTGetExitCode();
0177: }
0178: 
0179: 
0180: //--------------------------------------------------------------------------------------
0181: // Initialize the app 
0182: //--------------------------------------------------------------------------------------
0183: void InitApp()
0184: {
0185:     g_pFont = NULL;
0186: 
0187:     g_pRT_FullScreen = 0;
0188:     g_pEffect = NULL;
0189: 
0190:     g_bShowHelp = TRUE;
0191:     g_dwBackgroundColor = 0x00003F3F;
0192: 
0193:     // Initialize dialogs
0194:     g_SettingsDlg.Init( &g_DialogResourceManager );
0195:     g_HUD.Init( &g_DialogResourceManager );
0196:     g_SampleUI.Init( &g_DialogResourceManager );
0197: 
0198:     g_HUD.SetCallback( OnGUIEvent ); int iY = 10; 
0199:     g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 35, iY, 125, 22 );
0200:     g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 35, iY += 24, 125, 22 );
0201:     g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22, VK_F2 );
0202: 
0203:     g_SampleUI.SetCallback( OnGUIEvent ); iY = 200; 
0204: 
0205:     WCHAR sz[100];
0206: 
0207:     g_SampleUI.AddCheckBox( IDC_PAUSE, L"PAUSE", 50, iY += 24, 145, 22, g_bPause );
0208: //    iY += 24;
0209:     StringCchPrintf( sz, 100, L"Curvature: %0.2f", g_fCurvature ); 
0210:     g_SampleUI.AddStatic( IDC_SCALE_STATIC, sz, 35, iY += 24, 125, 22 );
0211:     g_SampleUI.AddSlider( IDC_SCALE, 50, iY += 24, 100, 22, 0, 300, (int) (100.0f*(g_fCurvature+1.0f)) );
0212: }
0213: 
0214: 
0215: //--------------------------------------------------------------------------------------
0216: // Called during device initialization, this code checks the device for some 
0217: // minimum set of capabilities, and rejects those that don't pass by returning false.
0218: //--------------------------------------------------------------------------------------
0219: bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
0220:                                   D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
0221: {
0222:     // Skip backbuffer formats that don't support alpha blending
0223:     IDirect3D9* pD3D = DXUTGetD3DObject(); 
0224:     if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
0225:                     AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
0226:                     D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
0227:         return false;
0228: 
0229:     // Must support pixel shader 1.1
0230:     if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )
0231:         return false;
0232: 
0233:     return true;
0234: }
0235: 
0236: 
0237: //--------------------------------------------------------------------------------------
0238: // This callback function is called immediately before a device is created to allow the 
0239: // application to modify the device settings. The supplied pDeviceSettings parameter 
0240: // contains the settings that the framework has selected for the new device, and the 
0241: // application can make any desired changes directly to this structure.  Note however that 
0242: // DXUT will not correct invalid device settings so care must be taken 
0243: // to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail.  
0244: //--------------------------------------------------------------------------------------
0245: bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
0246: {
0247:     // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 
0248:     // then switch to SWVP.
0249:     if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
0250:          pCaps->VertexShaderVersion < D3DVS_VERSION(2,0) )
0251:     {
0252:         pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0253:     }
0254: 
0255:     // Debugging vertex shaders requires either REF or software vertex processing 
0256:     // and debugging pixel shaders requires REF.  
0257: #ifdef DEBUG_VS
0258:     if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
0259:     {
0260:         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
0261:         pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;                            
0262:         pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
0263:     }
0264: #endif
0265: #ifdef DEBUG_PS
0266:     pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
0267: #endif
0268: 
0269:     // For the first device created if its a REF device, optionally display a warning dialog box
0270:     static bool s_bFirstTime = true;
0271:     if( s_bFirstTime )
0272:     {
0273:         s_bFirstTime = false;
0274:         if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
0275:             DXUTDisplaySwitchingToREFWarning();
0276:     }
0277: 
0278:     return true;
0279: }
0280: 
0281: 
0282: //--------------------------------------------------------------------------------------
0283: // This function loads the mesh and ensures the mesh has normals; it also optimizes the 
0284: // mesh for the graphics card's vertex cache, which improves performance by organizing 
0285: // the internal triangle list for less cache misses.
0286: //--------------------------------------------------------------------------------------
0287: HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh )
0288: {
0289:     ID3DXMesh* pMesh = NULL;
0290:     WCHAR str[MAX_PATH];
0291:     HRESULT hr;
0292: 
0293:     // Load the mesh with D3DX and get back a ID3DXMesh*.  For this
0294:     // sample we'll ignore the X file's embedded materials since we know 
0295:     // exactly the model we're loading.  See the mesh samples such as
0296:     // "OptimizedMesh" for a more generic mesh loading example.
0297:     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) );
0298: 
0299:     V_RETURN( D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh) );
0300: 
0301:     // Make sure there are normals which are required for lighting
0302:     if( !(pMesh->GetFVF() & D3DFVF_NORMAL) )
0303:     {
0304:         ID3DXMesh* pTempMesh;
0305:         V( pMesh->CloneMeshFVF( pMesh->GetOptions(), 
0306:                                   pMesh->GetFVF() | D3DFVF_NORMAL, 
0307:                                   pd3dDevice, &pTempMesh ) );
0308:         V( D3DXComputeNormals( pTempMesh, NULL ) );
0309: 
0310:         SAFE_RELEASE( pMesh );
0311:         pMesh = pTempMesh;
0312:     }
0313: 
0314:     *ppMesh = pMesh;
0315: 
0316:     return S_OK;
0317: }
0318: 
0319: HRESULT OptimizeMesh( IDirect3DDevice9* pd3dDevice, ID3DXMesh** ppMesh )
0320: {
0321:     ID3DXMesh* pMesh = *ppMesh;
0322:     DWORD *rgdwAdjacency = NULL;
0323:     HRESULT hr;
0324: 
0325:     // Optimize the mesh for this graphics card's vertex cache 
0326:     // so when rendering the mesh's triangle list the vertices will 
0327:     // cache hit more often so it won't have to re-execute the vertex shader 
0328:     // on those vertices so it will improve perf.     
0329:     rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
0330:     if( rgdwAdjacency == NULL )
0331:         return E_OUTOFMEMORY;
0332:     V( pMesh->GenerateAdjacency(1e-6f,rgdwAdjacency) );
0333:     V( pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
0334:     delete []rgdwAdjacency;
0335: 
0336:     *ppMesh = pMesh;
0337: 
0338:     return S_OK;
0339: }
0340: 
0341: 
0342: //--------------------------------------------------------------------------------------
0343: // This callback function will be called immediately after the Direct3D device has been 
0344: // created, which will happen during application initialization and windowed/full screen 
0345: // toggles. This is the best location to create D3DPOOL_MANAGED resources since these 
0346: // resources need to be reloaded whenever the device is destroyed. Resources created  
0347: // here should be released in the OnDestroyDevice callback. 
0348: //--------------------------------------------------------------------------------------
0349: HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
0350: {
0351:     WCHAR str[MAX_PATH];
0352:     HRESULT hr;
0353: 
0354:     V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
0355:     V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );
0356: 
0357:     // Initialize the font
0358:     V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, 
0359:                          OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
0360:                          L"Arial", &g_pFont ) );
0361: 
0362:     // Load meshs
0363:     V_RETURN( LoadMesh( pd3dDevice, TEXT("t-pot.x"), &g_pObjMesh ) );
0364:     V_RETURN( OptimizeMesh( pd3dDevice, &g_pObjMesh ) );
0365:     V_RETURN( LoadMesh( pd3dDevice, TEXT("room.x"), &g_pMapMesh ) );
0366:     V_RETURN( OptimizeMesh( pd3dDevice, &g_pMapMesh ) );
0367: 
0368:     // Load mesh textures
0369:     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"t-pot.bmp" ) );
0370:     V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, str, &g_pObjMeshTexture) );
0371:     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"room.bmp" ) );
0372:     V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, str, &g_pMapMeshTexture) );
0373: 
0374: 
0375:     // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the 
0376:     // shader debugger. Debugging vertex shaders requires either REF or software vertex 
0377:     // processing, and debugging pixel shaders requires REF.  The 
0378:     // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the 
0379:     // shader debugger.  It enables source level debugging, prevents instruction 
0380:     // reordering, prevents dead code elimination, and forces the compiler to compile 
0381:     // against the next higher available software target, which ensures that the 
0382:     // unoptimized shaders do not exceed the shader model limitations.  Setting these 
0383:     // flags will cause slower rendering since the shaders will be unoptimized and 
0384:     // forced into software.  See the DirectX documentation for more information about 
0385:     // using the shader debugger.
0386:     DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
0387:     #ifdef DEBUG_VS
0388:         dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
0389:     #endif
0390:     #ifdef DEBUG_PS
0391:         dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
0392:     #endif
0393: 
0394:     // Read the D3DX effect file
0395:     // If this fails, there should be debug output as to 
0396:     // they the .fx file failed to compile
0397:     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"main.fx" ) );
0398:     V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags, 
0399:                                         NULL, &g_pEffect, NULL ) );
0400: 
0401:     return S_OK;
0402: }
0403: 
0404: 
0405: 
0406: //--------------------------------------------------------------------------------------
0407: // This callback function will be called immediately after the Direct3D device has 
0408: // been destroyed, which generally happens as a result of application termination or 
0409: // windowed/full screen toggles. Resources created in the OnCreateDevice callback 
0410: // should be released here, which generally includes all D3DPOOL_MANAGED resources. 
0411: //--------------------------------------------------------------------------------------
0412: void CALLBACK OnDestroyDevice( void* pUserContext )
0413: {
0414:     g_DialogResourceManager.OnDestroyDevice();
0415:     g_SettingsDlg.OnDestroyDevice();
0416:     SAFE_RELEASE(g_pEffect);
0417:     SAFE_RELEASE(g_pFont);
0418: 
0419:     SAFE_RELEASE(g_pMapMeshTexture);
0420:     SAFE_RELEASE(g_pObjMeshTexture);
0421:     SAFE_RELEASE(g_pMapMesh);
0422:     SAFE_RELEASE(g_pObjMesh);
0423: }
0424: 
0425: 
0426: 
0427: //--------------------------------------------------------------------------------------
0428: // This callback function will be called immediately after the Direct3D device has been 
0429: // reset, which will happen after a lost device scenario. This is the best location to 
0430: // create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever 
0431: // the device is lost. Resources created here should be released in the OnLostDevice 
0432: // callback. 
0433: //--------------------------------------------------------------------------------------
0434: HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
0435:                                 const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
0436: {
0437:     HRESULT hr;
0438: 
0439:     V_RETURN( g_DialogResourceManager.OnResetDevice() );
0440:     V_RETURN( g_SettingsDlg.OnResetDevice() );
0441: 
0442:     if( g_pFont )
0443:         V_RETURN( g_pFont->OnResetDevice() );
0444:     if( g_pEffect )
0445:         V_RETURN( g_pEffect->OnResetDevice() );
0446: 
0447:     // Setup the camera with view & projection matrix
0448:     D3DXVECTOR3 vecEye(0.0f, 0.0f, 4.0f);
0449:     D3DXVECTOR3 vecAt (0.0f, 0.0f, 0.0f);
0450:     g_Camera.SetViewParams( &vecEye, &vecAt );
0451:     g_Camera.SetProjParams( D3DXToRadian(90.0f), 1.0f, 0.5f, 100.0f );
0452:     g_Camera.SetRotateButtons( TRUE, FALSE, FALSE, FALSE );// L M R 押しながら動かす
0453: 
0454: 
0455:     pd3dDevice->GetViewport(&g_ViewportFB);
0456: 
0457:     // Create fullscreen renders target texture
0458:     g_pRT_FullScreen = CRenderTarget::Create(pd3dDevice
0459:                                     , (DWORD)ORIGINAL_WIDTH, (DWORD)ORIGINAL_HEIGHT
0460:                                     , SCREEN_FORMAT);
0461: 
0462:     SetupQuad( pBackBufferSurfaceDesc );
0463: 
0464:     
0465:     // Get D3DXHANDLEs to the parameters/techniques that are set every frame so 
0466:     // D3DX doesn't spend time doing string compares.  Doing this likely won't affect
0467:     // the perf of this simple sample but it should be done in complex engine.
0468:     g_hWorld                    = g_pEffect->GetParameterByName( NULL, "mWorld" );
0469:     g_hWorldViewProjection      = g_pEffect->GetParameterByName( NULL, "mWorldViewProjection" );
0470:     g_hMeshTexture              = g_pEffect->GetParameterByName( NULL, "MeshTexture" );
0471: 
0472:     g_hTechScene                = g_pEffect->GetTechniqueByName("TechScene");
0473:     g_hTechFishEye              = g_pEffect->GetTechniqueByName("TechFishEye");
0474: 
0475:     // Set the vars in the effect that doesn't change each frame
0476:     V_RETURN( g_pEffect->SetTexture("RenderTargetTexture", g_pRT_FullScreen->GetTexture()) );
0477: 
0478:     pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
0479:     pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
0480: 
0481:     g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
0482:     g_HUD.SetSize( 170, 170 );
0483:     g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width-170, pBackBufferSurfaceDesc->Height-300 );
0484:     g_SampleUI.SetSize( 170, 250 );
0485: 
0486:     return S_OK;
0487: }
0488: 
0489: 
0490: //--------------------------------------------------------------------------------------
0491: // This callback function will be called immediately after the Direct3D device has 
0492: // entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
0493: // in the OnResetDevice callback should be released here, which generally includes all 
0494: // D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for 
0495: // information about lost devices.
0496: //--------------------------------------------------------------------------------------
0497: void CALLBACK OnLostDevice( void* pUserContext )
0498: {
0499:     g_DialogResourceManager.OnLostDevice();
0500:     g_SettingsDlg.OnLostDevice();
0501:     if( g_pFont )
0502:         g_pFont->OnLostDevice();
0503:     if( g_pEffect )
0504:         g_pEffect->OnLostDevice();
0505:     SAFE_RELEASE(g_pTextSprite);
0506: 
0507:     SAFE_RELEASE(g_pRT_FullScreen);
0508: }
0509: 
0510: 
0511: //--------------------------------------------------------------------------------------
0512: // Sets up a quad to render the fullscreen render target to the backbuffer
0513: // so it can run a fullscreen pixel shader pass that blurs based
0514: // on the depth of the objects.  It set the texcoords based on the blur factor
0515: //--------------------------------------------------------------------------------------
0516: void SetupQuad( const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
0517: {
0518:     FLOAT fWidth5  = pBackBufferSurfaceDesc->Width -0.5f;
0519:     FLOAT fHeight5 = pBackBufferSurfaceDesc->Height-0.5f;
0520: 
0521:     FLOAT fTexWidth1  = 1.0f;
0522:     FLOAT fTexHeight1 = 1.0f;
0523: 
0524:     g_Vertex[0].pos = D3DXVECTOR4(fWidth5, -0.5f, 0.0f, 1.0f);
0525:     g_Vertex[0].tex1 = D3DXVECTOR2(fTexWidth1, 0.0f);
0526: 
0527:     g_Vertex[1].pos = D3DXVECTOR4(fWidth5, fHeight5, 0.0f, 1.0f);
0528:     g_Vertex[1].tex1 = D3DXVECTOR2(fTexWidth1, fTexHeight1);
0529: 
0530:     g_Vertex[2].pos = D3DXVECTOR4(-0.5f, -0.5f, 0.0f, 1.0f);
0531:     g_Vertex[2].tex1 = D3DXVECTOR2(0.0f, 0.0f);
0532: 
0533:     g_Vertex[3].pos = D3DXVECTOR4(-0.5f, fHeight5, 0.0f, 1.0f);
0534:     g_Vertex[3].tex1 = D3DXVECTOR2(0.0f, fTexHeight1);
0535: }
0536: 
0537: void RenderQuad(IDirect3DDevice9* pd3dDevice, D3DXHANDLE hTech)
0538: {
0539:     HRESULT hr;
0540:     UINT cPasses, iPass;
0541: 
0542:     V( g_pEffect->SetTechnique(hTech) );
0543: 
0544:     V( pd3dDevice->SetFVF(VERTEX::FVF) );
0545: 
0546:     // Render the fullscreen quad on to the backbuffer
0547:     V( g_pEffect->Begin(&cPasses, 0) );
0548:     for (iPass = 0; iPass < cPasses; iPass++)
0549:     {
0550:         V( g_pEffect->BeginPass(iPass) );
0551:         V( pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_Vertex, sizeof(VERTEX)) );
0552:         V( g_pEffect->EndPass() );
0553:     }
0554:     V( g_pEffect->End() );
0555: }
0556: 
0557: //--------------------------------------------------------------------------------------
0558: // This callback function will be called once at the beginning of every frame. This is the
0559: // best location for your application to handle updates to the scene, but is not 
0560: // intended to contain actual rendering calls, which should instead be placed in the 
0561: // OnFrameRender callback.  
0562: //--------------------------------------------------------------------------------------
0563: void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
0564: {
0565:     // Update the camera's position based on user input 
0566:     g_Camera.FrameMove( fElapsedTime );
0567: 
0568:     if(!DXUTIsTimePaused())
0569:     {
0570:         if(!g_bPause)
0571:         {
0572:             g_fPhase += 2.0f * fElapsedTime;
0573:             if(2.0f * D3DX_PI < g_fPhase) g_fPhase -= 2.0f * D3DX_PI;
0574:         }
0575:     }
0576: 
0577: 
0578:     D3DXMATRIXA16 matTrans, matRot, matScale;
0579:     D3DXMatrixScaling(&matScale, 1.0f, 1.0f, 1.0f);
0580:     D3DXMatrixTranslation( &matTrans, 0.0f,+0.0f, -0.5f );
0581:     D3DXMatrixRotationY(&matRot, g_fPhase);
0582:     g_matObjWorld = matScale * matRot * matTrans;
0583: 
0584:     D3DXMatrixRotationY(&matRot, -D3DX_PI * 0.5f);
0585:     D3DXMatrixScaling(&matScale, 3.5f, 3.5f, 3.5f);
0586:     g_matMapWorld = matScale * matRot;
0587: }
0588: 
0589: // render map
0590: void RenderBG(IDirect3DDevice9* pd3dDevice)
0591: {
0592:     HRESULT hr;
0593:     UINT iPass, cPasses;
0594:     D3DXMATRIXA16 matView = *g_Camera.GetViewMatrix();
0595:     D3DXMATRIXA16 matProj = *g_Camera.GetProjMatrix();
0596:     D3DXMATRIXA16 matViewProj = matView * matProj;
0597: 
0598:     // Set world render technique
0599:     V( g_pEffect->SetTechnique( g_hTechScene ) );
0600:     
0601:     // Update effect vars
0602:     D3DXMATRIXA16 matWorldViewProj;
0603: 
0604:     if(g_bObj)
0605:     {
0606:         matWorldViewProj = g_matObjWorld * matViewProj;
0607: 
0608:         V( g_pEffect->SetMatrix( g_hWorld, &g_matObjWorld) );
0609:         V( g_pEffect->SetMatrix( g_hWorldViewProjection, &matWorldViewProj) );
0610: 
0611:         // Set the mesh texture 
0612:         V( g_pEffect->SetTexture( g_hMeshTexture, g_pObjMeshTexture) );
0613: 
0614:         // Draw the mesh on the rendertarget
0615:         V( g_pEffect->Begin(&cPasses, 0) );
0616:         for (iPass = 0; iPass < cPasses; iPass++)
0617:         {
0618:             V( g_pEffect->BeginPass(iPass) );
0619:             V( g_pObjMesh->DrawSubset(0) );
0620:             V( g_pEffect->EndPass() );
0621:         }
0622:         V( g_pEffect->End() );
0623:     }
0624: 
0625: 
0626:     if(g_bMap)
0627:     {
0628:         matWorldViewProj = g_matMapWorld * matViewProj;
0629:         V( g_pEffect->SetMatrix( g_hWorld, &g_matMapWorld) );
0630:         V( g_pEffect->SetMatrix( g_hWorldViewProjection, &matWorldViewProj) );
0631: 
0632:         // Set the mesh texture 
0633:         V( g_pEffect->SetTexture( g_hMeshTexture, g_pMapMeshTexture) );
0634: 
0635:         // Draw the mesh on the rendertarget
0636:         V( g_pEffect->Begin(&cPasses, 0) );
0637:         for (iPass = 0; iPass < cPasses; iPass++)
0638:         {
0639:             V( g_pEffect->BeginPass(iPass) );
0640:             V( g_pMapMesh->DrawSubset(0) );
0641:             V( g_pEffect->EndPass() );
0642:         }
0643:         V( g_pEffect->End() );
0644:     }
0645: }
0646: 
0647: 
0648: 
0649: void RenderScene(IDirect3DDevice9* pd3dDevice)
0650: {
0651:     if( SUCCEEDED( g_pRT_FullScreen->Begin() ) )
0652:     {
0653:         HRESULT hr;
0654: 
0655:         V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, g_dwBackgroundColor, 1.0f, 0) );
0656: 
0657:         RenderBG(pd3dDevice);
0658: 
0659:         g_pRT_FullScreen->End();
0660:     }
0661: }
0662: 
0663: void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
0664: {
0665:     HRESULT hr;
0666: 
0667:     // If the settings dialog is being shown, then
0668:     // render it instead of rendering the app's scene
0669:     if( g_SettingsDlg.IsActive() )
0670:     {
0671:         g_SettingsDlg.OnRender( fElapsedTime );
0672:         return;
0673:     }
0674: 
0675: 
0676:     LPDIRECT3DSURFACE9 pOriginalZbuffer = 0;
0677:     V( pd3dDevice->GetDepthStencilSurface( &pOriginalZbuffer ) );
0678: 
0679:     // First render the world on the rendertarget
0680:     RenderScene(pd3dDevice);
0681: 
0682:     V( pd3dDevice->SetDepthStencilSurface( pOriginalZbuffer ) );
0683:     SAFE_RELEASE( pOriginalZbuffer );
0684: 
0685:     // Clear the backbuffer 
0686: //    V( pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x00000000, 1.0f, 0L ) );
0687: 
0688:     // Begin the scene, rendering to the backbuffer
0689:     if( SUCCEEDED( pd3dDevice->BeginScene() ) )
0690:     {
0691:         pd3dDevice->SetViewport(&g_ViewportFB);
0692: 
0693:         g_pEffect->SetFloat("fCurvature", g_fCurvature);
0694:         RenderQuad(pd3dDevice, g_hTechFishEye);
0695: 
0696: #ifdef FAST_RENDERING
0697:         BOOL bFastRendering = true;
0698: #else // FAST_RENDERING
0699:         BOOL bFastRendering = false;
0700: #endif // FAST_RENDERING
0701: 
0702:         if(bFastRendering)
0703:         {
0704:             RenderText(true);
0705:         }else{
0706:             V( g_HUD.OnRender( fElapsedTime ) );
0707:             V( g_SampleUI.OnRender( fElapsedTime ) );
0708: 
0709:             // Render the text
0710:             RenderText(false);
0711: 
0712: #if 1
0713: #ifdef _DEBUG // Display textures when debugging, (デバッグ用にテクスチャを表示する)
0714:             {
0715:             pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,  D3DTOP_SELECTARG1);
0716:             pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,    D3DTA_TEXTURE);
0717:             pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0718:             pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
0719:             pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
0720:             pd3dDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
0721:             float scale = 128.0f;
0722:             typedef struct {
0723:                 FLOAT       p[4];
0724:                 FLOAT       tu, tv;
0725:             } TVERTEX;
0726:             LPDIRECT3DTEXTURE9 texture_tbl[] = 
0727:             {
0728:                 g_pRT_FullScreen->GetTexture(),
0729:                 NULL,
0730:             };
0731:             for(DWORD i=0; texture_tbl[i]; i++){
0732:                 TVERTEX Vertex[4] = {
0733:                     //    x                             y         z rhw tu tv
0734:                     {(i+0)*scale, (FLOAT)g_ViewportFB.Height-scale, 0, 1, 0, 0,},
0735:                     {(i+1)*scale, (FLOAT)g_ViewportFB.Height-scale, 0, 1, 1, 0,},
0736:                     {(i+1)*scale, (FLOAT)g_ViewportFB.Height-    0, 0, 1, 1, 1,},
0737:                     {(i+0)*scale, (FLOAT)g_ViewportFB.Height-    0, 0, 1, 0, 1,},
0738:                 };
0739:                 pd3dDevice->SetTexture( 0, texture_tbl[i] );
0740:                 pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TVERTEX ) );
0741:             }
0742:             }
0743: #endif      
0744: #endif
0745:         }
0746: 
0747:         // End the scene.
0748:         pd3dDevice->EndScene();
0749:     }
0750: }
0751: 
0752: //--------------------------------------------------------------------------------------
0753: // Render the help and statistics text. This function uses the ID3DXFont interface for 
0754: // efficient text rendering.
0755: //--------------------------------------------------------------------------------------
0756: void RenderText(bool bFast)
0757: {
0758:     if(bFast)
0759:     {
0760:         // なるべく負荷をかけたくないときには、
0761:         // FPS が更新されたときだけウィンドウのタイトルを変更するシステムにする
0762:         wchar_t buf[256];
0763:         static float s_fFPS_Last = -1.0f;
0764:         float fFps = DXUTGetFPS();
0765:         if(fFps != s_fFPS_Last)
0766:         {
0767:             swprintf_s(  buf, 256, TEXT("%0.4f"), fFps );
0768:             SetWindowText(g_hWnd, buf );
0769:             s_fFPS_Last = fFps;
0770:         }
0771: 
0772:         return;
0773:     }
0774: 
0775:     // The helper object simply helps keep track of text position, and color
0776:     // and then it calls pFont->DrawText( g_pSprite, strMsg, -1, &rc, DT_NOCLIP, g_clr );
0777:     // If NULL is passed in as the sprite object, then it will work however the 
0778:     // pFont->DrawText() will not be batched together.  Batching calls will improves performance.
0779:     CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
0780: 
0781:     // Output statistics
0782:     txtHelper.Begin();
0783:     txtHelper.SetInsertionPos( 5, 5 );
0784:     txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
0785:     txtHelper.DrawTextLine( DXUTGetFrameStats() );
0786:     txtHelper.DrawTextLine( DXUTGetDeviceStats() );
0787: 
0788:     txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
0789:     txtHelper.DrawFormattedTextLine( L"FPS: %0.4f", DXUTGetFPS() );
0790: 
0791: #if 0
0792:     // Draw help
0793:     if( g_bShowHelp )
0794:     {
0795:         const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
0796:         txtHelper.SetInsertionPos( 2, pd3dsdBackBuffer->Height-15*6 );
0797:         txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );
0798:         txtHelper.DrawTextLine( L"Controls (F1 to hide):" );
0799: 
0800:         txtHelper.SetInsertionPos( 20, pd3dsdBackBuffer->Height-15*5 );
0801:         txtHelper.DrawTextLine( L"Look: Left drag mouse\n"
0802:                                 L"Move: A,W,S,D or Arrow Keys\n"
0803:                                 L"Move up/down: Q,E or PgUp,PgDn\n"
0804:                                 L"Reset camera: Home\n" );
0805:     }
0806:     else
0807:     {
0808:         txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
0809:         txtHelper.DrawTextLine( L"Press F1 for help" );
0810:     }
0811: #endif
0812:     txtHelper.End();
0813: }
0814: 
0815: 
0816: //--------------------------------------------------------------------------------------
0817: // Before handling window messages, DXUT passes incoming windows 
0818: // messages to the application through this callback function. If the application sets 
0819: // *pbNoFurtherProcessing to TRUE, then DXUT will not process this message.
0820: //--------------------------------------------------------------------------------------
0821: LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
0822: {
0823:     g_hWnd = hWnd;
0824: 
0825:     // Always allow dialog resource manager calls to handle global messages
0826:     // so GUI state is updated correctly
0827:     *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
0828:     if( *pbNoFurtherProcessing )
0829:         return 0;
0830: 
0831:     if( g_SettingsDlg.IsActive() )
0832:     {
0833:         g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
0834:         return 0;
0835:     }
0836: 
0837:     // Give the dialogs a chance to handle the message first
0838:     *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
0839:     if( *pbNoFurtherProcessing )
0840:         return 0;
0841:     *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );
0842:     if( *pbNoFurtherProcessing )
0843:         return 0;
0844: 
0845:     // Pass all remaining windows messages to camera so it can respond to user input
0846:     g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
0847: 
0848:     return 0;
0849: }
0850: 
0851: 
0852: //--------------------------------------------------------------------------------------
0853: // As a convenience, DXUT inspects the incoming windows messages for
0854: // keystroke messages and decodes the message parameters to pass relevant keyboard
0855: // messages to the application.  The framework does not remove the underlying keystroke 
0856: // messages, which are still passed to the application's MsgProc callback.
0857: //--------------------------------------------------------------------------------------
0858: void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
0859: {
0860:     if( bKeyDown )
0861:     {
0862:         switch( nChar )
0863:         {
0864:             case VK_F1: g_bShowHelp = !g_bShowHelp; break;
0865:         }
0866:     }
0867: }
0868: 
0869: 
0870: //--------------------------------------------------------------------------------------
0871: // Handles the GUI events
0872: //--------------------------------------------------------------------------------------
0873: void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
0874: {
0875:     switch( nControlID )
0876:     {
0877:         case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
0878:         case IDC_TOGGLEREF:        DXUTToggleREF(); break;
0879:         case IDC_CHANGEDEVICE:     g_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() ); break;
0880: 
0881:         case IDC_PAUSE:
0882:             g_bPause = g_SampleUI.GetCheckBox( IDC_PAUSE )->GetChecked(); 
0883:             break;
0884: 
0885:         case IDC_SCALE: {
0886:             g_fCurvature = -1.0f + 0.01f*(float) (g_SampleUI.GetSlider( IDC_SCALE )->GetValue());
0887: 
0888:             WCHAR sz[100];
0889:             StringCchPrintf( sz, 100, L"Curvature: %0.2f", g_fCurvature ); 
0890:             g_SampleUI.GetStatic( IDC_SCALE_STATIC )->SetText( sz );
0891:             }break;
0892: 
0893:         default:
0894:             break;
0895:     }
0896: }
0897: 
0898: 
0899: