hain函数具有如下的函数原型:
[cpp]
HRESULT D3D11CreateDeviceAndSwapChain(
IDXGIAdapter *pAdapter,
D3D_DRIVER_TYPEDriverType,
HMODULE Software,
UINT Flags,
const D3D_FEATURE_LEVEL*pFeatureLevels,
UINT FeatureLevels,
UINT SDKVersion,
const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
IDXGISwapChain **ppSwapChain,
ID3D11Device **ppDevice,
D3D_FEATURE_LEVEL*pFeatureLevel,
ID3D11DeviceContext**ppImmediateContext
);
HRESULT D3D11CreateDeviceAndSwapChain(
IDXGIAdapter *pAdapter,
D3D_DRIVER_TYPEDriverType,
HMODULE Software,
UINT Flags,
const D3D_FEATURE_LEVEL*pFeatureLevels,
UINT FeatureLevels,
UINT SDKVersion,
const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
IDXGISwapChain **ppSwapChain,
ID3D11Device **ppDevice,
D3D_FEATURE_LEVEL*pFeatureLevel,
ID3D11DeviceContext**ppImmediateContext
);
四、 创建渲染目标视图
一个渲染目标视图是一个由Output MergerStage读取的D3D资源。为了output merger能渲染一个后台缓存的交换链,我们为其创建一个渲染目标视图。
由于纹理的概念说来话长,目前我们将纹理理解为一副图像就行了,后面中我们将展开讨论纹理的很多细节内容,。交换链的主缓存和辅助缓存为彩色的图像,为了获得它们的指针,我们一般会调用交换链中的函数GetBuffer。
得到指向缓存的指针后,我们调用Direct3D中的函数CreateRenderTargetView,来创建一个渲染目标视图(rendertarget view.)。渲染目标视图含有ID3D11RenderTargetView类型,而CreateRenderTargetView函数将创建我们视图的2D纹理,渲染目标描述,我们创建的ID3D11RenderTargetView的对象地址为其函数变量。将渲染目标描述变量设为空给我们所有的表面的MIP映射水平都为0级,MIP映射水平也将在后面进行详细讨论。
我们完成渲染目标的创建之后,就能够释放指针到交换链的后台缓存了。因为得到了COM对象的一个引用,我们必须调用COM中的Release函数来减少引用的数量。这样做会避免内存的泄露,因为我们不想应用程序退出后,系统仍然保留着这里内存,这将导致系统资源的浪费,而这种浪费是不科学的。
在每次我们想渲染一个特定的渲染目标的时候,必须在所有的绘制的函数调用之前对它进行设置。这个重任就交给了我们的OMSetRenderTarget函数,这个函数隶属于output merger,在之后会讲到。
代码段4 渲染目标视图的创建和绑定
[cpp]
ID3D11RenderTargetView* backBufferTarget_;
ID3D11Texture2D* backBufferTexture;
HRESULT result = swapChain_->GetBuffer( 0, __uuidof(ID3D11Texture2D ),
( LPVOID* )&backBufferTexture );
if( FAILED( result ) )
{
DXTRACE_MSG( "Failed to get the swap chain backbuffer!" );
return false;
}
result = d3dDevice_->CreateRenderTargetView(backBufferTexture, 0,
&backBufferTarget_ );
if( backBufferTexture )
backBufferTexture->Release( );
if( FAILED( result ) )
{
DXTRACE_MSG( "Failed to create the render targetview!" );
return false;
}
d3dContext_->OMSetRenderTargets( 1, &backBufferTarget_, 0);
ID3D11RenderTargetView* backBufferTarget_;
ID3D11Texture2D* backBufferTexture;
HRESULT result = swapChain_->GetBuffer( 0, __uuidof(ID3D11Texture2D ),
( LPVOID* )&backBufferTexture );
if( FAILED( result ) )
{
DXTRACE_MSG( "Failed to get the swap chain backbuffer!" );
return false;
}
result = d3dDevice_->CreateRenderTargetView(backBufferTexture, 0,
&backBufferTarget_ );
if( backBufferTexture )
backBufferTexture->Release( );
if( FAILED( result ) )
{
DXTRACE_MSG( "Failed to create the render targetview!" );
return false;
}
d3dContext_->OMSetRenderTargets( 1, &backBufferTarget_, 0);
在代码段4中你会注意到我们采用了一个叫做DXTRACE_MSG的宏。这个宏用作debugging来用。在之后将进行更详细的讲解。
五、 视口
Direct3D中 的一个重点同时也是难点在于创建和设置视口。
视口定义了我们渲染到屏幕上的面积。在单人或者非分割画面的多人游戏中一般都为全屏,所以我们设置视口的宽度和高度即为交换链的宽度和高度。对于分屏游戏,我们可以创建两个视口,一个视口定义在屏幕上方,另一个定义在屏幕下方。为了渲染分屏视口,我们可以分别以两位不同玩家的角度来渲染。
视点的创建由填充D3D11_VIEWPORT函数和设置调用上下文的RSSetViewports函数将其设置到渲染上下文中来完成。RSSetViewports函数需要我们设置的视口数量和视口对象的列举。全屏视口的创建和设置的相关代码在代码段五中有列举,其中X和Y标明左侧和顶部屏幕的位置,最小和最大深度是0到1之间的值,表明了视口深度的