一直埋头在DX SDK 9.0 的CD3DApplication中,最近抬起头来看一看,发现现在已经是DXUT框架的天下了。一开始想不明白为什么MS要改掉整个框架,原来的不是挺好么。大致看了看,发现DXUT对GUI的支持似乎好于更多些,而且不是party要求我们“与时俱进”么。今天开始学习DXUT,笔记下心得,备忘!学习的顺序基础是DX Sample Browser中的Tutorial。
Tutorial00为一个空的窗口程序,Tutorial01是一个仅创建空窗口和DX设备程序,其程序结构的区别如下
InitWindow()-->InitDevice()-->MessageLoop-->CleanupDevice()-->End
前者没有InitDevice和CleanupDevice两步。应注意以下几点
1.Tutorial01和Tutorial00中的消息循环不同:
(1)窗口程序的消息循环是
MSG msg = {0};
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
(2)DX程序的消息循环是
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}
即DX程序的消息循环用PeekMessage代替了GetMessage,同时利用系统空闲执行渲染函数Render(),使得程序的执行效率更高。
2.创建设备的步骤如下:
(1)准备DXGI_SWAP_CHAIN_DESC sd结构的数值
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory( &sd, sizeof(sd) );
sd.BufferCount = 1;
sd.BufferDesc.Width = width; // 窗口客户区的宽度
sd.BufferDesc.Height = height; // 窗口客户区的高度
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
(2)调用全局函数D3D10CreateDeviceAndSwapChain创建设备和交换链(?尚不明白交换链的含义,推测可能类似于前后缓冲区的交换),该函数的声明如下:
HRESULT D3D10CreateDeviceAndSwapChain( IDXGIAdapter* pAdaptor,
D3D10_DRIVER_TYPE DriverType, // 枚举类型,可以是D3D10_DRIVER_TYPE_HARDWARE或D3D10_DRIVER_TYPE_SOFTWARE
HMODULE Software,
UINT Flags,
UINT SDKVersion,
DXGI_SWAP_CHAIN_DESC* pSwapChain,
IDXGISwapChain** pSwapChain,
ID3D10Device** ppDevice);
(3)创建一个渲染的目标视图(Render target view)
ID3D10Texture2D* pBackBuffer;
gSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer);
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_pRenderTargetView); // ID3D10RenderTargetView* g_pRenderTargetView;
g_pd3dDevice->OMSetRenderTargets(1, &g_pRenderTargetView, NULL);
(4)设置视点
D3D10_VIEWPORT vp;
vp.Width = width;
vp.Height = height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pd3dDevice->RSSetViewports( 1, &vp );