1、配置D3D11 设备
首要是创建三个对象: 设备,立即上下文,交换链;其中立即上下文是DX11新对象。
在DX10中,设备对象用作渲染和资源创建。在DX11中,立即上下文用作渲染,设备用作创建资源。
交换链负责将设备渲染后的BUFF,显示到实现显示器中。交换包含二到多个BUFF.
通过配置DXGI_SWAPCHAIN_DESC交换链描述,进而创建交换链;留意,BackBufferUsage是一个用于指示后台BUFF如何使用的。例如,如果我们想渲染到后台BUFF,因而我们指定为DXGI_USAGE_RENDER_TARGET_OUTPUT。 OutputWindow是用于指定,交换链将要把BUFF提交显示的窗口。SampleDesc用作启用多采样。
至此可以创建交换链如下了:
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;
}
接下来我们要做的事情是,创建渲染目标视图。在DX11中,渲染目标视图是一个中资源视图。资源视图允许将资源绑定到图形管线的某一级。试想资源视图作为一个类型C, 一块原始内存的C可以转换成任意类型,原内存数据本身并没有太大用处,DX11视图资源基本起类似作用。例如,2D贴图资源,也是对应于一原始内存块,我可以以这个资源创建不同的资源视图,以不同的格式来绑定贴图到不同的管线阶段,以及作为渲染目标,深度模板BUFF(接收深度信息),贴图资源。
我们需要创建一个渲染目标视图,我们通常绑定交换链的一个后台BUFF作为渲染目标。DX11就是在上面渲染。我们首先调用GetBuffer()来取得后台BUFF;亦或者,通过a D3D11_RENDERTARGETVIEW_DESC结构,来CreateRenderTargetView创建渲染目标,可以在指二个参数设为NULL,取得一个缺省的渲染目标。一旦我们有了目标视图,我们可以在立即上下文上调用OMSetRenderTargets来绑定到管线上,这样就确保了管线渲染输出写到了后台BUFF.
// Create a render target view 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 );
在DX11能渲染之前,我们初始化视口,视口图剪辑了空间坐标,X和Y坐标范围-1到1;Z坐标范围至0到1,渲染到目标空间(像素空间);在DX11中,没有缺省视口,在此我们设定左上(0,0)点,宽高等同渲染目标的尺寸。如下:
// Create a render target view 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 );
渲染代码:
在这里我们将渲染最简单的场景,用单色填充单色,在DX11中,一个用单色填充渲染目标方法就是,使用立即上下文的ClearRenderTargetView()函数。
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 ); }