当初学GL的时候, 一直想写那个HDR的SHADER程序,苦于没有框架,再加上GL的例子太少,最后果断踏上了DX这条不归路.花了一天时间(准确的说是第一天的上午和第二天的下午)把DXUT的框架学习了,感觉很不错.算是正式踏上了DX这条大道.后面的无数的SHADER等着去实现,心里难免有点小激动!!!好了费话不多说了,跟着来吧,把这三个例子实现了,你就可以随意使用DXUT框架了.呵呵!!!

我的DX-SDK版本为:Microsoft DirectX SDK (June 2010)

这时的下载地址为:http://download.microsoft.com/download/A/E/7/AE743F1F-632B-4809-87A9-AA1BB3458E31/DXSDK_Jun10.exe
不知道以后会失效不!

版本一定要对,不然生成的DXUT框架代码不一样,会死人的!!!

开发环境为VS2008,D3D9

第一步:打开DirectX Sample Browser(June 2010)

第二步:找到EmptyProject项目(可以通过搜索empty快速定位):

这里我们需要最下面一个,那个才是DX9的框架

第三步:点击Install Project,选好目录,生成之.

最后,我们来分析下它生成的代码吧.

打开2008的项目文件

//--------------------------------------------------------------------------------------
// File: chap1_dx9.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "DXUT.h"
#include "resource.h"//--------------------------------------------------------------------------------------
// Rejects any D3D9 devices that aren't acceptable to the app by returning false
//--------------------------------------------------------------------------------------
bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,bool bWindowed, void* pUserContext )
{// Typically want to skip back buffer formats that don't support alpha blendingIDirect3D9* pD3D = DXUTGetD3D9Object();if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,D3DRTYPE_TEXTURE, BackBufferFormat ) ) )return false;return true;
}
/*知识点8.2:选择最好的设备设置
---------------------------------------------
来自<<DXUT框架剖析(4)>>
---------------------------------------------
在回调函数IsD3D9DeviceAcceptable()被每种设置的组合调用之后,框架把这些可以接受的组合分级,并从中选出最优的使用。较高级别的组合
包括:(1)D3DDEVTYPE_HAL,为了得到硬件加速。(2)如果该应用程序运行在全屏模式下,该框架会选择桌面格式所对应的适配器格式,这样从窗口到全屏模式的转换就快多了。例外的是,如果桌面显示模式不足32位,该框架会选择D3DFMT_X8R8G8B8。(3)适配器格式所对应的后台缓冲区格式。IDirect3D9::CheckDeviceFormat Method
Determines whether a surface format is available as a specified resource type and can be used as a texture, depth-stencil
buffer, or render target, or any combination of the three, on a device representing this adapter.Syntax
HRESULT CheckDeviceFormat([in]  UINT Adapter,[in]  D3DDEVTYPE DeviceType,[in]  D3DFORMAT AdapterFormat,[in]  DWORD Usage,[in]  D3DRESOURCETYPE RType,[in]  D3DFORMAT CheckFormat
);Parameters
Adapter [in]
UINT
Ordinal number denoting the display adapter to query. D3DADAPTER_DEFAULT is always the primary display adapter.
This method returns D3DERR_INVALIDCALL when this value equals or exceeds the number of display adapters in the system. DeviceType [in]
D3DDEVTYPE
Member of the D3DDEVTYPE enumerated type, identifying the device type.AdapterFormat [in]
D3DFORMAT
Member of the D3DFORMAT enumerated type, identifying the format of the display mode into which the adapter will be placed.Usage [in]
DWORD
Requested usage options for the surface. Usage options are any combination of D3DUSAGE and D3DUSAGE_QUERY constants
(only a subset of the D3DUSAGE constants are valid for CheckDeviceFormat; see the table on the D3DUSAGE page).RType [in]
D3DRESOURCETYPE
Resource type requested for use with the queried format. Member of D3DRESOURCETYPE. CheckFormat [in]
D3DFORMAT
Format of the surfaces which may be used, as defined by Usage. Member of D3DFORMAT.Return Value
HRESULT If the format is compatible with the specified device for the requested usage, this method returns D3D_OK.D3DERR_INVALIDCALL is returned if Adapter equals or exceeds the number of display adapters in the system, or if DeviceType is
unsupported.D3DERR_NOTAVAILABLE is returned if the format is not acceptable to the device for this usage.Remarks
Here are some examples using CheckDeviceFormat to check for hardware support of:An off-screen plain surface format - Specify Usage = 0 and RType = D3DRTYPE_SURFACE.
A depth-stencil format - The following snippet tests for the passed in depth-stencil format:
BOOL IsDepthFormatExisting( D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat )
{HRESULT hr = pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,AdapterFormat,D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE,DepthFormat);return SUCCEEDED( hr );
}See Selecting a Device (Direct3D 9) for more detail on the enumeration process.Can this texture be rendered in a particular format - Given the current display mode, this example shows how to verify that
the texture format is compatible with the specific back-buffer format:
BOOL IsTextureFormatOk( D3DFORMAT TextureFormat, D3DFORMAT AdapterFormat )
{HRESULT hr = pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,AdapterFormat,0,D3DRTYPE_TEXTURE,TextureFormat);return SUCCEEDED( hr );
}Alpha blending in a pixel shader - Set Usage to D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING. Expect this to fail for all
floating-point render targets.
Autogeneration of mipmaps - Set Usage to D3DUSAGE_AUTOGENMIPMAP. If the mipmap automatic generation fails, the application will
get a non-mipmapped texture. Calling this method is considered a hint, so this method can return D3DOK_NOAUTOGEN
(a valid success code) if the only thing that fails is the mipmap generation. For more information about mipmap generation,
see Automatic Generation of Mipmaps (Direct3D 9). When migrating code from Direct3D 9 to Direct3D 10, the Direct3D 10 equivalent to CheckDeviceFormat is CheckFormatSupport.*///--------------------------------------------------------------------------------------
// Before a device is created, modify the device settings as needed
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )
{return true;
}//--------------------------------------------------------------------------------------
// Create any D3D9 resources that will live through a device reset (D3DPOOL_MANAGED)
// and aren't tied to the back buffer size
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,void* pUserContext )
{return S_OK;
}//--------------------------------------------------------------------------------------
// Create any D3D9 resources that won't live through a device reset (D3DPOOL_DEFAULT)
// or that are tied to the back buffer size
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,void* pUserContext )
{return S_OK;
}//--------------------------------------------------------------------------------------
// Handle updates to the scene.  This is called regardless of which D3D API is used
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{
}//--------------------------------------------------------------------------------------
// Render the scene using the D3D9 device
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{HRESULT hr;// Clear the render target and the zbuffer V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 45, 50, 170 ), 1.0f, 0 ) );// Render the sceneif( SUCCEEDED( pd3dDevice->BeginScene() ) ){V( pd3dDevice->EndScene() );}
}//--------------------------------------------------------------------------------------
// Handle messages to the application
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,bool* pbNoFurtherProcessing, void* pUserContext )
{return 0;
}//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9ResetDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9LostDevice( void* pUserContext )
{
}//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9CreateDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
{
}//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int )
{// 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 functionsDXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
/*知识点8.1:选择最好的设备设置
---------------------------------------------
来自<<DXUT框架剖析(4)>>
---------------------------------------------
在应用程序中,可以使用DXUTSetCallbackD3D9DeviceAcceptable设置回调函数IsDeviceAcceptable()帮助DXUT框架为应用程序选择最好的设备,
该函数的声明如下:
Sets the Direct3D 9 device acceptable callback function.
VOID DXUTSetCallbackD3D9DeviceAcceptable(LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE pCallback,void* pUserContext
)Parameters
pCallback
[in] Pointer to a LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE callback function. If the callback function is supplied, it will be
called after the Direct3D 9 device.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL.
Return Value
No return value.
----------------------------------------
Application-defined callback function, called by DXUT to build an enumerated list of all possible Direct3D 9 devices.
DXUT then selects the best device for creation among this list. This callback function allows the application to prevent
unwanted devices from being added to the list.bool LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE(D3DCAPS9* pCaps,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,bool bWindowed,void* pUserContext
)Parameters
pCaps
[in] Pointer to the D3DCAPS9 capabilities of the Direct3D 9 device
AdapterFormat
[in] Format of the Direct3D 9 adapter
BackBufferFormat
[in] Format of the Direct3D 9 backbuffer
bWindowed
[in] Indicates windowed mode. TRUE if the application runs windowed; FALSE if the application runs full-screen.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
Program the application to return TRUE if the device settings are acceptable. If not, the application should return FALSE.Remarks
This function's parameters describe a set of unique valid device settings that could be used to create a device. The
application can examine and reject this set if desired.All possible unique valid combinations of the following device settings are sent to this callback function:pCapsAdapterFormatBackBufferFormatbWindowedAfter the application rejects the unwanted device settings combinations, DXUT picks the best of the remaining combinations and
uses that best combination to create the device. Before creating the device, DXUT calls LPDXUTCALLBACKMODIFYDEVICESETTINGS to
allow the application to change any of the device creation settings.应用程序可以使用这个回调函数拒绝任何硬件不支持或不想要的组合。例如,应用程序可以使用下列代码拒绝16位后台缓冲区格式以及所有至少
不支持像素渲染2.0版本的设备:bool CALLBACK IsD3D9DeviceAcceptable(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
bool bWindowed, void* pUserContext)
{   if(pCaps->PixelShaderVersion < D3DPS_VERSION(2, 0))       return false;if(BackBufferFormat == D3DFMT_X1R5G5B5 || BackBufferFormat == D3DFMT_R5G6B5)       return false;return true;
}
*/    DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
/*知识点9:修改可用的设备
---------------------------------------------
来自<<DXUT框架剖析(5)>>
---------------------------------------------
应用程序可以通过DXUTSetCallbackDeviceChanging()设置回调函数来修改Direct3D设备的创建设置:Sets a callback function that allow the application to change the device settings before the device is created.
VOID DXUTSetCallbackDeviceChanging(LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings,void* pUserContext
)Parameters
pCallbackModifyDeviceSettings
[in] Pointer to a LPDXUTCALLBACKMODIFYDEVICESETTINGS callback function. If the callback function is supplied, it will be called
before the Direct3D device is created. If NULL, DXUT will not notify the application about device changes.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
No return value.Remarks
Before a device is created by DXUT, the LPDXUTCALLBACKMODIFYDEVICESETTINGS callback will be called to allow the application to
examine or change the device settings before the device is created. This allows an application to modify the device creation
settings as it sees fit.This callback also allows applications to reject changing the device altogether. Returning false from inside this callback will
notify DXUT to keep using the current device instead of changing to the new device.-------------------------------------
Application-defined callback function, called by DXUT to allow changes in device settings before the device is created.bool LPDXUTCALLBACKMODIFYDEVICESETTINGS(DXUTDeviceSettings * pDeviceSettings,void* pUserContext
)Parameters
pDeviceSettings
[in] Pointer to a DXUTDeviceSettings structure that contains the settings for the new device.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
Program the application to return true to continue creating the device. If not, the application should return false to continue
using the current device if one exists.Remarks
Before a device is created by DXUT, the LPDXUTCALLBACKMODIFYDEVICESETTINGS callback will be called to allow the application to
examine or change the device settings before the device is created. This allows an application to modify the device creation
settings as it sees fit.This callback also allows applications to reject changing the device altogether. Returning false from inside this callback will
notify DXUT to keep using the current device instead of changing to the new device.Anything in pDeviceSettings can be changed by the application. DXUT will not prevent the failure of device creation caused by
changes to device settings.---------------------------------------------
DXUTDeviceSettings
A union of settings describing how to create the Direct3D 9 or Direct3D 10 device.
typedef struct DXUTDeviceSettings {DXUTDeviceVersion ver;union {DXUTD3D9DeviceSettings d3d9;DXUTD3D10DeviceSettings d3d10;};
} DXUTDeviceSettings, *LPDXUTDeviceSettings;Members
ver
Indicates whether the settings structure is for a Direct3D 9 or Direct3D 10 device.
d3d9
Device settings for Direct3D 9 device. Only valid if ver is DXUT_D3D9_DEVICE.
d3d10
Device settings for Direct3D 10 device. Only valid if ver is DXUT_D3D10_DEVICE.
Remarks
The DXUTDeviceSettings can only describe a single device because the DXUTD3D9DeviceSettings and DXUTD3D10DeviceSettings member
variables are unioned together. The DXUTDeviceVersion indicates which of these structures is valid.
--------------------------------------
DXUTD3D9DeviceSettingsDescribes the settings used to create a Direct3D 9 device.typedef struct DXUTD3D9DeviceSettings {UINT AdapterOrdinal;D3DDEVTYPE DeviceType;D3DFORMAT AdapterFormat;DWORD BehaviorFlags;D3DPRESENT_PARAMETERS pp;
} DXUTD3D9DeviceSettings, *LPDXUTD3D9DeviceSettings;Members
AdapterOrdinal
Ordinal number that denotes the display adapter.
DeviceType
Enumerated type of the device.
AdapterFormat
Adapter surface format.
BehaviorFlags
Behavior flags. This member can be a combination of one or more of the D3DCREATE values.
pp
Presentation parameters structure. DXUT fills this structure with valid values, and then passes the structure to the callback function where the application can
modify it. Be sure to validate any changes your application makes in this callback function. Here is an example that changes
the depth-stencil format.
bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings,void* pUserContext)
{    if( pDeviceSettings->ver == DXUT_D3D9_DEVICE )    {        IDirect3D9* pD3D = DXUTGetD3DObject();     if( SUCCEEDED( pD3D->CheckDeviceFormat(pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType,pDeviceSettings->d3d9.AdapterFormat, D3DUSAGE_DEPTHSTENCIL,D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) ){            if( SUCCEEDED( pD3D->CheckDepthStencilMatch(pDeviceSettings->d3d9.AdapterOrdinal, pDeviceSettings->d3d9.DeviceType,              pDeviceSettings->d3d9.AdapterFormat, pDeviceSettings->d3d9.pp.BackBufferFormat,D3DFMT_D24S8 ) ) )         {               pDeviceSettings->d3d9.pp.AutoDepthStencilFormat = D3DFMT_D24S8;       }      }   }     return true;
}回调函数ModifyDeviceSettings()返回一个布尔值,如果应用程序返回TRUE,DXUT框架继续像在正常情况下那样进行设备创建。如果返回FALSE,
框架不能改变设备,如果已有一个设备,则继续使用当前设备。如果框架提出的请求是改变到一个应用程序不能使用的设备,应用程序可以拒绝
该请求。例如,在一个多显示器配置中,默认情况下在显示器之间拖动窗口将使框架改变设备。但如果应用程序不能使用其他设备,它就必须拒
绝这种改变并继续使用当前设备。再举一例:降级到软件顶点处理Be careful if your hardware supports pixel processing (transforms and lighting) but does not support vertex processing.
One common mistake is to reject devices based on the vertex shader version in the (LPDXUTCALLBACKISD3D9DEVICEACCEPTABLE or
LPDXUTCALLBACKISD3D10DEVICEACCEPTABLE) callback functions. The correct solution is to implement the checking in the
ModifyDeviceSettings callback function as shown here.bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings,void* pUserContext )
{  if( pDeviceSettings->ver == DXUT_D3D9_DEVICE )   {      D3DCAPS9 caps;    DXUTGetD3D9DeviceCaps( pDeviceSettings, &caps ); // If device doesn't support HW T&L or doesn't support 1.1 vertex // shaders in HW, then switch to SWVP.      if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 || pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) ) {           pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; }           else    {        pDeviceSettings->d3d9.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING;  }  }    return true;
}*/DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );/*知识点1:第一阶段:启动
---------------------------------------------
来自<<DXUT框架剖析(1)>> 1
---------------------------------------------DXUT框架依次执行IsD3D9DeviceAcceptable()、ModifyDeviceSettings()、OnD3D9CreateDevice()、OnD3D9ResetDevice()这4个函数。在创建某个Direct3D渲染设备之前,如果需要对渲染设备的特征进行检查,查看设备是否支持需要的功能,可将检查代码写在函数
IsD3D9DeviceAcceptable()中。在某个渲染设备创建之前,如果需要修改该渲染设备的设置,可将代码写在函数ModifyDeviceSettings()中。DXUT框架接下来就根据
设置(或者是默认设置)创建最适合当前硬件的Direct3D渲染设备。例如,当硬件不支持某些功能时,可以通过使用参考设备进行模拟,
设置使用参考设备代码通常写在该函数中。DXUT框架创建了Direct3D设备之后,接下来会调用OnD3D9CreateDevice()回调函数,可在OnD3D9CreateDevice()回调函数中创建所有
内存池类型为D3DPOOL_MANAGED或D3DPOOL_SYSTEMMEM的资源。以类型D3DPOOL_MANAGED创建的设备由Direct3D系统代替管理(位于显存
或系统内存中),以类型D3DPOOL_SYSTEMMEM创建的设备位于系统内存中,在程序退出之前,这些资源常驻内存,不会出现设备丢失的
现象。也就是说,以这两种内存类型创建的资源不需要程序员进行管理。DXUT框架在调用OnD3D9CreateDevice()回调函数之后,将调用OnD3D9ResetDevice()回调函数。我们可在函数OnD3D9ResetDevice()中创
建所有内存池类型为D3DPOOL_DEFAULT的资源,这一类资源将尽可能存放在显存中,这样可以提高程序的运行速度。但是,这类资源在
程序运行时会出现设备丢失的现象(lost device:monitor resolution change,user locked and unlocked the OS,etc),因此需要程
序员自己管理。在设备丢失时释放它的内存,当设备恢复时重新为它分配内存。此外,观察变换矩阵和投影变换矩阵以及在整个程序运
行期间保持不变的渲染状态通常也在该回调函数中设置。如果性能不是很重要,使用D3DPOOL_MANAGED内存类型资源永远是一种安全的选择。*//*知识点2:Memory Pools---------------------------------------------
来自龙书P41
---------------------------------------------
1.3.4 Memory Pools
Surfaces and other Direct3D resources can be placed in a variety of
memory pools. The memory pool is specified by one of the members of
the D3DPOOL enumerated type. The memory pools available are:D3DPOOL_DEFAULT—The default memory pool instructs
Direct3D to place the resource in the memory that is best suited
for the resource type and its usage. This may be video memory,
AGP memory, or system memory. Note that resources in the
default pool must be destroyed (released) prior to an IDirect-
3DDevice9::Reset call, and must be reinitialized after the reset
call.D3DPOOL_MANAGED—Resources placed in the manage pool are
managed by Direct3D (that is, they are moved to video or AGP
memory as needed by the device automatically). In addition, a
back-up copy of the resource is maintained in system memory.
When resources are accessed and changed by the application, they
work with the system copy. Then, Direct3D automatically updates
them to video memory as needed.D3DPOOL_SYSTEMMEM—Specifies that the resource be placed in
system memoryD3DPOOL_SCRATCH—Specifies that the resource be placed in system
memory. The difference between this pool and D3DPOOL_
SYSTEMMEM is that these resources must not follow the graphics
device’s restrictions. Consequently, the device cannot access
resources in this pool. But the resources can be copied to and from
each other.
*/    DXUTSetCallbackMsgProc( MsgProc );DXUTSetCallbackFrameMove( OnFrameMove );DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );
/*知识点3:第二阶段:运行---------------------------------------------
来自<<DXUT框架剖析(1)>>
---------------------------------------------
DXUT框架调用回调函数MsgProc()处理各类消息,并在空闲时间反复调用OnFrameMove()和OnFrameRender()两个函数进行场景渲染。在每一帧中,程序为实现对场景的刷新,为用户输入的响应而编写的代码通常写在函数OnFrameMove()中,例如设置世界变换矩阵实现
物体的运动,它相当于“update”的性质,真正进行渲染的代码写在函数OnFrameRender()中。需要说明的是,在应用程序运行期间,当Direct3D设备变为丢失状态时,DXUT框架会调用OnD3D9LostDevice()函数,释放所有在回调
函数OnD3D9ResetDevice()中创建的设备资源。也就是说,这时释放的资源都是D3DPOOL_DEFAULT类型的。当Direct3D设备从丢失状态
恢复时,DXUT框架会调用回调函数OnD3D9ResetDevice()重新创建所有类型为D3DPOOL_DEFAULT的资源。也就是说,在程序运行时,如
果出现设备丢失现象,OnD3D9LostDevice()和OnD3D9ResetDevice()这一对函数就需要分别调用一次。
*/    /*知识点4:第三阶段:退出---------------------------------------------
来自<<DXUT框架剖析(1)>>
---------------------------------------------
在退出程序时,DXUT框架会依次调用OnD3D9LostDevice()和OnD3D9DestroyDevice()回调函数,在函数OnD3D9LostDevice()中释放由函数
OnD3D9ResetDevice()创建的资源,在函数OnD3D9DestroyDevice()中释放由函数OnD3D9CreateDevice()创建的资源。*/   /*知识点11:处理事件---------------------------------------------
来自<<DXUT框架剖析(6,7)>>
---------------------------------------------
框架使用回调函数机制来使应用程序对事件做出反应。应用程序只需对框架注册和设置相应的函数指针,则当事件发生时,框架就会调用相应的
函数。框架不需要注册所有的回调函数,所以应用程序只须对所需要的回调函数进行注册即可。通过为回调函数设置参数pUserContext,回调函
数可以从应用程序接受内容,比如将该参数设置为一个指向类对象的指针。DXUT框架可以处理以下事件类型:
(1)设备事件 当应用程序使用Direct3D设备渲染图形时,该设备有可能处于丢失状态。这种情况的发生有多种原因,例如按下Alt + Tab键离开一个全屏模式
的应用程序,或者按下Ctrl + Alt + Del键,或者启动了另一个全屏3D应用程序。发生这种情况时,当调用一些函数(如Present)时,Direct3D
API通过返回D3DERR_DEVICELOST通知应用程序设备丢失。当设备丢失时,应用程序负责释放所有不能在设备丢失时存在的Direct3D资源对象,如在D3DPOOL_DEFAULT内存池中创建的对象。如果没有释放这
些对象,那么该设备从丢失状态返回时就不能被重新设置。当设备丢失时,应用程序必须等待。当设备返回时,应用程序必须调用函数
IDirect3DDevice9::Reset(),并重新创建所有不能在Reset()函数中存在的对象。通过DXUT框架,这个过程可以通过在应用程序中使用回调函数来简化,这些回调函数处理各种设备事件:设备改变、创建、重新设置、丢失或
销毁。当设备丢失时,框架会有提示;当它从丢失状态返回时,框架会适当调用相应的回调函数,重新设置该设备,即框架使用应用程序的回调
函数在适当的时间释放和重新创建设备对象。应用程序需要做的是注册并实现相关回调函数,各回调函数的类型、注册、调用时机等细节见下表:注册函数
应用程序回调函数
框架调用时机
创建资源
释放资源  DXUTSetCallbackDeviceChanging
LPDXUTCALLBACKMODIFYDEVICESETTINGS
在创建Direct3D设备之前调用,应用程序可以返回FALSE,拒绝改变该设备。
x
xDXUTSetCallbackD3D9DeviceCreated
LPDXUTCALLBACKD3D9DEVICECREATED
当应用程序初始化和重新创建设备时,在Direct3D设备创建之后立即调用。
创建D3DPOOL_MANAGED资源,因为这些资源无论什么时候被销毁都需要重新加载,但这些资源被重新设置时不需要重新加载。在这里创建的资源
需要在LPDXUTCALLBACK-DEVICEDESTROYED中释放。
x DXUTSetCallbackD3D9DeviceReset
LPDXUTCALLBACKD3D9DEVICERESET
当Direct3D设备丢失又被重新设置后立即调用。
创建D3DPOOL_DEFAULT资源,因为这些资源无论什么时候丢失或重新设置时都需要重新加载,在这里创建的资源需要在
LPDXUTCALLBACK-DEVICELOST中释放。
x DXUTSetCallbackD3D9DeviceLost
LPDXUTCALLBACKD3D9DEVICELOST
当Direct3D设备变为丢失状态且在Reset调用之前,立即调用。
x
释放在回调函数LPDXUTCALLBACK-D3D9DEVICERESET中创建的资源,这些资源通常包括所有的D3DPOOL_DEFAULT资源。 DXUTSetCallbackD3D9DeviceDestroyed
LPDXUTCALLBACKD3D9DEVICEDESTROYED
当应用程序终止或重新创建设备时,Direct3D设备被销毁后,立即调用。
x
释放在回调函数LPDXUTCALLBACKD3D9DEVICECREATED中创建的资源,这些资源通常包括所有的D3DPOOL_MANAGED资源。 当设备在窗口和全屏模式间切换时常常需要重新设置,但有时它必须通过Direct3D重新创建。调用这些回调函数是可选的,但如果应用程序没有使用函数DXUTSetCallbackD3D9DeviceDestroyed()和 DXUTSetCallbackD3D9DeviceCreated()
注册销毁回调函数和创建回调函数,则改变设备或在硬件抽象层设备和参考设备间切换都不能进行。类似地,如果没有用函数DXUTSetCallbackD3D9DeviceLost()和 DXUTSetCallbackD3D9DeviceReset()注册丢失回调函数和重置回调函数,
则当设备丢失或重置设备时,框架无法通知应用程序。这样一来,所有不在D3DPOOL_MANAGED内存中的设备对象都不能重新设置。(2)帧事件 框架也提供了帧事件,它在渲染过程中的每一帧被调用,应用程序应该注册并实现这些回调函数,如下表所示:应用程序回调函数
注册回调函数
框架调用时机
场景渲染
LPDXUTCALLBACKFRAMEMOVE
DXUTSetCallbackFrameMove
在每一帧开始时调用一次
这个回调函数是应用程序处理场景更新的最好位置,但它不应包括实际的渲染调用,渲染调用应放在帧渲染回调函数中。LPDXUTCALLBACKD3D9FRAMERENDER
DXUTSetCallbackD3D9FrameRender
在每一帧结束或窗口需要重画时调用
所有对场景的渲染调用都应在此回调函数中完成,在这个回调函数返回后,框架将调用Present()来显示交换链中下一缓冲区的内容。
DXUTSetCallbackFrameMove Sets the frame update callback function.VOID DXUTSetCallbackFrameMove(LPDXUTCALLBACKFRAMEMOVE pCallbackFrameMove,void* pUserContext
)Parameters
pCallbackFrameMove
[in] Pointer to a LPDXUTCALLBACKFRAMEMOVE callback function. If the callback function is supplied, it will be called at the
beginning of every frame to facilitate updates to the scene. If NULL, DXUT will not notify the application about new frames.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
No return value.Remarks
The LPDXUTCALLBACKFRAMEMOVE callback function is the appropriate location for the application to handle updates to the scene.
However, LPDXUTCALLBACKFRAMEMOVE is not intended to contain actual rendering calls, which should instead be placed in the
LPDXUTCALLBACKD3D9FRAMERENDER or LPDXUTCALLBACKD3D10FRAMERENDER callback function. These callbacks is called when rendering
with either Direct3D 9 or Direct3D 10 respectively.The LPDXUTCALLBACKFRAMEMOVE callback function will be called once per frame, while the render callback function will be called
whenever the scene needs to be rendered, which might be more than once per frame on rare occasion if a WM_PAINT message occurs.-------------------------------------------------------------------------------------------------------------------------
LPDXUTCALLBACKFRAMEMOVE Application-defined callback function that allows for updating the scene. This function is called by DXUT once each frame, before the application renders the scene.VOID LPDXUTCALLBACKFRAMEMOVE(DOUBLE fTime,FLOAT fElapsedTime,void* pUserContext
)Parameters
fTime
[in] Time elapsed since the application started, in seconds.
fElapsedTime
[in] Time elapsed since the last frame, in seconds.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
No return value.Remarks
The LPDXUTCALLBACKFRAMEMOVE callback function is the appropriate location for the application to handle updates to the scene.
However, LPDXUTCALLBACKFRAMEMOVE is not intended to contain actual rendering calls, which should instead be placed in the
LPDXUTCALLBACKD3D9FRAMERENDER or LPDXUTCALLBACKD3D10FRAMERENDER callback function. These callbacks is called when rendering
with either Direct3D 9 or Direct3D 10 respectively.The LPDXUTCALLBACKFRAMEMOVE callback function will be called once per frame, while the render callback function will be called
whenever the scene needs to be rendered, which might be more than once per frame on rare occasion if a WM_PAINT message occurs.
----------------------------------------------------------------------------------------------------
DXUTSetCallbackD3D9FrameRender Sets the Direct3D 9 frame render callback function.VOID DXUTSetCallbackD3D9FrameRender(LPDXUTCALLBACKD3D9FRAMERENDER pCallback,void* pUserContext
)Parameters
pCallback
[in] Pointer to a LPDXUTCALLBACKD3D9FRAMERENDER callback function. If the callback function is supplied, it will be called once
per frame for the application to render the current scene using the Direct3D 9 device. If NULL, DXUT will not prompt the
application to render the scene.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
No return value.Remarks
This function only needs to be called if the application supports rendering with Direct3D 9 device.The LPDXUTCALLBACKD3D9FRAMERENDER callback function is the appropriate location for the application to render the current scene
using the Direct3D 9 device. The LPDXUTCALLBACKFRAMEMOVE callback function will be called once per frame, while
LPDXUTCALLBACKD3D9FRAMERENDER will be called when the scene needs to be rendered, which might be more than once per frame.---------------------------------------------------------------------------------
LPDXUTCALLBACKD3D9FRAMERENDER Application-defined callback function that allows for rendering the scene using a Direct3D 9 device. This function is called by DXUT at the end of every frame, and whenever the application needs to paint the scene.VOID LPDXUTCALLBACKD3D9FRAMERENDER(IDirect3DDevice9 * pd3dDevice,DOUBLE fTime,FLOAT fElapsedTime,void* pUserContext
)Parameters
pd3dDevice
[in] Pointer to the Direct3D 9 device used for rendering.
fTime
[in] Time elapsed since the application started, in seconds.
fElapsedTime
[in] Time elapsed since the last frame, in seconds.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
No return value.Remarks
The LPDXUTCALLBACKD3D9FRAMERENDER callback function is the appropriate location for the application to render the current
scene using the Direct3D 9 device. The LPDXUTCALLBACKFRAMEMOVE callback function will be called once per frame, while
LPDXUTCALLBACKD3D9FRAMERENDER will be called when the scene needs to be rendered, which might be more than once per frame.DXUT will call this function after the LPDXUTCALLBACKFRAMEMOVE callback function.-------------------------------------------------------------------------在函数 LPDXUTCALLBACKFRAMEMOVE 中,通常进行数据变换,比如设置坐标变换矩阵。在函数 LPDXUTCALLBACKD3D9FRAMERENDER 中,
主要进行图形的渲染.(3)消息事件 框架通过下表中的回调函数和相应的注册函数来传递窗口消息、键盘事件和鼠标事件,编写应用程序对这些事件做出适当反应。应用程序回调函数                 注册回调函数                          描述
LPDXUTCALLBACKMSGPROC           DXUTSetCallbackMsgProc          处理来自DXUT消息泵的窗口消息
LPDXUTCALLBACKKEYBOARD          DXUTSetCallbackKeyboard         处理来自DXUT消息泵的键盘事件
LPDXUTCALLBACKMOUSE             DXUTSetCallbackMouse            处理来自DXUT消息泵的鼠标事件 DXUTSetCallbackKeyboard Sets the keyboard event callback function.VOID DXUTSetCallbackKeyboard(LPDXUTCALLBACKKEYBOARD pCallbackKeyboard,void* pUserContext
)Parameters
pCallbackKeyboard
[in] Pointer to a LPDXUTCALLBACKKEYBOARD keyboard event callback function. If supplied, the callback function will be called
for keyboard events. If NULL, DXUT will not notify the application about keyboard events.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
No return value.Remarks
The pCallbackKeyboard keyboard event callback function will be called when any keyboard event occurs.This callback mechanism is provided to simplify handling keyboard messages through the windows message pump, but does not
preclude the application from handling those messages directly through the LPDXUTCALLBACKMSGPROC callback.------------------------------------------------------------------
LPDXUTCALLBACKKEYBOARD Application-defined keyboard event callback function, called by DXUT.VOID LPDXUTCALLBACKKEYBOARD(UINT nChar,bool bKeyDown,bool bAltDown,void* pUserContext
)Parameters
nChar
[in] A virtual-key code for the key. See Virtual-Key Codes for a listing.
bKeyDown
[in] TRUE if key is down. FALSE if the key is up
bAltDown
[in] TRUE if the ALT key is also down.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
No return value.Remarks
The pCallbackKeyboard keyboard event callback function will be called when any keyboard event occurs.This callback mechanism is provided to simplify handling keyboard messages through the windows message pump, but does not
preclude the application from handling those messages directly through the LPDXUTCALLBACKMSGPROC callback.---------------------------------------------------------------------------------------------------------DXUTSetCallbackMouse
Sets the mouse event callback function.VOID DXUTSetCallbackMouse(LPDXUTCALLBACKMOUSE pCallbackMouse,BOOL bIncludeMouseMove,void* pUserContext
)Parameters
pCallbackMouse
[in] Pointer to an LPDXUTCALLBACKMOUSE mouse event callback function. If supplied, the callback function will be called for
mouse events. If NULL, DXUT will not notify the application about mouse events.
bIncludeMouseMove
[in] If TRUE, the mouse movement events are passed to the pCallbackMouse callback function. Default value is FALSE.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
No return value.Remarks
The pCallbackMouse mouse event callback function will be called when any mouse events occursThis callback mechanism is provided to simplify handling mouse messages through the Windows message pump, but does not
preclude the application from handling those messages directly in the LPDXUTCALLBACKMSGPROC callback function.
------------------------------------------------------------------------------
LPDXUTCALLBACKMOUSE Application-defined mouse event callback function, called by DXUT when it receives mouse events.VOID LPDXUTCALLBACKMOUSE(bool bLeftButtonDown,bool bRightButtonDown,bool bMiddleButtonDown,bool bSideButton1Down,bool bSideButton2Down,INT nMouseWheelDelta,INT xPos,INT yPos,void* pUserContext
)Parameters
bLeftButtonDown
[in] The left mouse button is down.
bRightButtonDown
[in] The right mouse button is down.
bMiddleButtonDown
[in] The middle mouse button is down.
bSideButton1Down
[in] Windows 2000/Windows XP: The first side button is down.
bSideButton2Down
[in] Windows 2000/Windows XP: The second side button is down.
nMouseWheelDelta
[in] The distance and direction the mouse wheel has rolled, expressed in multiples or divisions of WHEEL_DELTA, which is 120.
A positive value indicates that the wheel was rotated forward, away from the user; a negative value indicates that the wheel
was rotated backward, toward the user.
xPos
[in] x-coordinate of the pointer, relative to the upper-left corner of the client area.
yPos
[in] y-coordinate of the pointer, relative to the upper-left corner of the client area.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
No return value.Remarks
The pCallbackMouse mouse event callback function will be called when any mouse events occursThis callback mechanism is provided to simplify handling mouse messages through the Windows message pump, but does not preclude
the application from handling those messages directly in the LPDXUTCALLBACKMSGPROC callback function*/    // TODO: Perform any application-level initialization here// Initialize DXUT and create the desired Win32 window and Direct3D device for the applicationDXUTInit( true, true ); // Parse the command line and show msgboxes
/*知识点5:初始化DXUT ---------------------------------------------
来自<<DXUT框架剖析(3)>>
---------------------------------------------
使用DXUT框架之前,首先需要初始化DXUT,初始化DXUT可以通过函数DXUTInit()完成:
HRESULT DXUTInit(    BOOL   bParseCommandLine  ,    BOOL   bShowMsgBoxOnError  ,    WCHAR *   strExtraCommandLineParams  ,    bool   bThreadSafeDXUT
) ;
ParametersbParseCommandLine [in] If TRUE, DXUT checks for command-line arguments. The application performs the following actions based upon the
entered command-line arguments. Command-line    Action
Argument
-forceapi:#     Forces the application to use the specified Direct3D API version. Fails if the application doesn't support this API or if no device is found.  -adapter:#       Forces the application to use this adapter ordinal. Fails if the adapter ordinal does not exist. -output:#      Applies to Direct3D 10 only. Forces the application to use a particular output on the adapter. Fails if the output does not exist.  -windowed       Forces the application to start in windowed mode.  -fullscreen      Forces the application to start in full-screen mode.  -forcehal     Forces the application to use a HAL device type. Fails if a HAL device does not exist.  -forceref       Forces the application to use a reference device type. Fails if a reference device does not exist.  -forcehwvp      Applies to Direct3D 9 only. Forces the application to use hardware vertex processing. Fails if the device does not support this mode.  -forcepurehwvp  Applies to Direct3D 9 only. Forces the application to use pure hardware vertex processing. Fails if the devicedoes not support this mode.  -forceswvp        Applies to Direct3D 9 only. Forces the application to use software vertex processing.  -forcevsync:#    If # is 0, then vertical sync is disabled. Otherwise, it is enabled. -width:#       Forces the application to use the window width #. For full-screen mode, DXUT picks the closest possible supported mode.  -height:#      Forces the application to use the window height #. For full-screen mode, DXUT picks the closest possible supported mode.  -startx:#     For windowed mode, forces the application to use the x-coordinate of the window position to the value of #. -starty:#       For windowed mode, forces the application to use the y-coordinate of the window position to the value of #. -constantframetime  Forces the application to into a mode where DXUT reports that a constant amount of time has passed betweeneach frame, where # is the time/frame in seconds. This is useful for such scenarios as rendering an movie that can not render in real time  -quitafterframe:# Forces the application to quit after frame #.  -noerrormsgboxes Prevents the display of message boxes generated by DXUT, allowing the application to be run without user interaction.  -nostats     Prevents the display of device and frame statistics by always returning blank strings for DXUTGetDeviceStatsand DXUTGetFrameStats.  -automation     This is a simple hint to other components that automation is active. The DXUT GUI uses this to enable UI navigation with keyboard by default.  Return Values
If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the error codes in
DXUTERR.Remarks
If this function has not been called before DXUTCreateWindow or DXUTSetWindow, DXUT will automatically call this function using
the default parameter values.通常在WinMain()函数中调用DXUTInit()函数进行DXUT初始化工作,如果程序员没有调用DXUTInit()函数,则DXUT框架会自动使用默认参数调用
该函数。如果第一个参数 bParseCommandLine 设置为TRUE,则DXUT框架就会使用命令行参数,例如通过下面的命令运行上面的chap1_dx9_2008.exe:chap1_dx9_2008.exe -windowed -width:1024 -height:768DXUT框架会尽量使用上面命令行中设置的窗口宽度和高度。注意:在VS2008中,可以通过 项目->属性->配置属性->调试->命令参数 向程序传入参数在这里我们只需填入:-windowed -width:1024 -height:768*/   DXUTCreateWindow( L"chap1_dx9" );
/*知识点6:创建一个窗口
---------------------------------------------
来自<<DXUT框架剖析(3)>>
---------------------------------------------
在应用程序中使用Windows API函数创建窗口是一个比较复杂的过程,如果操作有误,就会导致bug。尽管这对于一个Direct3D程序员来说可能
并不起眼,但在每个应用程序中却都是必须的。而DXUT框架通过函数DXUTCreateWindow()简化了这个过程,该函数的声明如下:Creates the window for the application.HRESULT DXUTCreateWindow(CONST const WCHAR * strWindowTitle,HINSTANCE hInstance,HICON hIcon,HMENU hMenu,INT x,INT y
)Parameters
strWindowTitle
[in] Title bar caption for the window. The default value is L"Direct3D Window".
hInstance
[in] Handle of the application's instance, or NULL to retrieve the handle of the current module. The default value is NULL.
hIcon
[in] Handle to the application's icon, or NULL to use the first icon embedded in the application's executable. The default
value is NULL.
hMenu
[in] Handle to the application's menu resource, or NULL to indicate no menu. The default value is NULL.
x
[in] Horizontal coordinate of the window's upper left corner, in screen coordinates. Using a value of CW_USEDEFAULT allows
Windows to choose an appropriate location. The default value is CW_USEDEFAULT.
y
[in] Vertical coordinate of the window's upper left corner, in screen coordinates. Using a value of CW_USEDEFAULT allows
Windows to choose an appropriate location. The default value is CW_USEDEFAULT.
Return Values
If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the error codes in
DXUTERR.Remarks
This function creates a new window for the application; alternately, the application can handle window creation and pass the
desired window handle to DXUT by using the DXUTSetWindow function. If neither DXUTCreateWindow nor DXUTSetWindow has been
called before calling a device creation method, DXUT will call DXUTCreateWindow using the default parameter values.
The window width and height are set later using the device settings.All parameters are optional.If both x and y are CW_USEDEFAULT and a windowed non-primary Direct3D device is created, the window will automatically be moved
to the adapter's monitor to ensure maximum performance.DXUT框架创建的窗口的句柄可以通过DXUTGetHWND()函数来获取。如果应用程序要对上面创建的窗口消息做出反应,那么需要使用DXUTSetCallbackMsgProc()来设置一个窗口消息处理函数Sets the window message callback function.VOID DXUTSetCallbackMsgProc(    LPDXUTCALLBACKMSGPROC   pCallbackMsgProc  ,    void*   pUserContext  ) ;-----------------------------------------------Application-defined function that processes messages from DXUT message pump.LRESULT LPDXUTCALLBACKMSGPROC(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam,bool * pbNoFurtherProcessing,void* pUserContext
)Parameters
hWnd
[in] Handle to the window.
uMsg
[in] Specifies the message. See WindowProc for details.
wParam
[in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.
lParam
[in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.
pbNoFurtherProcessing
[out] If TRUE, prevents DXUT from further handling the message.
pUserContext
[in] Pointer to a user-defined value which is passed to the callback function. Typically used by an application to pass a
pointer to a data structure that provides context information for the callback function. The default value is NULL
Return Value
Returns zero if the function has processed window messages successfully; otherwise, returns a nonzero value.Remarks
This function and its parameters are similar to to the Windows WindowProc function.With the use of the pbNoFurtherProcessing parameter, the application can control DXUT's level of involvement in processing
window messages. If the application sets pbNoFurtherProcessing to TRUE in the call to LPDXUTCALLBACKMSGPROC, DXUT will not
process the message and will immediately return with the value returned by LPDXUTCALLBACKMSGPROC. If the application sets
pbNoFurtherProcessing to FALSE, DXUT will handle window management events.在这个回调函数中,因为所有的重要消息都被该框架处理了,所以应用程序可以无需对任何消息做出响应。如果想禁用DXUT框架的消息处理,
应用程序可以将 pbNoFurtherProcessing 设为TRUE。但是,使用这个设置时要格外小心,因为它有可能使框架不能正确运行。如果想要应用程序创建自己的窗口并同DXUT框架一起使用,那么可以创建一个窗口,然后使用函数DXUTSetWindow()为DXUT框架设置自己创建的
窗口,该函数声明如下:Sets a previously created window for use by DXUT.HRESULT DXUTSetWindow(HWND hWndFocus,HWND hWndDeviceFullScreen,HWND hWndDeviceWindowed,BOOL bHandleMessages
)Parameters
hWndFocus
[in] Handle of the Direct3D focus window. Must not be NULL.
hWndDeviceFullScreen
[in] Handle of the Direct3D device window when in full-screen mode. Must not be NULL.
hWndDeviceWindowed
[in] Handle of the Direct3D device window when in windowed mode. Must not be NULL.
bHandleMessages
[in] If TRUE, DXUT will handle and respond to messages for the window. If FALSE, DXUT will not handle messages for the window,
giving the application full responsibility for responding to messages. The default value is TRUE.
Return Values
If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the error codes in
DXUTERR.Remarks
This function relies on an existing window object created by the application. Alternately, the application can call
DXUTCreateWindow to have DXUT create a window. If neither DXUTCreateWindow nor DXUTSetWindow has been called before calling
a device creation method, DXUT will automatically call DXUTCreateWindow using the default parameter values.The same Window handle may be used for more than one parameter.这个函数使用了3个窗口句柄参数,但它们通常都设置为同一个窗口句柄。如果框架创建了窗口,窗口消息将被自动处理,而要让DXUT框架使用自己创建的窗口,除了为DXUT框架设置窗口之外,还需要向DXUT框架通知
窗口接收到的消息(仅当DXUTSetWindow函数中bHandleMessages为false时需要),才能使DXUT框架正常运行。应用程序可通过函数
DXUTStaticWndProc()将窗口消息从窗口回调函数WindowProc 的内部传递给框架,函数DXUTStaticWndProc()的声明如下:
Processes messages sent to a window.LRESULT_CALLBACK DXUTStaticWndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam
)Parameters
hWnd
[in] Handle to the window.
uMsg
[in] Specifies the message.
wParam
[in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.
lParam
[in] Specifies additional message information. The contents of this parameter depend on the value of the uMsg parameter.
Return Value
If the function has processed window messages successfully, returns zero; otherwise, returns a nonzero value.Remarks
This method does not normally need to be called. It is useful only when the application use DXUTSetWindow with bHandleMessages
set to FALSE but still wants DXUT to assist with handling Windows messages. If this is the case, this function can be called
from inside the application's window procedure, or it can be used directly as the window procedure.*/DXUTCreateDevice( true, 640, 480 );
/*知识点7:创建一个设备---------------------------------------------
来自<<DXUT框架剖析(4)>>
---------------------------------------------
通常可以用标准的Direct3D方法CreateDevice()创建一个Direct3D设备,这个方法需要一个有效的显示适配器、设备类型(硬件抽象层设备或参
考设备)、窗口句柄、运行标志(软件/硬件顶点运算模式和其他驱动标志)和提交参数。更重要的是,结构体 D3DPRESENT_PARAMETERS有许多
成员指定了后台缓冲区的设置、多重采样设置、交换效果、窗口模式、深度缓冲区设置、刷新频率、提交间隔和提交标志等。为所有的参数选择合适的设置是比较繁琐的,DXUT框架使用函数DXUTCreateDevice()简化了Direct3D设备的创建,该函数的声明如下:
HRESULT DXUTCreateDevice(bool bWindowed,INT nSuggestedWidth,INT nSuggestedHeight
)Parameters
bWindowed
[in] If TRUE, the application will start in windowed mode; if FALSE, the application will start in full-screen mode.
The default value is TRUE.
nSuggestedWidth
[in] The requested initial width of the application's back buffer. The actual width may be adjusted to fit device and
operating system constraints. The default value is 0.
nSuggestedHeight
[in] The requested initial height of the application's back buffer. The actual height may be adjusted to fit device and
operating system constraints. The default value is 0. If both nSuggestedWidth and nSuggestedHeight are zero, the dimension
of the client area of the window is used.
Return Value
If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the error codes
in DXUTERR.Remarks
This function creates a new Direct3D 9 or Direct3D 10 device for the application. DXUT will pick the best device for the
application based upon what is available on the system and which Direct3D API version(s) the application supports. The API
version(s) that the application supports is determined by which device callbacks are set. This logic can be overridden by
calling DXUTSetD3DVersionSupport. If both Direct3D 9 and Direct3D 10 are available on the system and both are supported by
the application, then DXUT will favor Direct3D 10.Alternately, the application can use the DXUTCreateDeviceFromSettings or handle device creation and pass the desired device to
DXUT by using the DXUTSetD3D9Device or DXUTSetD3D10Device function. If neither DXUTCreateDevice, DXUTCreateDeviceFromSettings,
nor DXUTSetD3D9Device or DXUTSetD3D10Device have been called before calling DXUTMainLoop, DXUT will automatically call
DXUTCreateDevice using the default parameter values.The application can call this method after a device has already been created to change the current device.If a device is successfully found, the LPDXUTCALLBACKMODIFYDEVICESETTINGS callback will be called to allow the application to
examine or change the device settings before the device is created. This allows an application to modify the device creation
settings as it sees fit.通过这个简单的调用,DXUT框架创建了一个使用默认设置的Direct3D设备,它可以在大多数情况下使用,默认的设备创建设置如下表所示:Direct3D创建标志                                     描述                  DXUTCreateDevice的默认值
函数CheckDeviceFormat()的参数AdapterFormat               适配器表面格式         当前桌面显示模式,如果桌面显示模式不足32位,则使用D3DFMT_X8R8G8B8 IDirect3D9::CreateDevice()的参数Adapter                    显示适配器编号         D3DADAPTER_DEFAULT D3DPRESENT_PARAMETERS.BackBufferCount                    后台缓冲区数目         2,表示有两个后台缓冲区,可实现3倍缓冲。 D3DPRESENT_PARAMETERS.BackBufferFormat                  后台缓冲区格式         桌面显示模式,如果桌面显示模式不足32位,则使用D3DFMT_X8R8G8B8 D3DPRESENT_PARAMETERS.AutoDepthStencilFormat          设备将自动创建的深度  如果后台缓冲区格式小于等于16位,模板表面的深度格式       则使用D3DFMT_D16,否则使用D3DFMT_D32。IDirect3D9::CreateDevice()函数的参数DeviceType           设备类型                若D3DDEVTYPE_HAL可行,则使用之,否则使用D3DDEVTYPE_REF,若二者均不可行,则创建失败。D3DPRESENT_PARAMETERS.MultiSampleQuality                多重采样数量          MultiSampleQuality = 0表示禁用多重采样 D3DPRESENT_PARAMETERS.Flags                              提交参数标志          D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL D3DPRESENT_PARAMETERS.PresentationInterval              提交间隔                窗口模式下为D3DPRESENT_INTERVAL_IMMEDIATE,全屏模式下为D3DPRESENT_INTERVAL_DEFAULT。 D3DPRESENT_PARAMETERS.FullScreen_RefreshRateInHz      显示适配器刷新频率       0,表示当前桌面设置的刷新频率。 D3DPRESENT_PARAMETERS.BackBufferWidth和BackBufferHeight 显示器分辨率           在窗口模式下为640 x 480,全屏模式下为桌面分辨率。 D3DPRESENT_PARAMETERS.SwapEffect                       交换效果                D3DSWAPEFFECT_DISCARD
IDirect3D9::CreateDevice()的参数BehaviorFlags          顶点运算标志          如果硬件支持,就使用D3DCREATE_HARDWARE_VERTEXPROCESSING,否则使用D3DCREATE_SOFTWARE_VERTEXPROCESSING。 D3DPRESENT_PARAMETERS.Windowed                         窗口模式或全屏模式       TRUE,表示窗口模式
IDirect3D9::CreateDevice()的参数hFocusWindow           创建窗口的句柄         DXUTSetWindow函数的参数hWndFocus
D3DPRESENT_PARAMETERS.hDeviceWindow                     设备窗口的句柄         DXUTSetWindow的参数hWndDeviceFullScreen或hWndDeviceWindowed D3DPRESENT_PARAMETERS.EnableAutoDepthStencil            深度模板缓冲区创建标志 TRUE,表示自动创建深度模板缓冲区 让我们对比下在DX中如何创建设备
HRESULT IDirect3D9::CreateDevice(
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS *pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface
);
我们可以发现它们是一一对应的
*/ DXUTSetHotkeyHandling( true, true, true );  // handle the default hotkeysDXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen// Start the render loopDXUTMainLoop();
/*知识点10:进入消息循环 ---------------------------------------------
来自<<DXUT框架剖析(6)>>
---------------------------------------------
在窗口和设备创建好之后,应用程序需要使用消息循环处理窗口消息、更新和渲染场景、处理设备事件。应用程序可以实现自己的消息循环,
也可以使用DXUT消息循环,注册相应的回调函数,可以让DXUT处理设备、帧消息事件。为使用DXUT框架的消息循环,可以调用DXUTMainLoop()函数:Starts the main execution loop of DXUT.HRESULT DXUTMainLoop(HACCEL hAccel
)Parameters
hAccel
[in] Handle to an accelerator table to use in translating keyboard messages from the Windows message queue, or NULL if not
using an accelerator table. The default value is NULL.
Return Value
If the function succeeds, the return value is S_OK. If the function fails, the return value can be one of the error codes
in DXUTERR.Remarks
This function starts the message loop that will run for the lifetime of the application. During execution, DXUTMainLoop
calls the registered callback functions to ask the application to update and render the frame, as well as handle any device
or input events.Custom Main Loop
For some advanced applications a custom main loop may be a better design. It is possible to use DXUT with a custom main loop.
An example of how to do this is shown below.INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT )
{  DXUTSetCallbackD3D9DeviceAcceptable( IsDeviceAcceptable );  DXUTSetCallbackD3D9DeviceCreated( OnCreateDevice );   DXUTSetCallbackD3D9DeviceReset( OnResetDevice );  DXUTSetCallbackD3D9FrameRender( OnFrameRender );  DXUTSetCallbackD3D9DeviceLost( OnLostDevice );    DXUTSetCallbackD3D9DeviceDestroyed( OnDestroyDevice ); DXUTSetCallbackMsgProc( MsgProc );   DXUTSetCallbackKeyboard( KeyboardProc );  DXUTSetCallbackFrameMove( OnFrameMove );   DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );  DXUTInit( true, true );    DXUTCreateWindow( L"Example" );  DXUTCreateDevice( true, 640, 480 );    // Custom main loop    HWND hWnd = DXUTGetHWND();//知识点12    BOOL bGotMsg;    MSG  msg;    msg.message = WM_NULL;   PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE ); while( WM_QUIT != msg.message  )   {    // Use PeekMessage() so we can use idle time to render the scene      bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );     if( bGotMsg )     {           // Translate and dispatch the message  if( 0 == TranslateAccelerator( hWnd, NULL, &msg ) )   {             TranslateMessage( &msg );     DispatchMessage( &msg );        }     }       else      {           // Render a frame during idle time (no messages are waiting) DXUTRender3DEnvironment();     }  }      return DXUTGetExitCode();
}
This example calls DXUTRender3DEnvironment to have DXUT update and render the scene and handle device events. While it is
possible for the application to completely replicate this functionality, it is not recommended.
-------------------------------------------
DXUTRender3DEnvironment
Renders the 3D environment.
VOID DXUTRender3DEnvironment()Return Value
No return value.Remarks
This method does not normally need to be called. It is useful only when the application does not use DXUTMainLoop but still
wants DXUT to assist with rendering.This method checks whether the device is lost. If so, the method attempts to reset the device and then calls the
LPDXUTCALLBACKFRAMEMOVE and LPDXUTCALLBACKD3D10FRAMERENDER callback functions.If the application window is minimized or the application is paused, CPU time is yielded to other processes.*/// TODO: Perform any application-level cleanup here
/*知识点12:允许改变DXUT行为和获取内部变量的函数---------------------------------------------
来自<<DXUT框架剖析(9,10,11,12)>>
---------------------------------------------
管理窗口的DXUT函数DXUTGetHINSTANCE         获取应用程序实例的句柄
DXUTGetHWND                 获取当前设备窗口的句柄
DXUTGetHWNDFocus            获取当前获得焦点的窗口的句柄
DXUTGetHWNDDeviceFullScreen 获取全屏模式设备窗口的句柄
DXUTGetHWNDDeviceWindowed   获取窗口模式设备窗口的句柄
DXUTGetWindowClientRect     获取应用程序设备窗口的客户区矩形
DXUTGetWindowTitle          获取指向应用程序窗口标题的指针
DXUTIsWindowed              检查应用程序是否处在窗口模式下 管理设备的DXUT函数DXUTSetCursorSettings        为全屏模式下光标的用法设置选项
DXUTSetMultimonSettings     为框架如何在多显示器配置中工作设置选项
DXUTToggleFullscreen        使应用程序在窗口模式和全屏模式间切换
DXUTToggleREF               使应用程序在硬件抽象层和参考设备间切换 管理DXUT框架的函数
DXUTResetFrameworkState     将框架状态重置为初始默认状态,之前设置的框架状态改变将失效。
DXUTShutdown                触发程序终止和清空框架
DXUTGetExitCode             获取框架的退出代码 检索Direct3D变量的函数
DXUTGetD3DObject                    获取一个指向IDirect3D9对象的指针
DXUTGetD3D9Device                   获取一个指向代表当前设备的IDirect3DDevice9接口指针
DXUTGetDeviceSettings               获取用来创建当前设备的结构体DXUTDeviceSettings
DXUTGetPresentParameters            获取当前设备的提交(presentation)参数
DXUTGetD3D9BackBufferSurfaceDesc    获取一个指向当前设备后台缓冲区表面的D3DSURFACE_DESC结构体的指针
DXUTGetD3D9DeviceCaps               获取一个指向当前设备的D3DCAPS9结构体的指针 DXUT统计函数 DXUTGetFPS               获取当前每秒提交的帧数
DXUTGetFrameStats       获取一个指向字符串的指针,该字符串包括每秒帧数、分辨率、后台缓冲区格式、深度缓冲区格式。
DXUTGetDeviceStats      获取一个指向字符串的指针,该字符串包括当前设备类型、顶点运算行为和设备名。 DXUT时间函数 DXUTGetTime                   获取当前时间(秒)
DXUTGetElapsedTime          获取从上一帧到当前帧所经过的时间
DXUTSetConstantFrameTime    启用或禁用固定帧时间 DXUT计时器函数DXUTSetTimer                添加一个新的计时器
DXUTKillTimer               卸载一个已有的计时器 DXUT暂停函数DXUTPause                    将框架的内部计数器和(或)渲染过程设为暂停状态
DXUTRenderingPaused         检查当前设备的渲染状态是否处在暂停状态
DXUTIsTimePaused            检查当前设备的计时器是否处在暂停状态 DXUT用户输入函数DXUTIsKeyDown 检查当该函数调用时,键盘上指定的某个键是否按下。
DXUTIsMouseButtonDown 检查当该函数调用时,指定的鼠标键是否按下。 */    return DXUTGetExitCode();
/*知识点13:DXUTGetExitCode---------------------------------------------
来自<<DXUT框架剖析(10)>>
---------------------------------------------Gets the DXUT exit code.INT DXUTGetExitCode()Return Value
Returns a DXUT exit code, which will be one of the possible values shown in the following table. Value      Description
0       Successful execution.
1       An undetermined error occurred.
2       Direct3D could not be initialized.
3       No Direct3D device could be found with the specified device settings.
4       The required media could not be found.
5       The Direct3D device has a non-zero reference count, meaning that some objects were not released.
6       An error occurred when attempting to create a Direct3D device.
7       An error occurred when attempting to reset a Direct3D device.
8       An error occurred in the device creation callback function.
9       An error occurred in the device reset callback function.
10      The last device used upon exit was a reference (REF) device type.
11      The device was removed.  Remarks
The return value of this function is typically used in the application as the return code of the application's WinMain
function. Command-line tests can then be performed on applications using this return code.The following is an example of command-line usage that uses DXUT exit code:start /wait BasicHLSL.exe
echo %errorlevel%*/}

一天搞定DXUT三步曲之一:DXUT框架相关推荐

  1. java 简单的调用类_java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊...

    java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊 java 调用 C# 类库搞定,可以调用任何类及方法,很简单,非常爽啊 总体分三步走: 一.准备一个 C# 类库 (d ...

  2. java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊...

    java 调用 C# 类库搞定,三步即可,可以调用任何类及方法,很简单,非常爽啊 java 调用 C# 类库搞定,可以调用任何类及方法,很简单,非常爽啊 总体分三步走: 一.准备一个 C# 类库 (d ...

  3. 一天搞定DXUT三步曲之二:添加文本

    添加文本比较简单,自己看源码吧,我就不多说了 //--------------------------------------------------------------------------- ...

  4. Membership三步曲之入门篇 - Membership基础示例

    Membership 三步曲之入门篇 - Membership基础示例 Membership三步曲之入门篇 -  Membership基础示例 Membership三步曲之进阶篇 -  深入剖析Pro ...

  5. 苹果 iOS 内购三步曲:App 内退款、历史订单查询、绑定用户防掉单

    ????????关注后回复 "进群" ,拉你进程序员交流群???????? 转自:掘金 37手游iOS技术运营团队 https://juejin.cn/post/697473339 ...

  6. 苹果iOS内购三步曲:App内退款、历史订单查询、绑定用户防掉单!--- WWDC21

    一.前言 如果大家的 App 有使用 IAP 功能,那么可能会遇到用户反馈苹果充值成功,但是服务没有到账的情况,用户一般会提供这样的苹果收据: 用户反馈时提供的苹果收据中,有一个字段中 ORDER I ...

  7. 软文营销流程三步曲,快速见效!

    软文营销的效果是最持久最快的,当天发当天见效,而且应用范围广泛,可以是吸粉,招商,卖产品,品牌推广,都可以用软文搞定.那小编今天就分享软文营销的三步曲,看完只要你马上操作,一周内,你会看到效果,对于懂 ...

  8. 软件测试职业发展三步曲之一

    软件测试职业发展三步曲之一    --软件测试职业发展方向          作者:叶赫华          天地玄黄,宇宙洪荒:所谓光阴似箭,因为一转眼滚滚的历史车轮就将人类文明推 进了二十一世纪的 ...

  9. 创凡PC120的系统安装三步曲

    创凡PC120的系统安装三步曲                            -------创造非凡的电脑急救       第一,如果是新电脑就先把硬盘分好区,一般分四个区.如果是旧电脑,就根 ...

最新文章

  1. 四十四、ETL工具的查询_连接和映射
  2. 51单片机有几个通用io口_51单片机IO口的四种使用方法
  3. asp网络编程:用ASP实现网页BBS
  4. Linux环境下安装单实例MySQL 5.7
  5. 开发者强势围观!Gartner 发布 2020 年十大战略科技发展趋势
  6. 如何使用 Java 调取 Python、R 的训练模型?
  7. Winfrom打印表单
  8. 分布式存储系统学习笔记(二)—分布式文件系统(2)—淘宝文件系统(TFS)
  9. DevOps使用教程 华为云(14)持续集成 流水线 自动化测试 怎么用
  10. OpenCV-图像处理(25、直方图比较)
  11. matlab简单仿真机器人
  12. DC工具的基本使用(一)
  13. 从猎豹移动到瑞幸咖啡,看中国企业在海外的信誉破产
  14. Claus Hansen加入Entrust Datacard,担任亚太地区和日本销售副总裁
  15. Tekla图纸二次开发课程
  16. uml具有多种视图_UML语言中五大视图
  17. Spring Cloud中的Eureka和Zookeeper的区别在哪?
  18. Xmind思维导图编写测试点,便于扩展测试用例(详细)
  19. 数据库基础及查询语句
  20. UnityShader应用——卡通渲染

热门文章

  1. QDebug输出彩色消息
  2. 利用QDataStream将大文件转化成二进制文件QBatyArray
  3. Qt线程间信号槽传递自定义数据类型(qRegisterMetaType的使用)
  4. C++类型转换方式总结
  5. UWP 颜色选择器(ColorPicker) 和 自定义的Flyout(AdvancedFlyout)
  6. 《深入理解并行编程》中文版
  7. 产品设计体会(6016)我是哪种用户(下)
  8. 判断Sbo的Matrix中是否存在相同数据行
  9. 宁德时代机器人编程开发_高通发布5G机器人开发平台,内置强大AI算力。各大厂商竞相发布机器人处理平台,万物互联的时代即将到来...
  10. 学业水平考试b能上985吗_这是最好考的985高校,如今被“降级”到双一流B类,真让人惋惜...