由於內容有點多,而且本人是0基礎學習這個,所以寫博客來幫助記憶。
首先官方給的第一個例子提到了三個東西:
device(設備):創建資源
immediate context(直接上下文):應用程序使用直接上下文在緩衝區進行渲染
swap chain(交換鏈):獲取設備呈現的緩衝區,在屏幕上呈現內容
首先創建一個交換鏈,具體的參數信息看文檔。
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory( &sd, sizeof(sd) );
sd.BufferCount = 1;
sd.BufferDesc.Width = 640;
sd.BufferDesc.Height = 480;
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;
if( FAILED( D3D11CreateDeviceAndSwapChain( NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, NULL, &g_pImmediateContext ) ) )
{
return FALSE;
}
然後就是通過直接上下文去渲染視圖,首先通過GetBuffer獲取後臺緩衝區對象,再通過這個對象創建渲染目標視圖,再用OMSetRenderTargets將視圖綁定到管道。確保屏幕輸出的是後臺緩衝區.
ID3D11Texture2D *pBackBuffer;
if( FAILED( g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&pBackBuffer ) ) )
return FALSE;
hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
pBackBuffer->Release();
if( FAILED( hr ) )
return FALSE;
g_pImmediateContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );
然後就是初始化視口,視口用於輸出渲染目標。這裏設置左上角爲(0,0),然後寬和高跟渲染的大小相同。
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)width;
vp.Height = (FLOAT)height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pImmediateContext->RSSetViewports( 1, &vp );
然後是消息循環,通過peekmessage而不是getmeessage,前者非阻塞,後者阻塞,具體的區別看msdn文檔。
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render(); // Do some rendering
}
}
通過直接上下文進行渲染。
void Render()
{
//
// Clear the backbuffer
//
float ClearColor[4] = { 0.0f, 0.125f, 0.6f, 1.0f }; // RGBA
g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );
g_pSwapChain->Present( 0, 0 );
}