D3D的初始化

翻译自Introduction.to.3D.Game.Programming.with.DirectX.10

D3D中,有点万物皆纹理的意思。z-buffer是纹理,frame-buffer也是纹理。纹理通常有两种用途,render target或者shader resource。分别对应以下的状态标志:

D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE

如果我们想要使用纹理,D3D要求我们在初始化时创建一个纹理的资源视图。将纹理用作render target,则需要创建ID3D10RenderTargetView。将纹理用作shader resource,则需要创建ID3D10ShaderResourceView。

在为指定的资源创建视图之前,资源必须以对应的状态标志创建。比如,如果资源没有以D3D10_BIND_DEPTH_STENCIL创建,则我们不可以创建一个ID3D10DepthStencilView。

如果想要开启重采样,需要声明一个DXGI_SAMPLE_DESC对象,指定重采样的数量和级别。使用以下函数可以查询给定纹理格式的重采样级别和数量:

HRESULT ID3D10Device::CheckMultisampleQualityLevels(
DXGI_FORMAT Format, UINT SampleCount, UINT *pNumQualityLevels);

D3D的初始化步骤如下:
  1. 需要创建一个DXGI_SWAP_CHAIN_DESC结构的实例来描述交换链。
  2. 用D3D10CreateDeviceAndSwapChain函数来创建ID3D10Device和IDXGISwapChain接口。
  3. 为交换链的back buffer创建render target view。
  4. 创建depth/stencil buffer和相应的depth/stencil view。
  5. 绑定render target view和depth/stencil view到渲染管线的输出合并步骤,以供D3D使用。
  6. 设置viewport。
第一步

我们在结构体DXGI_SWAP_CHAIN_DESC中描述交换链。至于每个参数什么用处,这里就不贴出来。。

DXGI_SWAP_CHAIN_DESC sd;
sd.BufferDesc.Width = mClientWidth; // use window’s client area dims
sd.BufferDesc.Height = mClientHeight;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// No multisampling.
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.BufferCount = 1;
sd.OutputWindow = mhMainWnd;
sd.Windowed = true;
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
sd.Flags = 0;

第二步

创建了DXGI_SWAP_CHAIN_DESC之后,可以调用D3D10CreateDeviceAndSwapChain函数来创建设备和交换链

ID3D10Device* md3dDevice;
IDXGISwapChain* mSwapChain;
D3D10CreateDeviceAndSwapChain(0, D3D10_DRIVER_TYPE_HARDWARE,
0, createDeviceFlags, D3D10_SDK_VERSION,
&sd, &mSwapChain, &md3dDevice);

会返回两个指针,一个指向设备,一个指向交换链。

第三步

就像上面说的,我们并不直接将一个资源绑定到管线步骤;而是创建一个资源view,然后将view绑定到管线中。要让D3D可以渲染back buffer,需要为back buffer创建一个render target view。

ID3D10RenderTargetView* mRenderTargetView;
ID3D10Texture2D* backBuffer;
mSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D),
          reinterpret_cast<void**>(&backBuffer));
md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
ReleaseCOM(backBuffer);

IDXGISwapChain::GetBuffer方法用于获得指向back buffer的指针,第一个参数用于指定要获取的back buffer(以防止有多个),第二个参数是buffer的接口类型,通常是2D纹理,第三个参数返回指向back buffer的指针。

通过ID3D10Device::CreateRenderTargetView来创建render target view。第一个指针指向资源,第二个参数是指向D3D10_RENDER_TARGET_VIEW_DESC的指针,描述了资源中元素的类型。如果资源是以规定类型格式创建的,则这个指针可以是NULL,指按照资源创建的格式来使用。第三个参数返回一个指向创建好的render target view的指针。

IDXGISwapChain::GetBuffer的调用增加了back buffer的COM引用数量,所以需要在代码段的最后release。

第四步

接下来需要创建depth/stencil buffer,上面已经说过了,depth buffer只是一个存储深度信息的2D纹理。要创建一个纹理,需要使用D3D10_TEXTURE2D_DESC结构,绑定相应的depth/stencil view,然后调用ID3D10Device::CreateTexture2D函数。

D3D10_TEXTURE2D_DESC depthStencilDesc;
depthStencilDesc.Width = mClientWidth;
depthStencilDesc.Height = mClientHeight;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilDesc.SampleDesc.Count = 1; // multisampling must match
depthStencilDesc.SampleDesc.Quality = 0; // swap chain values.
depthStencilDesc.Usage = D3D10_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D10_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;
ID3D10Texture2D* mDepthStencilBuffer;
ID3D10DepthStencilView* mDepthStencilView;
HR(md3dDevice->CreateTexture2D(
&depthStencilDesc, 0, &mDepthStencilBuffer));
HR(md3dDevice->CreateDepthStencilView(
mDepthStencilBuffer, 0, &mDepthStencilView));

第五步

创建好了各种view后,就可以把它们绑定到输出合并阶段了。

md3dDevice->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilView);

第一个参数是绑定的render targets的数量,第二个参数是指向render target view指针数组的第一个元素的指针(有点拗口,假设有多个render targets,所以有多个view指针,它们组成了一个数组),第三个参数是指向depth/stencil view的指针。

第六步

视口的设置在D3D10_VIEWPORT结构体中,然后调用ID3D10Device::RSSetViewports函数。

  先翻译到这里吧。。

本文原创 转载请著名出处 http://www.cnblogs.com/luluathena/

posted @ 2010-09-08 20:34  筱夏  阅读(3012)  评论(2编辑  收藏  举报