D3D9 -
D3DAppTemplate
D3DAppTemplate.h
-
#include
<d3d9.h>
#include <d3dx9.h>
#include
"D3DAppTemplateDlg.h"
class CD3DAppTemplateApp
~CD3DAppTemplateApp();
public:
CD3DAppTemplateDlg* pMainWindow;
D3DAppTemplate.cpp
#include
"DXUT.h"
#include "DXUTcamera.h"
#include "DXUTsettingsdlg.h"
#include "SDKmisc.h"
#include "SDKsound.h"
//--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
ID3DXFont*
g_pFont = NULL; // Font for drawing text
ID3DXSprite* g_pTextSprite = NULL; // Sprite for batching draw text calls
CFirstPersonCamera g_Camera; // A model viewing camera
CSoundManager g_DSound; // DirectSound class
bool
g_bShowHelp = true; // If true, it renders the UI control text
bool g_bPlaySounds = true; // whether to play sounds
double g_fLastAnimTime = 0.0; // Time for the animations
//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
D3DFORMAT BackBufferFormat, bool bWindowed,
void* pUserContext );
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings,
void* pUserContext );
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC*
pBackBufferSurfaceDesc,
void* pUserContext );
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC*
pBackBufferSurfaceDesc,
void* pUserContext );
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext
);
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime,
float fElapsedTime, void* pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam, bool* pbNoFurtherProcessing,
void* pUserContext );
void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown,
void* pUserContext );
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl,
void* pUserContext );
void CALLBACK OnLostDevice( void* pUserContext );
void CALLBACK OnDestroyDevice( void* pUserContext );
void RenderText();
void
InitApp();
void
InitialD3DAppSettings();
CD3DAppTemplateApp::CD3DAppTemplateApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
pMainWindow = NULL;
}
BOOL
CD3DAppTemplateApp::InitInstance()
{
// InitCommonControlsEx() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
pMainWindow = new CD3DAppTemplateDlg();
pMainWindow->Create(CD3DAppTemplateDlg::IDD);
pMainWindow->ShowWindow(SW_SHOW);
pMainWindow->ShowWindow(SW_HIDE);
m_pMainWnd = pMainWindow;
InitialD3DAppSettings();
//g_d3dApp.Cleanup3DEnvironment();
delete
pMainWindow;
pMainWindow
= NULL;
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
void
InitialD3DAppSettings()
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
// Set the callback functions. These functions allow DXUT to notify
// the application about device changes, user input, and windows messages.
The
// callbacks are optional so you need only set callbacks for events you're
interested
// in. However, if you don't handle the device reset/lost callbacks then
the sample
// framework won't be able to reset your device since the application
must first
// release all device resources before resetting. Likewise, if you don't
handle the
// device created/destroyed callbacks then DXUT won't be able to
// recreate your device resources.
DXUTSetCallbackD3D9DeviceAcceptable( IsDeviceAcceptable );
DXUTSetCallbackD3D9DeviceCreated( OnCreateDevice );
DXUTSetCallbackD3D9DeviceReset( OnResetDevice );
DXUTSetCallbackD3D9FrameRender( OnFrameRender );
DXUTSetCallbackD3D9DeviceLost( OnLostDevice );
DXUTSetCallbackD3D9DeviceDestroyed( OnDestroyDevice );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackKeyboard( KeyboardProc );
DXUTSetCallbackFrameMove( OnFrameMove );
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
// Show the cursor and clip it when in full screen
DXUTSetCursorSettings( true, true );
InitApp();
// Initialize DXUT and create the desired Win32 window and Direct3D
// device for the application. Calling each of these functions is optional,
but they
// allow you to set several options which control the behavior of the
framework.
DXUTInit( true, true ); // Parse the command line and show msgboxes
DXUTSetHotkeyHandling( true, true, true ); // handle the defaul hotkeys
/*DXUTCreateWindow( L"D3D9 App Template", 0, 0, LoadMenu(0,
MAKEINTRESOURCE(IDR_MAINMENU)) );*/
DXUTCreateWindow( L"D3D9 App Template", 0, 0, 0);
SetWindowLong( DXUTGetHWND(), GWL_STYLE,
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX);
// We need to set up DirectSound after we have a window.
g_DSound.Initialize( DXUTGetHWND(), DSSCL_PRIORITY );
DXUTCreateDevice( true, 631, 380 );
//InitD3DApp();
// Pass control to DXUT for handling the message pump and
// dispatching render calls. DXUT will call your FrameMove
// and FrameRender callback when there is idle time between handling window
messages.
DXUTMainLoop();
// Perform any application-level cleanup here. Direct3D device resources
are released within the
// appropriate callback functions and therefore don't require any cleanup
code here.
//return DXUTGetExitCode();
}
//--------------------------------------------------------------------------------------
// Initialize the app
//--------------------------------------------------------------------------------------
void InitApp()
{
// Add mixed vp to the available vp choices in device settings dialog.
DXUTGetD3D9Enumeration()->SetPossibleVertexProcessingList( true, false,
false, true );
// Setup the camera with view matrix
D3DXVECTOR3 vEye( .5f, .55f, -.2f );
D3DXVECTOR3 vAt( .5f, .125f, .5f );
g_Camera.SetViewParams( &vEye, &vAt );
g_Camera.SetScalers( 0.01f, 1.0f ); // Camera movement parameters
}
//--------------------------------------------------------------------------------------
// Called during device initialization, this code checks the device for
some
// minimum set of capabilities, and rejects those that don't pass by returning
false.
//--------------------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat,
D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
{
// Skip backbuffer formats that don't support alpha blending
IDirect3D9* pD3D = DXUTGetD3D9Object();
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
return false;
// Need to support ps 2.0
if( pCaps->PixelShaderVersion < D3DPS_VERSION( 2, 0 ) )
return false;
// Need to support A8R8G8B8 textures
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
AdapterFormat, 0,
D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8 ) ) )
return false;
return true;
}
//--------------------------------------------------------------------------------------
// This callback function is called immediately before a device is created
to allow the
// application to modify the device settings. The supplied pDeviceSettings
parameter
// contains the settings that the framework has selected for the new device,
and the
// application can make any desired changes directly to this structure.
Note however that
// DXUT will not correct invalid device settings so care must be taken
// to return valid device settings, otherwise IDirect3D9::CreateDevice()
will fail.
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings,
void* pUserContext )
{
assert( DXUT_D3D9_DEVICE == pDeviceSettings->ver );
HRESULT hr;
IDirect3D9* pD3D = DXUTGetD3D9Object();
D3DCAPS9 caps;
V( pD3D->GetDeviceCaps( pDeviceSettings->d3d9.AdapterOrdinal,
pDeviceSettings->d3d9.DeviceType,
&caps ) );
// If device doesn't support HW T&L or doesn't support 1.1 vertex
shaders in HW
// then switch to SWVP.
if( ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) == 0 ||
caps.VertexShaderVersion < D3DVS_VERSION( 1, 1 ) )
{
pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
// If the hardware cannot do vertex blending, use software vertex processing.
if( caps.MaxVertexBlendMatrices < 2 )
pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
// If using hardware vertex processing, change to mixed vertex processing
// so there is a fallback.
if( pDeviceSettings->d3d9.BehaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING
)
pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_MIXED_VERTEXPROCESSING;
// Debugging vertex shaders requires either REF or software vertex processing
// and debugging pixel shaders requires REF.
#ifdef DEBUG_VS
if( pDeviceSettings->d3d9.DeviceType != D3DDEVTYPE_REF )
{
pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
pDeviceSettings->d3d9.BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
pDeviceSettings->d3d9.BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
#endif
#ifdef DEBUG_PS
pDeviceSettings->d3d9.DeviceType = D3DDEVTYPE_REF;
#endif
// For the first device created if its a REF device, optionally display
a warning dialog box
static bool s_bFirstTime = true;
if( s_bFirstTime )
{
s_bFirstTime = false;
if( pDeviceSettings->d3d9.DeviceType == D3DDEVTYPE_REF )
DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver );
}
return true;
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D
device has been
// created, which will happen during application initialization and windowed/full
screen
// toggles. This is the best location to create D3DPOOL_MANAGED resources
since these
// resources need to be reloaded whenever the device is destroyed. Resources
created
// here should be released in the OnDestroyDevice callback.
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC*
pBackBufferSurfaceDesc,
void* pUserContext )
{
HRESULT hr;
// Initialize the font
V_RETURN( D3DXCreateFont( pd3dDevice, 10, 0, 0, 1, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
L"MS Sans Serif ", &g_pFont ) );
// Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders
with the
// shader debugger. Debugging vertex shaders requires either REF or software
vertex
// processing, and debugging pixel shaders requires REF. The
// D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience
in the
// shader debugger. It enables source level debugging, prevents instruction
// reordering, prevents dead code elimination, and forces the compiler
to compile
// against the next higher available software target, which ensures that
the
// unoptimized shaders do not exceed the shader model limitations. Setting
these
// flags will cause slower rendering since the shaders will be unoptimized
and
// forced into software. See the DirectX documentation for more information
about
// using the shader debugger.
DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
#if
defined( DEBUG ) || defined( _DEBUG )
// Set the D3DXSHADER_DEBUG flag to embed debug information in the shaders.
// Setting this flag improves the shader debugging experience, but still
allows
// the shaders to be optimized and to run exactly the way they will run
in
// the release configuration of this program.
dwShaderFlags |= D3DXSHADER_DEBUG;
#endif
#ifdef
DEBUG_VS
dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
#endif
#ifdef DEBUG_PS
dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
#endif
return S_OK;
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D
device has been
// reset, which will happen after a lost device scenario. This is the
best location to
// create D3DPOOL_DEFAULT resources since these resources need to be reloaded
whenever
// the device is lost. Resources created here should be released in the
OnLostDevice
// callback.
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
HRESULT hr;
// get device caps
D3DCAPS9 caps;
pd3dDevice->GetDeviceCaps( &caps );
if( g_pFont )
V_RETURN( g_pFont->OnResetDevice() );
// Create a sprite to help batch calls when drawing many lines of text
V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
// Setup the camera's projection parameters
float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height;
g_Camera.SetProjParams( D3DX_PI / 3, fAspectRatio, 0.001f, 100.0f );
// set lighting
pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
pd3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_ARGB( 255, 255,
255, 255 ) );
pd3dDevice->LightEnable( 0, TRUE );
pd3dDevice->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE );
// reset the timer
g_fLastAnimTime = DXUTGetGlobalTimer()->GetTime();
return S_OK;
}
//--------------------------------------------------------------------------------------
// This callback function will be called once at the beginning of every
frame. This is the
// best location for your application to handle updates to the scene,
but is not
// intended to contain actual rendering calls, which should instead be
placed in the
// OnFrameRender callback.
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext
)
{
g_fLastAnimTime = fTime;
// Update the camera's position based on user input
g_Camera.FrameMove( fElapsedTime );
}
//--------------------------------------------------------------------------------------
// This callback function will be called at the end of every frame to
perform all the
// rendering calls for the scene, and it will also be called if the window
needs to be
// repainted. After this function has returned, DXUT will call
// IDirect3DDevice9::Present to display the contents of the next buffer
in the swap chain
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime,
float fElapsedTime, void* pUserContext )
{
pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
0xFFA1E1FF, 1.0f, 0L );
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
//
// Output text information
//
RenderText();
pd3dDevice->EndScene();
}
}
//--------------------------------------------------------------------------------------
// Render the help and statistics text. This function uses the ID3DXFont
interface for
// efficient text rendering.
//--------------------------------------------------------------------------------------
void RenderText()
{
// The helper object simply helps keep track of text position, and color
// and then it calls pFont->DrawText( m_pSprite, strMsg, -1, &rc,
DT_NOCLIP, m_clr );
// If NULL is passed in as the sprite object, then it will work however
the
// pFont->DrawText() will not be batched together. Batching calls will
improves performance.
CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 10 );
const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetD3D9BackBufferSurfaceDesc();
// Output statistics
txtHelper.Begin();
txtHelper.SetInsertionPos( 5, 5 );
txtHelper.SetForegroundColor( 0xFF0000FF );
txtHelper.DrawTextLine( DXUTGetFrameStats( true ) );
txtHelper.End();
}
//--------------------------------------------------------------------------------------
// As a convenience, DXUT inspects the incoming windows messages for
// keystroke messages and decodes the message parameters to pass relevant
keyboard
// messages to the application. The framework does not remove the underlying
keystroke
// messages, which are still passed to the application's MsgProc callback.
//--------------------------------------------------------------------------------------
void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown,
void* pUserContext )
{
if( bKeyDown )
{
switch( nChar )
{
case VK_F1:
g_bShowHelp = !g_bShowHelp; break;
}
}
}
//--------------------------------------------------------------------------------------
// Before handling window messages, DXUT passes incoming windows
// messages to the application through this callback function. If the
application sets
// *pbNoFurtherProcessing to TRUE, then DXUT will not process this message.
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
lParam, bool* pbNoFurtherProcessing,
void* pUserContext )
{
g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
return 0;
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D
device has
// been destroyed, which generally happens as a result of application
termination or
// windowed/full screen toggles. Resources created in the OnCreateDevice
callback
// should be released here, which generally includes all D3DPOOL_MANAGED
resources.
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
SAFE_RELEASE( g_pFont );
//g_d3dApp.Cleanup3DEnvironment();
//
//.
g_d3dApp - ,
.
.
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D
device has
// entered a lost state and before IDirect3DDevice9::Reset is called.
Resources created
// in the OnResetDevice callback should be released here, which generally
includes all
// D3DPOOL_DEFAULT resources. See the "Lost Devices" section
of the documentation for
// information about lost devices.
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
if( g_pFont )
g_pFont->OnLostDevice();
SAFE_RELEASE( g_pTextSprite );
}
|